Merge "RCFilters: Adjust to use MenuTagMultiselectWidget"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 13 Apr 2017 20:04:40 +0000 (20:04 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 13 Apr 2017 20:04:41 +0000 (20:04 +0000)
147 files changed:
RELEASE-NOTES-1.29
autoload.php
includes/Block.php
includes/DefaultSettings.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/MovePage.php
includes/OutputPage.php
includes/Revision.php
includes/SiteStats.php
includes/Title.php
includes/actions/InfoAction.php
includes/api/ApiBase.php
includes/api/ApiOpenSearch.php
includes/api/ApiPageSet.php
includes/api/ApiQuery.php
includes/api/ApiQueryBase.php
includes/api/i18n/fr.json
includes/api/i18n/pt-br.json
includes/cache/BacklinkCache.php
includes/cache/LinkCache.php
includes/cache/MessageBlobStore.php
includes/cache/MessageCache.php
includes/changes/ChangesListBooleanFilter.php
includes/changetags/ChangeTags.php
includes/dao/DBAccessBase.php
includes/db/DatabaseOracle.php
includes/filerepo/ForeignDBRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/file/LocalFile.php
includes/installer/DatabaseInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/MssqlInstaller.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlInstaller.php
includes/installer/PostgresInstaller.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteInstaller.php
includes/installer/SqliteUpdater.php
includes/installer/i18n/pt-br.json
includes/interwiki/ClassicInterwikiLookup.php
includes/libs/lockmanager/DBLockManager.php
includes/libs/rdbms/connectionmanager/ConnectionManager.php
includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/DatabaseMssql.php
includes/libs/rdbms/database/DatabaseMysql.php
includes/libs/rdbms/database/DatabaseMysqlBase.php
includes/libs/rdbms/database/DatabaseMysqli.php
includes/libs/rdbms/database/DatabasePostgres.php
includes/libs/rdbms/database/DatabaseSqlite.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/IMaintainableDatabase.php
includes/libs/rdbms/database/MaintainableDBConnRef.php
includes/libs/rdbms/database/utils/SavepointPostgres.php
includes/libs/rdbms/exception/DBQueryError.php
includes/libs/rdbms/field/PostgresField.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/objectcache/SqlBagOStuff.php
includes/resourceloader/ResourceLoaderSkinModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/skins/Skin.php
includes/specialpage/ChangesListSpecialPage.php
includes/user/BotPassword.php
includes/user/User.php
languages/i18n/ar.json
languages/i18n/ast.json
languages/i18n/atj.json
languages/i18n/az.json
languages/i18n/be-tarask.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/bs.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/dty.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/fy.json
languages/i18n/gl.json
languages/i18n/gor.json
languages/i18n/gsw.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/ht.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/ilo.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/mg.json
languages/i18n/mk.json
languages/i18n/ms.json
languages/i18n/nb.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sco.json
languages/i18n/sl.json
languages/i18n/sq.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tr.json
languages/i18n/udm.json
languages/i18n/uk.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesDty.php
maintenance/rebuildtextindex.php
maintenance/sqlite.inc
resources/Resources.php
resources/lib/jquery/jquery.migrate.js [new file with mode: 0644]
resources/lib/jquery/jquery3.js [new file with mode: 0644]
resources/src/mediawiki.action/mediawiki.action.edit.js
resources/src/mediawiki.action/mediawiki.action.edit.styles.css
resources/src/mediawiki.skinning/interface.css
resources/src/mediawiki.widgets/mw.widgets.ComplexNamespaceInputWidget.js
resources/src/mediawiki.widgets/mw.widgets.ComplexTitleInputWidget.js
resources/src/mediawiki/mediawiki.js
tests/phpunit/includes/OutputPageTest.php
tests/phpunit/includes/db/DatabaseMysqlBaseTest.php
tests/phpunit/includes/db/DatabaseSqliteTest.php

index 33d917c..f9ff2e3 100644 (file)
@@ -63,6 +63,13 @@ production.
 * Completely new user interface for the RecentChanges page, which
   structures filters into user-friendly groups.  This has corresponding
   changes to how filters are registered by core and extensions.
+* The edit form now uses pretty OOjs UI buttons, checkboxes and summary input.
+  Because this change can cause problems for extensions and on-wiki
+  scripts depending on the exact HTML, the old version is still available
+  and can be used by setting $wgOOUIEditPage = false; in LocalSettings.php.
+  This will be removed later and OOjs UI will become the only option.
+  To make testing easier, users can also force either mode by adding
+  &ooui=true or &ooui=false to the action=edit URL.
 
 === External library changes in 1.29 ===
 
@@ -75,6 +82,7 @@ production.
 * Updated monolog from v1.18.2 to 1.22.1.
 * Updated wikimedia/composer-merge-plugin from v1.3.1 to v1.4.0.
 * Updated OOjs from v1.1.10 to v2.0.0.
+* Updated jQuery from v1.11.3 to v3.2.1 (including jQuery Migrate v3.0.0).
 
 ==== New external libraries ====
 * Added wikimedia/timestamp v1.0.0.
index 0c26811..bfac50d 100644 (file)
@@ -1260,7 +1260,6 @@ $wgAutoloadLocalClasses = [
        'SVGReader' => __DIR__ . '/includes/media/SVGMetadataExtractor.php',
        'SamplingStatsdClient' => __DIR__ . '/includes/libs/stats/SamplingStatsdClient.php',
        'Sanitizer' => __DIR__ . '/includes/Sanitizer.php',
-       'SavepointPostgres' => __DIR__ . '/includes/libs/rdbms/database/utils/SavepointPostgres.php',
        'ScopedCallback' => __DIR__ . '/includes/compat/ScopedCallback.php',
        'ScopedLock' => __DIR__ . '/includes/libs/lockmanager/ScopedLock.php',
        'SearchApi' => __DIR__ . '/includes/api/SearchApi.php',
@@ -1597,7 +1596,14 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\ConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/ConnectionManager.php',
        'Wikimedia\\Rdbms\\DBConnRef' => __DIR__ . '/includes/libs/rdbms/database/DBConnRef.php',
        'Wikimedia\\Rdbms\\DBMasterPos' => __DIR__ . '/includes/libs/rdbms/database/position/DBMasterPos.php',
+       'Wikimedia\\Rdbms\\Database' => __DIR__ . '/includes/libs/rdbms/database/Database.php',
        'Wikimedia\\Rdbms\\DatabaseDomain' => __DIR__ . '/includes/libs/rdbms/database/DatabaseDomain.php',
+       'Wikimedia\\Rdbms\\DatabaseMssql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMssql.php',
+       'Wikimedia\\Rdbms\\DatabaseMysql' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysql.php',
+       'Wikimedia\\Rdbms\\DatabaseMysqlBase' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqlBase.php',
+       'Wikimedia\\Rdbms\\DatabaseMysqli' => __DIR__ . '/includes/libs/rdbms/database/DatabaseMysqli.php',
+       'Wikimedia\\Rdbms\\DatabasePostgres' => __DIR__ . '/includes/libs/rdbms/database/DatabasePostgres.php',
+       'Wikimedia\\Rdbms\\DatabaseSqlite' => __DIR__ . '/includes/libs/rdbms/database/DatabaseSqlite.php',
        'Wikimedia\\Rdbms\\FakeResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/FakeResultWrapper.php',
        'Wikimedia\\Rdbms\\Field' => __DIR__ . '/includes/libs/rdbms/field/Field.php',
        'Wikimedia\\Rdbms\\IBlob' => __DIR__ . '/includes/libs/rdbms/encasing/IBlob.php',
@@ -1627,6 +1633,7 @@ $wgAutoloadLocalClasses = [
        'Wikimedia\\Rdbms\\PostgresField' => __DIR__ . '/includes/libs/rdbms/field/PostgresField.php',
        'Wikimedia\\Rdbms\\ResultWrapper' => __DIR__ . '/includes/libs/rdbms/database/resultwrapper/ResultWrapper.php',
        'Wikimedia\\Rdbms\\SQLiteField' => __DIR__ . '/includes/libs/rdbms/field/SQLiteField.php',
+       'Wikimedia\\Rdbms\\SavepointPostgres' => __DIR__ . '/includes/libs/rdbms/database/utils/SavepointPostgres.php',
        'Wikimedia\\Rdbms\\SessionConsistentConnectionManager' => __DIR__ . '/includes/libs/rdbms/connectionmanager/SessionConsistentConnectionManager.php',
        'Wikimedia\\Rdbms\\TransactionProfiler' => __DIR__ . '/includes/libs/rdbms/TransactionProfiler.php',
        'WikitextContent' => __DIR__ . '/includes/content/WikitextContent.php',
index b6b3ae0..0b7f7b2 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 
index 53a147b..e38524f 100644 (file)
@@ -3216,6 +3216,14 @@ $wgHTMLFormAllowTableFormat = true;
  */
 $wgUseMediaWikiUIEverywhere = false;
 
+/**
+ * Temporary variable that determines whether the EditPage class should use OOjs UI or not.
+ * This will be removed later and OOjs UI will become the only option.
+ *
+ * @since 1.29
+ */
+$wgOOUIEditPage = true;
+
 /**
  * Whether to label the store-to-database-and-show-to-others button in the editor
  * as "Save page"/"Save changes" if false (the default) or, if true, instead as
@@ -3665,6 +3673,16 @@ $wgResourceLoaderMinifierMaxLineLength = 1000;
  */
 $wgIncludeLegacyJavaScript = false;
 
+/**
+ * Use jQuery 3 (with jQuery Migrate) instead of jQuery 1.
+ *
+ * This is a temporary feature flag for the MediaWiki 1.29 development cycle while
+ * instabilities with jQuery 3 are being addressed. See T124742.
+ *
+ * @deprecated since 1.29
+ */
+$wgUsejQueryThree = true;
+
 /**
  * Whether or not to assign configuration variables to the global window object.
  *
index 7bdc3bc..c19ed5e 100644 (file)
@@ -413,10 +413,17 @@ class EditPage {
         */
        private $isOldRev = false;
 
+       /**
+        * @var bool Whether OOUI should be enabled here
+        */
+       private $oouiEnabled = false;
+
        /**
         * @param Article $article
         */
        public function __construct( Article $article ) {
+               global $wgOOUIEditPage;
+
                $this->mArticle = $article;
                $this->page = $article->getPage(); // model object
                $this->mTitle = $article->getTitle();
@@ -426,6 +433,8 @@ class EditPage {
 
                $handler = ContentHandler::getForModelID( $this->contentModel );
                $this->contentFormat = $handler->getDefaultFormat();
+
+               $this->oouiEnabled = $wgOOUIEditPage;
        }
 
        /**
@@ -476,6 +485,14 @@ class EditPage {
                }
        }
 
+       /**
+        * Check if the edit page is using OOUI controls
+        * @return bool
+        */
+       public function isOouiEnabled() {
+               return $this->oouiEnabled;
+       }
+
        /**
         * Returns if the given content model is editable.
         *
@@ -843,6 +860,9 @@ class EditPage {
        public function importFormData( &$request ) {
                global $wgContLang, $wgUser;
 
+               # Allow users to change the mode for testing
+               $this->oouiEnabled = $request->getFuzzyBool( 'ooui', $this->oouiEnabled );
+
                # Section edit can come from either the form or a link
                $this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
 
@@ -2637,6 +2657,7 @@ class EditPage {
                $wgOut->addHTML( Html::openElement(
                        'form',
                        [
+                               'class' => $this->oouiEnabled ? 'mw-editform-ooui' : 'mw-editform-legacy',
                                'id' => self::EDITFORM_ID,
                                'name' => self::EDITFORM_ID,
                                'method' => 'post',
@@ -2736,6 +2757,11 @@ class EditPage {
                $wgOut->addHTML( Html::hidden( 'format', $this->contentFormat ) );
                $wgOut->addHTML( Html::hidden( 'model', $this->contentModel ) );
 
+               // following functions will need OOUI, enable it only once; here.
+               if ( $this->oouiEnabled ) {
+                       $wgOut->enableOOUI();
+               }
+
                if ( $this->section == 'new' ) {
                        $this->showSummaryInput( true, $this->summary );
                        $wgOut->addHTML( $this->getSummaryPreview( true, $this->summary ) );
@@ -3007,6 +3033,24 @@ class EditPage {
                $this->showHeaderCopyrightWarning();
        }
 
+       /**
+        * Helper function for summary input functions, which returns the neccessary
+        * attributes for the input.
+        *
+        * @param array|null $inputAttrs Array of attrs to use on the input
+        * @return array
+        */
+       private function getSummaryInputAttributes( array $inputAttrs = null ) {
+               // Note: the maxlength is overridden in JS to 255 and to make it use UTF-8 bytes, not characters.
+               return ( is_array( $inputAttrs ) ? $inputAttrs : [] ) + [
+                       'id' => 'wpSummary',
+                       'maxlength' => '200',
+                       'tabindex' => '1',
+                       'size' => 60,
+                       'spellcheck' => 'true',
+               ] + Linker::tooltipAndAccesskeyAttribs( 'summary' );
+       }
+
        /**
         * Standard summary input and label (wgSummary), abstracted so EditPage
         * subclasses may reorganize the form.
@@ -3024,14 +3068,7 @@ class EditPage {
        public function getSummaryInput( $summary = "", $labelText = null,
                $inputAttrs = null, $spanLabelAttrs = null
        ) {
-               // Note: the maxlength is overridden in JS to 255 and to make it use UTF-8 bytes, not characters.
-               $inputAttrs = ( is_array( $inputAttrs ) ? $inputAttrs : [] ) + [
-                       'id' => 'wpSummary',
-                       'maxlength' => '200',
-                       'tabindex' => '1',
-                       'size' => 60,
-                       'spellcheck' => 'true',
-               ] + Linker::tooltipAndAccesskeyAttribs( 'summary' );
+               $inputAttrs = $this->getSummaryInputAttributes( $inputAttrs );
 
                $spanLabelAttrs = ( is_array( $spanLabelAttrs ) ? $spanLabelAttrs : [] ) + [
                        'class' => $this->missingSummary ? 'mw-summarymissed' : 'mw-summary',
@@ -3053,6 +3090,34 @@ class EditPage {
                return [ $label, $input ];
        }
 
+       /**
+        * Same as self::getSummaryInput, but uses OOUI, instead of plain HTML.
+        * Builds a standard summary input with a label.
+        *
+        * @param string $summary The value of the summary input
+        * @param string $labelText The html to place inside the label
+        * @param array $inputAttrs Array of attrs to use on the input
+        *
+        * @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
+        */
+       function getSummaryInputOOUI( $summary = "", $labelText = null, $inputAttrs = null ) {
+               $inputAttrs = OOUI\Element::configFromHtmlAttributes(
+                       $this->getSummaryInputAttributes( $inputAttrs )
+               );
+
+               return new OOUI\FieldLayout(
+                       new OOUI\TextInputWidget( [
+                               'value' => $summary,
+                       ] + $inputAttrs ),
+                       [
+                               'label' => new OOUI\HtmlSnippet( $labelText ),
+                               'align' => 'top',
+                               'id' => 'wpSummaryLabel',
+                               'classes' => [ $this->missingSummary ? 'mw-summarymissed' : 'mw-summary' ],
+                       ]
+               );
+       }
+
        /**
         * @param bool $isSubjectPreview True if this is the section subject/title
         *   up top, or false if this is the comment summary
@@ -3073,14 +3138,23 @@ class EditPage {
                                return;
                        }
                }
+
                $labelText = $this->context->msg( $isSubjectPreview ? 'subject' : 'summary' )->parse();
-               list( $label, $input ) = $this->getSummaryInput(
-                       $summary,
-                       $labelText,
-                       [ 'class' => $summaryClass ],
-                       []
-               );
-               $wgOut->addHTML( "{$label} {$input}" );
+               if ( $this->oouiEnabled ) {
+                       $wgOut->addHTML( $this->getSummaryInputOOUI(
+                               $summary,
+                               $labelText,
+                               [ 'class' => $summaryClass ]
+                       ) );
+               } else {
+                       list( $label, $input ) = $this->getSummaryInput(
+                               $summary,
+                               $labelText,
+                               [ 'class' => $summaryClass ]
+                       );
+                       $wgOut->addHTML( "{$label} {$input}" );
+               }
+
        }
 
        /**
@@ -3490,9 +3564,21 @@ HTML
                        $wgOut->addHTML( $this->getSummaryPreview( false, $this->summary ) );
                }
 
-               $checkboxes = $this->getCheckboxes( $tabindex,
-                       [ 'minor' => $this->minoredit, 'watch' => $this->watchthis ] );
-               $wgOut->addHTML( "<div class='editCheckboxes'>" . implode( $checkboxes, "\n" ) . "</div>\n" );
+               if ( $this->oouiEnabled ) {
+                       $checkboxes = $this->getCheckboxesOOUI(
+                               $tabindex,
+                               [ 'minor' => $this->minoredit, 'watch' => $this->watchthis ]
+                       );
+                       $checkboxesHTML = new OOUI\HorizontalLayout( [ 'items' => $checkboxes ] );
+               } else {
+                       $checkboxes = $this->getCheckboxes(
+                               $tabindex,
+                               [ 'minor' => $this->minoredit, 'watch' => $this->watchthis ]
+                       );
+                       $checkboxesHTML = implode( $checkboxes, "\n" );
+               }
+
+               $wgOut->addHTML( "<div class='editCheckboxes'>" . $checkboxesHTML . "</div>\n" );
 
                // Show copyright warning.
                $wgOut->addWikiText( $this->getCopywarn() );
@@ -3580,13 +3666,22 @@ HTML
                } elseif ( $this->getContextTitle()->isRedirect() ) {
                        $cancelParams['redirect'] = 'no';
                }
-
-               return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
-                       $this->getContextTitle(),
-                       new HtmlArmor( $this->context->msg( 'cancel' )->parse() ),
-                       Html::buttonAttributes( [ 'id' => 'mw-editform-cancel' ], [ 'mw-ui-quiet' ] ),
-                       $cancelParams
-               );
+               if ( $this->oouiEnabled ) {
+                       return new OOUI\ButtonWidget( [
+                               'id' => 'mw-editform-cancel',
+                               'href' => $this->getContextTitle()->getLinkUrl( $cancelParams ),
+                               'label' => new OOUI\HtmlSnippet( $this->context->msg( 'cancel' )->parse() ),
+                               'framed' => false,
+                               'flags' => 'destructive',
+                       ] );
+               } else {
+                       return MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
+                               $this->getContextTitle(),
+                               new HtmlArmor( $this->context->msg( 'cancel' )->parse() ),
+                               Html::buttonAttributes( [ 'id' => 'mw-editform-cancel' ], [ 'mw-ui-quiet' ] ),
+                               $cancelParams
+                       );
+               }
        }
 
        /**
@@ -4062,7 +4157,7 @@ HTML
        }
 
        /**
-        * Returns an array of html code of the following checkboxes:
+        * Returns an array of html code of the following checkboxes old style:
         * minor and watch
         *
         * @param int $tabindex Current tabindex
@@ -4119,6 +4214,68 @@ HTML
                return $checkboxes;
        }
 
+       /**
+        * Returns an array of html code of the following checkboxes:
+        * minor and watch
+        *
+        * @param int $tabindex Current tabindex
+        * @param array $checked Array of checkbox => bool, where bool indicates the checked
+        *                 status of the checkbox
+        *
+        * @return array
+        */
+       public function getCheckboxesOOUI( &$tabindex, $checked ) {
+               $checkboxes = [];
+               $checkboxesDef = $this->getCheckboxesDefinition( $checked );
+
+               $origTabindex = $tabindex;
+
+               foreach ( $checkboxesDef as $name => $options ) {
+                       $legacyName = isset( $options['legacy-name'] ) ? $options['legacy-name'] : $name;
+
+                       $title = null;
+                       $accesskey = null;
+                       if ( isset( $options['tooltip'] ) ) {
+                               $accesskey = $this->context->msg( "accesskey-{$options['tooltip']}" )->text();
+                               $title = Linker::titleAttrib( $options['tooltip'], 'withaccess' );
+                       }
+                       if ( isset( $options['title-message'] ) ) {
+                               $title = $this->context->msg( $options['title-message'] )->text();
+                       }
+                       if ( isset( $options['label-id'] ) ) {
+                               $labelAttribs['id'] = $options['label-id'];
+                       }
+
+                       $checkboxes[ $legacyName ] = new OOUI\FieldLayout(
+                               new OOUI\CheckboxInputWidget( [
+                                       'tabIndex' => ++$tabindex,
+                                       'accessKey' => $accesskey,
+                                       'id' => $options['id'],
+                                       'name' => $name,
+                                       'selected' => $options['default'],
+                               ] ),
+                               [
+                                       'align' => 'inline',
+                                       'label' => new OOUI\HtmlSnippet( $this->context->msg( $options['label-message'] )->parse() ),
+                                       'title' => $title,
+                                       'id' => isset( $options['label-id'] ) ? $options['label-id'] : null,
+                               ]
+                       );
+               }
+
+               // Backwards-compatibility hack to run the EditPageBeforeEditChecks hook. It's important,
+               // people have used it for the weirdest things completely unrelated to checkboxes...
+               // And if we're gonna run it, might as well allow its legacy checkboxes to be shown.
+               $legacyCheckboxes = $this->getCheckboxes( $origTabindex, $checked );
+               foreach ( $legacyCheckboxes as $name => $html ) {
+                       if ( $html && !isset( $checkboxes[$name] ) ) {
+                               $checkboxes[$name] = new OOUI\Widget( [ 'content' => new OOUI\HtmlSnippet( $html ) ] );
+                       }
+               }
+
+               return $checkboxes;
+       }
+
        /**
         * Returns an array of html code of the following buttons:
         * save, diff and preview
@@ -4144,31 +4301,56 @@ HTML
                        'name' => 'wpSave',
                        'tabindex' => ++$tabindex,
                ] + Linker::tooltipAndAccesskeyAttribs( 'save' );
-               $buttons['save'] = Html::submitButton(
-                       $this->context->msg( $buttonLabelKey )->text(),
-                       $attribs,
-                       [ 'mw-ui-progressive' ]
-               );
+
+               if ( $this->oouiEnabled ) {
+                       $saveConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
+                       $buttons['save'] = new OOUI\ButtonInputWidget( [
+                               'flags' => [ 'constructive', 'primary' ],
+                               'label' => $this->context->msg( $buttonLabelKey )->text(),
+                               'type' => 'submit',
+                       ] + $saveConfig );
+               } else {
+                       $buttons['save'] = Html::submitButton(
+                               $this->context->msg( $buttonLabelKey )->text(),
+                               $attribs,
+                               [ 'mw-ui-progressive' ]
+                       );
+               }
 
                $attribs = [
                        'id' => 'wpPreview',
                        'name' => 'wpPreview',
                        'tabindex' => ++$tabindex,
                ] + Linker::tooltipAndAccesskeyAttribs( 'preview' );
-               $buttons['preview'] = Html::submitButton(
-                       $this->context->msg( 'showpreview' )->text(),
-                       $attribs
-               );
-
+               if ( $this->oouiEnabled ) {
+                       $previewConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
+                       $buttons['preview'] = new OOUI\ButtonInputWidget( [
+                               'label' => $this->context->msg( 'showpreview' )->text(),
+                               'type' => 'submit'
+                       ] + $previewConfig );
+               } else {
+                       $buttons['preview'] = Html::submitButton(
+                               $this->context->msg( 'showpreview' )->text(),
+                               $attribs
+                       );
+               }
                $attribs = [
                        'id' => 'wpDiff',
                        'name' => 'wpDiff',
                        'tabindex' => ++$tabindex,
                ] + Linker::tooltipAndAccesskeyAttribs( 'diff' );
-               $buttons['diff'] = Html::submitButton(
-                       $this->context->msg( 'showdiff' )->text(),
-                       $attribs
-               );
+               if ( $this->oouiEnabled ) {
+                       $diffConfig = OOUI\Element::configFromHtmlAttributes( $attribs );
+                       $buttons['diff'] = new OOUI\ButtonInputWidget( [
+                               'label' => $this->context->msg( 'showdiff' )->text(),
+                               'type' => 'submit',
+                       ] + $diffConfig );
+               } else {
+                       $buttons['diff'] = Html::submitButton(
+                               $this->context->msg( 'showdiff' )->text(),
+                               $attribs
+                       );
+               }
 
                // Avoid PHP 7.1 warning of passing $this by reference
                $editPage = $this;
index 3747c23..243d066 100644 (file)
@@ -3072,7 +3072,7 @@ function wfSplitWikiID( $wiki ) {
  * @todo Replace calls to wfGetDB with calls to LoadBalancer::getConnection()
  *       on an injected instance of LoadBalancer.
  *
- * @return Database
+ * @return \Wikimedia\Rdbms\Database
  */
 function wfGetDB( $db, $groups = [], $wiki = false ) {
        return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
index 9a83d35..ce6ecad 100644 (file)
@@ -455,7 +455,7 @@ class MovePage {
                        $overwriteMessage = wfMessage(
                                        'delete_and_move_reason',
                                        $this->oldTitle->getPrefixedText()
-                               )->text();
+                               )->inContentLanguage()->text();
                        $newpage = WikiPage::factory( $nt );
                        $errs = [];
                        $status = $newpage->doDeleteArticleReal(
index df49bf6..5c05ad7 100644 (file)
@@ -4005,29 +4005,22 @@ class OutputPage extends ContextSource {
         * @since 1.26
         */
        protected function addLogoPreloadLinkHeaders() {
-               $logo = $this->getConfig()->get( 'Logo' ); // wgLogo
-               $logoHD = $this->getConfig()->get( 'LogoHD' ); // wgLogoHD
+               $logo = ResourceLoaderSkinModule::getLogo( $this->getConfig() );
 
                $tags = [];
                $logosPerDppx = [];
                $logos = [];
 
-               $logosPerDppx['1.0'] = $logo;
-
-               if ( !$logoHD ) {
+               if ( !is_array( $logo ) ) {
                        // No media queries required if we only have one variant
                        $this->addLinkHeader( '<' . $logo . '>;rel=preload;as=image' );
                        return;
                }
 
-               foreach ( $logoHD as $dppx => $src ) {
-                       // Only 1.5x and 2x are supported
-                       // Note: Keep in sync with ResourceLoaderSkinModule
-                       if ( in_array( $dppx, [ '1.5x', '2x' ] ) ) {
-                               // LogoHD uses a string in this format: "1.5x"
-                               $dppx = substr( $dppx, 0, -1 );
-                               $logosPerDppx[$dppx] = $src;
-                       }
+               foreach ( $logo as $dppx => $src ) {
+                       // Keys are in this format: "1.5x"
+                       $dppx = substr( $dppx, 0, -1 );
+                       $logosPerDppx[$dppx] = $src;
                }
 
                // Because PHP can't have floats as array keys
index bae974f..b20f843 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
index bc6b842..1c7730c 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index 95bb1d9..dd6aaef 100644 (file)
@@ -22,6 +22,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\Interwiki\InterwikiLookup;
index 167b709..df7afca 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\Database;
 
 /**
  * Displays information about a page.
index b698cef..a6c4b2a 100644 (file)
@@ -385,6 +385,13 @@ abstract class ApiBase extends ContextSource {
 
        /**
         * Indicates whether this module requires write mode
+        *
+        * This should return true for modules that may require synchronous database writes.
+        * Modules that do not need such writes should also not rely on master database access,
+        * since only read queries are needed and each master DB is a single point of failure.
+        * Additionally, requests that only need replica DBs can be efficiently routed to any
+        * datacenter via the Promise-Non-Write-API-Action header.
+        *
         * @return bool
         */
        public function isWriteMode() {
@@ -626,7 +633,7 @@ abstract class ApiBase extends ContextSource {
 
        /**
         * Gets a default replica DB connection object
-        * @return Database
+        * @return IDatabase
         */
        protected function getDB() {
                if ( !isset( $this->mSlaveDB ) ) {
index ff65d0e..dc1b4e7 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\Database;
 
 /**
  * @ingroup API
index a235532..5609ad8 100644 (file)
@@ -1426,7 +1426,7 @@ class ApiPageSet extends ApiBase {
 
        /**
         * Get the database connection (read-only)
-        * @return Database
+        * @return IDatabase
         */
        protected function getDB() {
                return $this->mDbSource->getDB();
index 5395bf0..e6f3fc4 100644 (file)
@@ -24,6 +24,8 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
+
 /**
  * This is the main query class. It behaves similar to ApiMain: based on the
  * parameters given, it will create a list of titles to work on (an ApiPageSet
@@ -168,7 +170,7 @@ class ApiQuery extends ApiBase {
         * @param string $name Name to assign to the database connection
         * @param int $db One of the DB_* constants
         * @param array $groups Query groups
-        * @return Database
+        * @return IDatabase
         */
        public function getNamedDB( $name, $db, $groups ) {
                if ( !array_key_exists( $name, $this->mNamedDB ) ) {
index 87bb6a7..baefbda 100644 (file)
@@ -24,6 +24,7 @@
  * @file
  */
 
+use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\ResultWrapper;
 
 /**
@@ -105,7 +106,7 @@ abstract class ApiQueryBase extends ApiBase {
 
        /**
         * Get the Query database connection (read-only)
-        * @return Database
+        * @return IDatabase
         */
        protected function getDB() {
                if ( is_null( $this->mDb ) ) {
@@ -121,7 +122,7 @@ abstract class ApiQueryBase extends ApiBase {
         * @param string $name Name to assign to the database connection
         * @param int $db One of the DB_* constants
         * @param array $groups Query groups
-        * @return Database
+        * @return IDatabase
         */
        public function selectNamedDB( $name, $db, $groups ) {
                $this->mDb = $this->getQuery()->getNamedDB( $name, $db, $groups );
index fb4c37f..4c028b2 100644 (file)
        "apihelp-query+tags-paramvalue-prop-active": "Si la balise est encore appliquée.",
        "apihelp-query+tags-example-simple": "Lister les balises disponibles",
        "apihelp-query+templates-description": "Renvoie toutes les pages incluses dans les pages fournies.",
-       "apihelp-query+templates-param-namespace": "Afficher les modèles uniquement dans ces espaces de nom.",
+       "apihelp-query+templates-param-namespace": "Afficher les modèles uniquement dans ces espaces de noms.",
        "apihelp-query+templates-param-limit": "Combien de modèles renvoyer.",
        "apihelp-query+templates-param-templates": "Lister uniquement ces modèles. Utile pour vérifier si une certaine page utilise un modèle donné.",
        "apihelp-query+templates-param-dir": "La direction dans laquelle lister.",
        "apihelp-query+templates-example-namespaces": "Obtenir les pages des espaces de nom {{ns:user}} et {{ns:template}} qui sont inclues dans la page <kdb>Main Page<kdb>.",
        "apihelp-query+tokens-description": "Récupère les jetons pour les actions de modification de données.",
        "apihelp-query+tokens-param-type": "Types de jeton à demander.",
-       "apihelp-query+tokens-example-simple": "Récupérer un jeton csrf (par défaut)",
-       "apihelp-query+tokens-example-types": "Récupérer un jeton de suivi et un de patrouille",
+       "apihelp-query+tokens-example-simple": "Récupérer un jeton csrf (par défaut).",
+       "apihelp-query+tokens-example-types": "Récupérer un jeton de suivi et un de patrouille.",
        "apihelp-query+transcludedin-description": "Trouver toutes les pages qui incluent les pages données.",
        "apihelp-query+transcludedin-param-prop": "Quelles propriétés obtenir :",
        "apihelp-query+transcludedin-paramvalue-prop-pageid": "ID de page de chaque page.",
index 7d5f7ea..ba05141 100644 (file)
@@ -12,7 +12,8 @@
                        "LucyDiniz",
                        "Eduardo Addad de Oliveira",
                        "Warley Felipe C.",
-                       "TheEduGobi"
+                       "TheEduGobi",
+                       "Felipe L. Ewald"
                ]
        },
        "apihelp-main-param-action": "Qual ação executar.",
        "apihelp-upload-param-ignorewarnings": "Ignorar todos os avisos.",
        "apihelp-userrights-param-user": "Nome de usuário.",
        "apihelp-userrights-param-userid": "ID de usuário.",
-       "apihelp-userrights-param-add": "Adicionar o usuário para estes grupos.",
+       "apihelp-userrights-param-add": "Adicione o usuário a esses grupos ou, se ele já for membro, atualizar a expiração de sua associação nesse grupo.",
        "apihelp-userrights-param-remove": "Remover o usuário destes grupos.",
        "apihelp-userrights-param-reason": "Motivo para a mudança.",
        "apihelp-none-description": "Nenhuma saída.",
        "api-help-license-unknown": "Fonte: <span class=\"apihelp-unknown\">desconhecida</span>",
        "api-help-parameters": "{{PLURAL:$1|Parâmetro|Parâmetros}}:",
        "api-help-param-deprecated": "Obsoleto",
-       "api-help-param-required": "Este parâmetro é obrigatório."
+       "api-help-param-required": "Este parâmetro é obrigatório.",
+       "api-credits-header": "Créditos"
 }
index 7215606..e171bc7 100644 (file)
@@ -143,7 +143,7 @@ class BacklinkCache {
        /**
         * Get the replica DB connection to the database
         * When non existing, will initialize the connection.
-        * @return Database
+        * @return IDatabase
         */
        protected function getDB() {
                if ( !isset( $this->db ) ) {
index 57f66f1..2d08895 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  * @ingroup Cache
  */
+
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
index 14baeeb..b076a08 100644 (file)
@@ -26,6 +26,7 @@
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
+use Wikimedia\Rdbms\Database;
 
 /**
  * This class generates message blobs for use by ResourceLoader modules.
index 8a42a9a..355aff4 100644 (file)
@@ -23,6 +23,7 @@
 use MediaWiki\MediaWikiServices;
 use Wikimedia\ScopedCallback;
 use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Rdbms\Database;
 
 /**
  * MediaWiki message cache structure version.
index 4117a11..851d173 100644 (file)
@@ -136,10 +136,15 @@ class ChangesListBooleanFilter extends ChangesListFilter {
        }
 
        /**
+        * Get the default value
+        *
+        * @param bool $structuredUI Are we currently showing the structured UI
         * @return bool|null Default value
         */
-       public function getDefault() {
-               return $this->defaultValue;
+       public function getDefault( $structuredUI = false ) {
+               return $this->isReplacedInStructuredUi && $structuredUI ?
+                       false :
+                       $this->defaultValue;
        }
 
        /**
index d2239eb..ca3c28b 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Change tagging
  */
 
+use Wikimedia\Rdbms\Database;
+
 class ChangeTags {
        /**
         * Can't delete tags with more than this many uses. Similar in intent to
index da660bd..0f8d7f7 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\LoadBalancer;
 
 /**
index ef5a8fe..a0d7ad8 100644 (file)
@@ -20,6 +20,8 @@
  * @file
  * @ingroup Database
  */
+
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\Blob;
 use Wikimedia\Rdbms\ResultWrapper;
 
index 29c017c..bce3005 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup FileRepo
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index 9c92bc0..d91ab24 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 use Wikimedia\Rdbms\ResultWrapper;
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index c109fba..292fc80 100644 (file)
@@ -21,7 +21,8 @@
  * @ingroup FileAbstraction
  */
 
-use \MediaWiki\Logger\LoggerFactory;
+use MediaWiki\Logger\LoggerFactory;
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index 22717fc..6113573 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Deployment
  */
 use Wikimedia\Rdbms\LBFactorySingle;
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index 8913c77..a4cb695 100644 (file)
@@ -20,6 +20,7 @@
  * @file
  * @ingroup Deployment
  */
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use MediaWiki\MediaWikiServices;
 
index d6efeb2..8307d8b 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\Database;
+
 /**
  * Class for setting up the MediaWiki database using Microsoft SQL Server.
  *
index 988ec41..dfe595e 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\DatabaseMssql;
+
 /**
  * Class for setting up the MediaWiki database using Microsoft SQL Server.
  *
index 7269773..c0731e7 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\Database;
+
 /**
  * Class for setting up the MediaWiki database using MySQL.
  *
index 906768f..bd7cfb3 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\Database;
+
 /**
  * Class for setting up the MediaWiki database using Postgres.
  *
index 1a7b208..39cb89c 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\DatabasePostgres;
+
 /**
  * Class for handling updates to Postgres databases.
  *
index 0fe7068..e9d3ad4 100644 (file)
@@ -21,6 +21,9 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\DatabaseSqlite;
+
 /**
  * Class for setting up the MediaWiki database using SQLLite.
  *
index dcd66dd..9c90283 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Deployment
  */
 
+use Wikimedia\Rdbms\DatabaseSqlite;
+
 /**
  * Class for handling updates to Sqlite databases.
  *
index 35fa8e8..1e9d1b9 100644 (file)
@@ -21,7 +21,8 @@
                        "Almondega",
                        "Luk3",
                        "Eduardo Addad de Oliveira",
-                       "Warley Felipe C."
+                       "Warley Felipe C.",
+                       "Felipe L. Ewald"
                ]
        },
        "config-desc": "O instalador do MediaWiki",
        "config-db-host": "Servidor da base de dados:",
        "config-db-host-help": "Se a base de dados do seu servidor está em um servidor diferente, digite o nome do hospedeiro ou o endereço IP aqui.\n\nSe você está utilizando um hospedeiro web compartilhado, o seu provedor de hospedagem deverá fornecer o nome do hospedeiro correto na sua documentação.\n\nSe você está instalando em um servidor Windows e usando o MySQL, usar \"localhost\" pode não funcionar para o nome de servidor. Se não funcionar, tente \"127.0.01\" para o endereço de IP local.\n\nSe você está usando PostgreSQl, deixe este campo em branco para se conectar através de um socket Unix.",
        "config-db-host-oracle": "TNS da base de dados:",
+       "config-db-host-oracle-help": "Digite um  [http://download.oracle.com/docs/cd/B28359_01/network.111/b28317/tnsnames.htm Nome de Conexão local] válido; o arquivo tnsnames.ora precisa estar visível para esta instalação.<br />Se você estiver usando bibliotecas cliente 10g ou mais recente,\n você também pode usar o método [http://download.oracle.com/docs/cd/E11882_01/network.112/e10836/naming.htm Easy Connect].",
        "config-db-wiki-settings": "Identifique esta wiki",
        "config-db-name": "Nome da base de dados:",
        "config-db-name-help": "Escolha um nome que identifique a sua wiki.\nEle não deve conter espaços.\n\nSe você está utilizando um hospedeiro web compartilhado, o provedor de hospedagem lhe dará um nome especifico de base de dados para usar ou o deixará criar a partir do painel de controle.",
        "config-db-name-oracle": "Esquema de base de dados:",
+       "config-db-account-oracle-warn": "Há três cenários suportados para instalar o Oracle como backend do banco de dados:\n\nSe você deseja criar a conta do banco de dados como parte do processo de instalação, forneça uma conta com função SYSDBA como conta do banco de dados para instalação e especifique as credenciais desejadas para a conta de acesso pela web, caso contrário, você poderá criar a conta de acesso via web manualmente e fornecer apenas aquela conta (se tiver permissões necessárias para criar os objetos schema) ou fornecer duas contas diferentes, uma com privilégios de criação e uma restrita para acesso à web.\n\nO script para criar uma conta com os privilégios necessários pode ser encontrado no diretório \"maintenance/oracle/\" desta instalação. Lembre-se de que usar uma conta restrita desativará todos os recursos de manutenção com a conta padrão.",
        "config-db-install-account": "Conta de usuário para instalação",
        "config-db-username": "Nome de usuário do banco de dados:",
        "config-db-password": "Senha do banco de dados:",
index f19e3db..5226aa0 100644 (file)
@@ -23,7 +23,7 @@ namespace MediaWiki\Interwiki;
  */
 use \Cdb\Exception as CdbException;
 use \Cdb\Reader as CdbReader;
-use Database;
+use Wikimedia\Rdbms\Database;
 use Hooks;
 use Interwiki;
 use Language;
index 8ef8196..ddb8521 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup LockManager
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index 0d5fbf5..6481c92 100644 (file)
@@ -2,7 +2,6 @@
 
 namespace Wikimedia\Rdbms;
 
-use Database;
 use InvalidArgumentException;
 
 /**
@@ -605,4 +604,4 @@ class DBConnRef implements IDatabase {
        }
 }
 
-class_alias( 'Wikimedia\Rdbms\DBConnRef', 'DBConnRef' );
+class_alias( DBConnRef::class, 'DBConnRef' );
index 40bcc1b..6fafe71 100644 (file)
  * @file
  * @ingroup Database
  */
+namespace Wikimedia\Rdbms;
+
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerInterface;
 use Wikimedia\ScopedCallback;
-use Wikimedia\Rdbms\TransactionProfiler;
-use Wikimedia\Rdbms\LikeMatch;
-use Wikimedia\Rdbms\DatabaseDomain;
-use Wikimedia\Rdbms\ResultWrapper;
-use Wikimedia\Rdbms\DBMasterPos;
-use Wikimedia\Rdbms\Blob;
 use Wikimedia\Timestamp\ConvertibleTimestamp;
-use Wikimedia\Rdbms\IDatabase;
-use Wikimedia\Rdbms\IMaintainableDatabase;
+use MediaWiki;
+use BagOStuff;
+use HashBagOStuff;
+use InvalidArgumentException;
+use DBQueryError;
+use DBUnexpectedError;
+use DBConnectionError;
+use DBReadOnlyError;
+use Exception;
+use RuntimeException;
 
 /**
  * Relational database abstraction object
@@ -339,6 +343,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        'oracle' => [],
                        'mssql' => [],
                ];
+               static $classAliases = [
+                       'DatabaseMssql' => DatabaseMssql::class,
+                       'DatabaseMysql' => DatabaseMysql::class,
+                       'DatabaseMysqli' => DatabaseMysqli::class,
+                       'DatabaseSqlite' => DatabaseSqlite::class,
+                       'DatabasePostgres' => DatabasePostgres::class
+               ];
 
                $driver = false;
                $dbType = strtolower( $dbType );
@@ -362,12 +373,17 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                } else {
                        $driver = $dbType;
                }
+
                if ( $driver === false || $driver === '' ) {
                        throw new InvalidArgumentException( __METHOD__ .
                                " no viable database extension found for type '$dbType'" );
                }
 
                $class = 'Database' . ucfirst( $driver );
+               if ( isset( $classAliases[$class] ) ) {
+                       $class = $classAliases[$class];
+               }
+
                if ( class_exists( $class ) && is_subclass_of( $class, IDatabase::class ) ) {
                        // Resolve some defaults for b/c
                        $p['host'] = isset( $p['host'] ) ? $p['host'] : false;
@@ -3479,4 +3495,5 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 }
 
-class_alias( Database::class, 'DatabaseBase' );
+class_alias( Database::class, 'DatabaseBase' ); // b/c for old name
+class_alias( Database::class, 'Database' ); // b/c global alias
index 75ddc9d..bbd2400 100644 (file)
  * @author Ryan Biesemeyer <v-ryanbi at microsoft dot com>
  * @author Ryan Schmidt <skizzerz at gmail dot com>
  */
-use Wikimedia\Rdbms\Blob;
-use Wikimedia\Rdbms\MssqlBlob;
-use Wikimedia\Rdbms\MssqlField;
-use Wikimedia\Rdbms\ResultWrapper;
-use Wikimedia\Rdbms\MssqlResultWrapper;
+
+namespace Wikimedia\Rdbms;
+
+use MediaWiki;
+use DBConnectionError;
+use DBUnexpectedError;
+use DBQueryError;
+use Exception;
+use stdClass;
 
 /**
  * @ingroup Database
@@ -1360,3 +1364,5 @@ class DatabaseMssql extends Database {
                return $old;
        }
 }
+
+class_alias( DatabaseMssql::class, 'DatabaseMssql' );
index 9ab7c64..c0c9223 100644 (file)
@@ -20,6 +20,9 @@
  * @file
  * @ingroup Database
  */
+namespace Wikimedia\Rdbms;
+
+use DBConnectionError;
 
 /**
  * Database abstraction object for PHP extension mysql.
@@ -202,3 +205,5 @@ class DatabaseMysql extends DatabaseMysqlBase {
                return mysql_real_escape_string( $s, $conn );
        }
 }
+
+class_alias( DatabaseMysql::class, 'DatabaseMysql' );
index e2b5226..b09516c 100644 (file)
  * @file
  * @ingroup Database
  */
-use Wikimedia\Rdbms\DBMasterPos;
-use Wikimedia\Rdbms\MySQLMasterPos;
-use Wikimedia\Rdbms\MySQLField;
-use Wikimedia\Rdbms\ResultWrapper;
+namespace Wikimedia\Rdbms;
+
+use DateTime;
+use DateTimeZone;
+use MediaWiki;
+use InvalidArgumentException;
+use DBError;
+use DBExpectedError;
+use DBUnexpectedError;
+use DBConnectionError;
+use Exception;
+use stdClass;
 
 /**
  * Database abstraction object for MySQL.
@@ -1360,3 +1368,5 @@ abstract class DatabaseMysqlBase extends Database {
                }
        }
 }
+
+class_alias( DatabaseMysqlBase::class, 'DatabaseMysqlBase' );
index 7a2200a..be25489 100644 (file)
  * @file
  * @ingroup Database
  */
+namespace Wikimedia\Rdbms;
 
-use Wikimedia\Rdbms\ResultWrapper;
+use mysqli;
+use DBConnectionError;
+use IP;
 
 /**
  * Database abstraction object for PHP extension mysqli.
@@ -263,7 +266,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param resource|ResultWrapper $res
+        * @param mysqli $res
         * @param int $n
         * @return mixed
         */
@@ -274,7 +277,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param resource|ResultWrapper $res
+        * @param mysqli $res
         * @param int $n
         * @return mixed
         */
@@ -285,7 +288,7 @@ class DatabaseMysqli extends DatabaseMysqlBase {
        }
 
        /**
-        * @param resource|ResultWrapper $res
+        * @param mysqli $res
         * @param int $row
         * @return mixed
         */
@@ -331,3 +334,5 @@ class DatabaseMysqli extends DatabaseMysqlBase {
                }
        }
 }
+
+class_alias( DatabaseMysqli::class, 'DatabaseMysqli' );
index 5bcd4a8..5049f9b 100644 (file)
  * @file
  * @ingroup Database
  */
+namespace Wikimedia\Rdbms;
+
 use Wikimedia\Timestamp\ConvertibleTimestamp;
 use Wikimedia\WaitConditionLoop;
-use Wikimedia\Rdbms\Blob;
-use Wikimedia\Rdbms\PostgresBlob;
-use Wikimedia\Rdbms\PostgresField;
-use Wikimedia\Rdbms\ResultWrapper;
+use MediaWiki;
+use DBUnexpectedError;
+use DBConnectionError;
+use Exception;
 
 /**
  * @ingroup Database
@@ -859,10 +861,10 @@ __INDEXATTR__;
         *
         * @since 1.19
         * @param string $text Postgreql array returned in a text form like {a,b}
-        * @param string $output
+        * @param string[] $output
         * @param int|bool $limit
         * @param int $offset
-        * @return string
+        * @return string[]
         */
        private function pg_array_parse( $text, &$output, $limit = false, $offset = 1 ) {
                if ( false === $limit ) {
@@ -1383,6 +1385,8 @@ SQL;
         * @return string Integer
         */
        private function bigintFromLockName( $lockName ) {
-               return Wikimedia\base_convert( substr( sha1( $lockName ), 0, 15 ), 16, 10 );
+               return \Wikimedia\base_convert( substr( sha1( $lockName ), 0, 15 ), 16, 10 );
        }
 }
+
+class_alias( DatabasePostgres::class, 'DatabasePostgres' );
index 090ce8e..6d187b8 100644 (file)
  * @file
  * @ingroup Database
  */
-use Wikimedia\Rdbms\Blob;
-use Wikimedia\Rdbms\SQLiteField;
-use Wikimedia\Rdbms\ResultWrapper;
+namespace Wikimedia\Rdbms;
+
+use PDO;
+use PDOException;
+use LockManager;
+use FSLockManager;
+use DBConnectionError;
+use DBReadOnlyError;
+use InvalidArgumentException;
+use RuntimeException;
+use DBError;
+use stdClass;
 
 /**
  * @ingroup Database
@@ -116,8 +125,10 @@ class DatabaseSqlite extends Database {
                $p['dbFilePath'] = $filename;
                $p['schema'] = false;
                $p['tablePrefix'] = '';
+               /** @var DatabaseSqlite $db */
+               $db = Database::factory( 'sqlite', $p );
 
-               return Database::factory( 'sqlite', $p );
+               return $db;
        }
 
        /**
@@ -1048,3 +1059,6 @@ class DatabaseSqlite extends Database {
                return 'SQLite ' . (string)$this->mConn->getAttribute( PDO::ATTR_SERVER_VERSION );
        }
 }
+
+class_alias( DatabaseSqlite::class, 'DatabaseSqlite' );
+
index 0b146cd..feaf5cf 100644 (file)
@@ -1808,4 +1808,4 @@ interface IDatabase {
        public function setTableAliases( array $aliases );
 }
 
-class_alias( 'Wikimedia\Rdbms\IDatabase', 'IDatabase' );
+class_alias( IDatabase::class, 'IDatabase' );
index b984c42..5666170 100644 (file)
@@ -279,4 +279,4 @@ interface IMaintainableDatabase extends IDatabase {
        public function unlockTables( $method );
 }
 
-class_alias( 'Wikimedia\Rdbms\IMaintainableDatabase', 'IMaintainableDatabase' );
+class_alias( IMaintainableDatabase::class, 'IMaintainableDatabase' );
index 8238f3e..6c94eb9 100644 (file)
@@ -82,4 +82,4 @@ class MaintainableDBConnRef extends DBConnRef implements IMaintainableDatabase {
        }
 }
 
-class_alias( 'Wikimedia\Rdbms\MaintainableDBConnRef', 'MaintainableDBConnRef' );
+class_alias( MaintainableDBConnRef::class, 'MaintainableDBConnRef' );
index 8ae78e9..cf5060e 100644 (file)
@@ -18,6 +18,9 @@
  * @file
  * @ingroup Database
  */
+
+namespace Wikimedia\Rdbms;
+
 use Psr\Log\LoggerInterface;
 
 /**
index b4c3d52..89b9cea 100644 (file)
@@ -18,6 +18,7 @@
  * @file
  * @ingroup Database
  */
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index c5819a3..600f34a 100644 (file)
@@ -2,8 +2,6 @@
 
 namespace Wikimedia\Rdbms;
 
-use DatabasePostgres;
-
 class PostgresField implements Field {
        private $name, $tablename, $type, $nullable, $max_length, $deferred, $deferrable, $conname,
                $has_default, $default;
index 2ea0e4e..8b5a98d 100644 (file)
@@ -23,7 +23,6 @@
  */
 namespace Wikimedia\Rdbms;
 
-use Database;
 use DBError;
 use DBAccessError;
 use DBTransactionError;
index d178657..ffa4f78 100644 (file)
@@ -25,7 +25,6 @@ namespace Wikimedia\Rdbms;
 use Psr\Log\LoggerInterface;
 use Psr\Log\NullLogger;
 use Wikimedia\ScopedCallback;
-use Database;
 use BagOStuff;
 use EmptyBagOStuff;
 use WANObjectCache;
@@ -49,7 +48,7 @@ use Exception;
 class LoadBalancer implements ILoadBalancer {
        /** @var array[] Map of (server index => server config array) */
        private $mServers;
-       /** @var \Database[][][] Map of local/foreignUsed/foreignFree => server index => IDatabase array */
+       /** @var Database[][][] Map of local/foreignUsed/foreignFree => server index => IDatabase array */
        private $mConns;
        /** @var float[] Map of (server index => weight) */
        private $mLoads;
@@ -87,7 +86,7 @@ class LoadBalancer implements ILoadBalancer {
        /** @var LoggerInterface */
        protected $perfLogger;
 
-       /** @var \Database Database connection that caused a problem */
+       /** @var Database DB connection object that caused a problem */
        private $errorConnection;
        /** @var integer The generic (not query grouped) replica DB index (of $mServers) */
        private $mReadIndex;
@@ -431,60 +430,65 @@ class LoadBalancer implements ILoadBalancer {
 
        public function waitFor( $pos ) {
                $oldPos = $this->mWaitForPos;
-               $this->mWaitForPos = $pos;
-
-               // If a generic reader connection was already established, then wait now
-               $i = $this->mReadIndex;
-               if ( $i > 0 ) {
-                       if ( !$this->doWait( $i ) ) {
-                               $this->laggedReplicaMode = true;
+               try {
+                       $this->mWaitForPos = $pos;
+                       // If a generic reader connection was already established, then wait now
+                       $i = $this->mReadIndex;
+                       if ( $i > 0 ) {
+                               if ( !$this->doWait( $i ) ) {
+                                       $this->laggedReplicaMode = true;
+                               }
                        }
+               } finally {
+                       // Restore the older position if it was higher
+                       $this->setWaitForPositionIfHigher( $oldPos );
                }
-
-               // Restore the older position if it was higher
-               $this->setWaitForPositionIfHigher( $oldPos );
        }
 
        public function waitForOne( $pos, $timeout = null ) {
                $oldPos = $this->mWaitForPos;
-               $this->mWaitForPos = $pos;
+               try {
+                       $this->mWaitForPos = $pos;
 
-               $i = $this->mReadIndex;
-               if ( $i <= 0 ) {
-                       // Pick a generic replica DB if there isn't one yet
-                       $readLoads = $this->mLoads;
-                       unset( $readLoads[$this->getWriterIndex()] ); // replica DBs only
-                       $readLoads = array_filter( $readLoads ); // with non-zero load
-                       $i = ArrayUtils::pickRandom( $readLoads );
-               }
+                       $i = $this->mReadIndex;
+                       if ( $i <= 0 ) {
+                               // Pick a generic replica DB if there isn't one yet
+                               $readLoads = $this->mLoads;
+                               unset( $readLoads[$this->getWriterIndex()] ); // replica DBs only
+                               $readLoads = array_filter( $readLoads ); // with non-zero load
+                               $i = ArrayUtils::pickRandom( $readLoads );
+                       }
 
-               if ( $i > 0 ) {
-                       $ok = $this->doWait( $i, true, $timeout );
-               } else {
-                       $ok = true; // no applicable loads
+                       if ( $i > 0 ) {
+                               $ok = $this->doWait( $i, true, $timeout );
+                       } else {
+                               $ok = true; // no applicable loads
+                       }
+               } finally {
+                       // Restore the older position if it was higher
+                       $this->setWaitForPositionIfHigher( $oldPos );
                }
 
-               // Restore the older position if it was higher
-               $this->setWaitForPositionIfHigher( $oldPos );
-
                return $ok;
        }
 
        public function waitForAll( $pos, $timeout = null ) {
                $oldPos = $this->mWaitForPos;
-               $this->mWaitForPos = $pos;
-               $serverCount = count( $this->mServers );
+               try {
+                       $this->mWaitForPos = $pos;
+                       $serverCount = count( $this->mServers );
 
-               $ok = true;
-               for ( $i = 1; $i < $serverCount; $i++ ) {
-                       if ( $this->mLoads[$i] > 0 ) {
-                               $ok = $this->doWait( $i, true, $timeout ) && $ok;
+                       $ok = true;
+                       for ( $i = 1; $i < $serverCount; $i++ ) {
+                               if ( $this->mLoads[$i] > 0 ) {
+                                       $ok = $this->doWait( $i, true, $timeout ) && $ok;
+                               }
                        }
+               } finally {
+                       // Restore the older position if it was higher
+                       $this->setWaitForPositionIfHigher( $oldPos );
                }
 
-               // Restore the older position if it was higher
-               $this->setWaitForPositionIfHigher( $oldPos );
-
                return $ok;
        }
 
index 8f94374..141a375 100644 (file)
@@ -21,6 +21,7 @@
  * @ingroup Cache
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 use \MediaWiki\MediaWikiServices;
 use \Wikimedia\WaitConditionLoop;
index 7d37944..5740925 100644 (file)
@@ -28,45 +28,77 @@ class ResourceLoaderSkinModule extends ResourceLoaderFileModule {
         * @return array
         */
        public function getStyles( ResourceLoaderContext $context ) {
-               $conf = $this->getConfig();
-               $logo = $conf->get( 'Logo' );
-               $logoHD = $conf->get( 'LogoHD' );
-
-               $logo1 = OutputPage::transformResourcePath( $conf, $logo );
-               $logo15 = OutputPage::transformResourcePath( $conf, $logoHD['1.5x'] );
-               $logo2 = OutputPage::transformResourcePath( $conf, $logoHD['2x'] );
-
+               $logo = $this->getLogo( $this->getConfig() );
                $styles = parent::getStyles( $context );
+
+               $default = !is_array( $logo ) ? $logo : $logo['1x'];
                $styles['all'][] = '.mw-wiki-logo { background-image: ' .
-                       CSSMin::buildUrlValue( $logo1 ) .
-                       '; }';
-               // Only 1.5x and 2x are supported
-               // Note: Keep in sync with OutputPage::addLogoPreloadLinkHeaders()
-               if ( $logoHD ) {
-                       if ( isset( $logoHD['1.5x'] ) ) {
+                               CSSMin::buildUrlValue( $default ) .
+                               '; }';
+
+               if ( is_array( $logo ) ) {
+                       if ( isset( $logo['1.5x'] ) ) {
                                $styles[
                                        '(-webkit-min-device-pixel-ratio: 1.5), ' .
                                        '(min--moz-device-pixel-ratio: 1.5), ' .
                                        '(min-resolution: 1.5dppx), ' .
                                        '(min-resolution: 144dpi)'
                                ][] = '.mw-wiki-logo { background-image: ' .
-                               CSSMin::buildUrlValue( $logo15 ) . ';' .
+                               CSSMin::buildUrlValue( $logo['1.5x'] ) . ';' .
                                'background-size: 135px auto; }';
                        }
-                       if ( isset( $logoHD['2x'] ) ) {
+                       if ( isset( $logo['2x'] ) ) {
                                $styles[
                                        '(-webkit-min-device-pixel-ratio: 2), ' .
                                        '(min--moz-device-pixel-ratio: 2),' .
                                        '(min-resolution: 2dppx), ' .
                                        '(min-resolution: 192dpi)'
                                ][] = '.mw-wiki-logo { background-image: ' .
-                               CSSMin::buildUrlValue( $logo2 ) . ';' .
+                               CSSMin::buildUrlValue( $logo['2x'] ) . ';' .
                                'background-size: 135px auto; }';
                        }
                }
+
                return $styles;
        }
 
+       /**
+        * @param Config $conf
+        * @return string|array Single url if no variants are defined
+        *  or array of logo urls keyed by dppx in form "<float>x".
+        *  Key "1x" is always defined.
+        */
+       public static function getLogo( Config $conf ) {
+               $logo = $conf->get( 'Logo' );
+               $logoHD = $conf->get( 'LogoHD' );
+
+               $logo1Url = OutputPage::transformResourcePath( $conf, $logo );
+
+               if ( !$logoHD ) {
+                       return $logo1Url;
+               }
+
+               $logoUrls = [
+                       '1x' => $logo1Url,
+               ];
+
+               // Only 1.5x and 2x are supported
+               if ( isset( $logoHD['1.5x'] ) ) {
+                       $logoUrls['1.5x'] = OutputPage::transformResourcePath(
+                               $conf,
+                               $logoHD['1.5x']
+                       );
+               }
+               if ( isset( $logoHD['2x'] ) ) {
+                       $logoUrls['2x'] = OutputPage::transformResourcePath(
+                               $conf,
+                               $logoHD['2x']
+                       );
+               }
+
+               return $logoUrls;
+       }
+
        /**
         * @param ResourceLoaderContext $context
         * @return bool
index 04b2f72..d92dc0a 100644 (file)
@@ -112,7 +112,6 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
                        'wgIllegalFileChars' => Title::convertByteClassToUnicodeClass( $illegalFileChars ),
                        'wgResourceLoaderStorageVersion' => $conf->get( 'ResourceLoaderStorageVersion' ),
                        'wgResourceLoaderStorageEnabled' => $conf->get( 'ResourceLoaderStorageEnabled' ),
-                       'wgResourceLoaderLegacyModules' => self::getLegacyModules(),
                        'wgForeignUploadTargets' => $conf->get( 'ForeignUploadTargets' ),
                        'wgEnableUploads' => $conf->get( 'EnableUploads' ),
                ];
@@ -330,9 +329,11 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         */
        public static function getStartupModulesUrl( ResourceLoaderContext $context ) {
                $rl = $context->getResourceLoader();
-
                $derivative = new DerivativeResourceLoaderContext( $context );
-               $derivative->setModules( self::getStartupModules() );
+               $derivative->setModules( array_merge(
+                       self::getStartupModules(),
+                       self::getLegacyModules()
+               ) );
                $derivative->setOnly( 'scripts' );
                // Must setModules() before makeVersionQuery()
                $derivative->setVersion( $rl->makeVersionQuery( $derivative ) );
index 3eac5df..fd31eac 100644 (file)
@@ -22,6 +22,7 @@
  * @author Roan Kattouw
  */
 
+use Wikimedia\Rdbms\Database;
 use Wikimedia\Rdbms\IDatabase;
 
 /**
index 52678d4..99658f2 100644 (file)
@@ -164,8 +164,6 @@ abstract class Skin extends ContextSource {
                        'content' => [
                                'mediawiki.page.ready',
                        ],
-                       // modules that exist for legacy reasons
-                       'legacy' => ResourceLoaderStartUpModule::getLegacyModules(),
                        // modules relating to search functionality
                        'search' => [],
                        // modules relating to functionality relating to watching an article
index 97d1dcb..8e79703 100644 (file)
@@ -707,6 +707,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
        public function getDefaultOptions() {
                $config = $this->getConfig();
                $opts = new FormOptions();
+               $structuredUI = $this->getUser()->getOption( 'rcenhancedfilters' );
 
                // Add all filters
                foreach ( $this->filterGroups as $filterGroup ) {
@@ -716,7 +717,7 @@ abstract class ChangesListSpecialPage extends SpecialPage {
                                $opts->add( $filterGroup->getName(), $filterGroup->getDefault() );
                        } else {
                                foreach ( $filterGroup->getFilters() as $filter ) {
-                                       $opts->add( $filter->getName(), $filter->getDefault() );
+                                       $opts->add( $filter->getName(), $filter->getDefault( $structuredUI ) );
                                }
                        }
                }
index 57610fc..9a955fb 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 use MediaWiki\Session\BotPasswordSessionProvider;
+use Wikimedia\Rdbms\IMaintainableDatabase;
 
 /**
  * Utility class for bot passwords
@@ -68,7 +69,7 @@ class BotPassword implements IDBAccessObject {
        /**
         * Get a database connection for the bot passwords database
         * @param int $db Index of the connection to get, e.g. DB_MASTER or DB_REPLICA.
-        * @return Database
+        * @return IMaintainableDatabase
         */
        public static function getDB( $db ) {
                global $wgBotPasswordsCluster, $wgBotPasswordsDatabase;
index e9f6dce..30e370e 100644 (file)
@@ -27,6 +27,7 @@ use MediaWiki\Auth\AuthManager;
 use MediaWiki\Auth\AuthenticationResponse;
 use MediaWiki\Auth\AuthenticationRequest;
 use Wikimedia\ScopedCallback;
+use Wikimedia\Rdbms\Database;
 
 /**
  * String Some punctuation to prevent editing from broken text-mangling proxies.
index 231ab22..01ca0db 100644 (file)
        "right-editsemiprotected": "تعديل الصفحات التي حمايتها \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "عدل طريقة محتوى صفحة",
        "right-editinterface": "تعديل واجهة المستخدم",
-       "right-editusercssjs": "تعديل ملفات CSS و JS للمستخدمين الآخرين",
        "right-editusercss": "تعديل ملفات CSS للمستخدمين الآخرين",
        "right-edituserjs": "تعديل ملفات جافاسكريبت للمستخدمين الآخرين",
        "right-editmyusercss": "تعديل ملفات CSS للمستخدم نفسه",
        "editcomment": "ملخص التعديل كان:<em>$1</em>.",
        "revertpage": "استرجع تعديلات [[Special:Contributions/$2|$2]] ([[User talk:$2|نقاش]]) حتى آخر مراجعة ل[[User:$1|$1]]",
        "revertpage-nouser": "استرجع تعديلات مستخدم مخفي حتى آخر مراجعة ل{{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "استرجع ØªØ¹Ø¯Ù\8aÙ\84ات {{GENDER:$3|$1}}Ø\9b\nاسترجع حتى آخر نسخة بواسطة {{GENDER:$4|$2}}.",
+       "rollback-success": "تÙ\85 Ø§Ø³ØªØ±Ø¬Ø§Ø¹ ØªØ¹Ø¯Ù\8aÙ\84ات {{GENDER:$3|$1}}Ø\8c حتى آخر نسخة بواسطة {{GENDER:$4|$2}}.",
        "rollback-success-notify": "تم استرجاع التعديلات بواسطة $1;\nتم التغيير إلى آخر مراجعة بواسطة $2. [$3 عرض التغييرات]",
        "sessionfailure-title": "فشل في الجلسة",
        "sessionfailure": "يبدو أنه هناك مشكلة في جلسة الدخول الخاصة بك؛\nلذلك فقد ألغيت هذه العملية كإجراء احترازي ضد الاختراق.\nمن فضلك اضغط على مفتاح \"رجوع\" لتحميل الصفحة التي جئت منها، ثم حاول مرة أخرى.",
        "unblocked-id": "منع $1 تم رفعه",
        "unblocked-ip": "تم رفع المنع عن [[Special:Contributions/$1|$1]].",
        "blocklist": "المستخدمون الممنوعون",
+       "autoblocklist": "منع تلقائي",
+       "autoblocklist-submit": "بحث",
+       "autoblocklist-legend": "عرض عمليات المنع التلقائي",
+       "autoblocklist-localblocks": "{{PLURAL:$1|المنع التلقائي المحلي|عمليات المنع التلقائي المحلية}}",
+       "autoblocklist-empty": "قائمة المنع التلقائي فارغة.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|المنع التلقائي الآخر|عمليات المنع التلقائي الأخرى}}",
        "ipblocklist": "المستخدمون الممنوعون",
        "ipblocklist-legend": "إيجاد مستخدم ممنوع",
        "blocklist-userblocks": "أخفِ منع الحسابات",
        "htmlform-user-not-valid": "اسم المستخدم <strong>$1</strong> غير صالح.",
        "logentry-delete-delete": "{{GENDER:$2|حذف|حذفت}} $1 صفحة $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|حذف|حذفت}} التحويلة $3 بواسطة إعادة الكتابة",
-       "logentry-delete-restore": "{{GENDER:$2|استرجع|استرجعت}} $1 صفحة $3",
+       "logentry-delete-restore": "{{GENDER:$2|استرجع|استرجعت}} الصفحة $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|استرجع|استرجعت}} الصفحة $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 مراجعة|$1 مراجعة}}",
+       "restore-count-files": "{{PLURAL:$1|1 ملف|$1 ملف}}",
        "logentry-delete-event": "{{GENDER:$2|غيّر|غيّرت}} $1 إمكانية مشاهدة {{PLURAL:$5||حدث|حدثين|$5 أحداث|$5 حدثًا|$5 حدث}} في سجل $3: $4",
        "logentry-delete-revision": "غيّر{{GENDER:$2||ت}} $1 إمكانية مشاهدة {{PLURAL:$5||مراجعة واحدة|مراجعتين|$5 مراجعات|$5 مراجعة}} في صفحة $3: $4",
        "logentry-delete-event-legacy": "{{GENDER:$2|غيّر|غيّرت}} $1 إمكانية رؤية أحداث في سجل $3",
index 23d0b1d..8a067a1 100644 (file)
        "right-editsemiprotected": "Editar les páxines protexíes como \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Editar el modelu de conteníu d'una páxina",
        "right-editinterface": "Editar la interfaz d'usuariu",
-       "right-editusercssjs": "Editar los ficheros CSS y JavaScript d'otros usuarios",
        "right-editusercss": "Editar los ficheros CSS d'otros usuarios",
        "right-edituserjs": "Editar los ficheros JavaScript d'otros usuarios",
        "right-editmyusercss": "Editar los propios ficheros CSS d'usuariu",
index 882903f..b035828 100644 (file)
        "december-date": "Pitcipipon pisimw $1",
        "pagecategories": "{{PLURAL:$1|Ka ici arimotcikatek|Ka ici arimotcikateki}}",
        "category_header": "Masinhikana ka ici arimotcikateki \"$1\"",
+       "subcategories": "Awocamec ke ici arimotcikateki",
        "hidden-categories": "{{PLURAL:$1|Ka katcictek|Ka katcicteki}}",
        "listingcontinuesabbrev": "minawatc",
        "about": "Taci we otciparik",
        "newwindow": "(cepita kotak ocki osapwakan)",
        "cancel": "Ponipita",
        "mypage": "Masinhikan",
-       "mytalk": "Ka ici arimowaniok",
+       "mytalk": "Ka ici arimowaniwok",
        "anontalk": "Ka ici arimowaniok",
        "navigation": "Matcecikinikan",
        "and": "&#32;kaie",
        "editthispage": "Mecikotona owe",
        "delete": "Wepina",
        "newpage": "Ocki matcecikinakanik",
-       "talkpagelinktext": "ka ici arimowaniok",
+       "talkpagelinktext": "ka ici arimowaniwok",
        "personaltools": "Kit irapatcitcikan",
        "talk": "Ka ici arimowaniok",
        "views": "Ke icinakok",
        "templatesused": "{{PLURAL:$1|tapapitcikan ka apatak |tapapitcikan ka apatak}} nta paskickwemakanik:",
        "template-protected": "(nakatweritcikatew)",
        "template-semiprotected": "(apita nakatoweritakon)",
-       "moveddeleted-notice": "Paskickwemakan ka ki wepinikatek.\nOhwe wapatcikan nitc ici nokon  paskickwemakanik ka ki wepinikateki acit ka ki atcipitcikateki .",
+       "moveddeleted-notice": "Paskickwemakan ka ki wepinikatek.\nOhwe wapatcikan nitc ici nokon paskickwemakanik ka ki wepinikateki acit ka ki atcipitcikateki.",
        "content-model-javascript": "JavaScript",
        "viewpagelogs": "Kinawapta kekwan kaki isparik ota masinhikanik",
        "revisionasof": "Kiwe wapata $1",
        "editundo": "nama ntwatc",
        "searchresults": "Kaki nta kiskeritakok",
        "searchresults-title": "Kaki nta kiskeritakok \"$1\"",
-       "shown-title": "Akoskoha $1 {{PLURAL:$1|result|results}}  tatwa e matce paskickwemikein",
+       "prevn": "{{PLURAL:$1|nictamictew|nictamictewa $1}}",
+       "nextn": "minawa {{PLURAL:$1|$1}}",
+       "nextn-title": "Minawa $1 {{PLURAL:$1|ke iti icinakok|ke iti icinakoki}}",
+       "shown-title": "Akoskoha $1 {{PLURAL:$1|ke iti icinakok|ke iti icinakoki}} tatwa e matce paskickwemikein",
+       "viewprevnext": "Tapwatcike ($1 {{int:pipe-separator}} $2) ($3)",
        "searchprofile-articles": "Masinhikana ka aicteki",
        "searchprofile-images": "Mitcetowina",
        "searchprofile-everything": "Kaskina",
        "searchprofile-advanced-tooltip": "Nantona taci e ici actek  ka mihikok",
        "search-result-size": "$1 ({{PLURAL:$2|1 itewin e masinatek|$2 itewina e masinateki}})",
        "search-redirect": "(Taci e kiweckwemokok $1)",
+       "search-section": "(ke arimotcikatek $1)",
        "search-suggest": "Ohwe kotcita e itasinatek:$1",
        "searchall": "kaskina",
        "powersearch-legend": "Awocamec nantona",
        "filehist-current": "mekwatc",
        "filehist-datetime": "Tatokonakisitc acitc tato tipahikaneak",
        "filehist-thumb": "Masinasonic",
+       "filehist-thumbtext": "Masinasowinicic apitc ka meckotcipatakaniwitc $1",
        "filehist-user": "Ka mitatc",
        "filehist-dimensions": "E iskwaki",
        "filehist-comment": "E iteritaman",
        "imagelinks": "Ke irapatak masinahikaniwoc",
        "nolinkstoimage": "Nama tekaci apatan masinahikaniwoc.",
+       "sharedupload-desc-here": "Owe masinhikaniwoc ote otciparin $1. Matci kotakik wec kita apitan.\nOta masinateriw $2 e irapitak.",
        "upload-disallowed-here": "Nama actew  kata meckotanaman.",
        "filedelete": "Wepina $1",
        "filedelete-submit": "Wepina",
        "allpages": "Kaskina paskickwemikana",
        "allarticles": "Kaskina paskickwemikana",
        "allpagessubmit": "Tapowata",
-       "categories": "Nakwe tipanictasinihikan",
+       "categories": "Ka ici arimotcikateki",
        "categories-submit": "Wapata",
-       "sp-deletedcontributions-contribs": "Wi kipitanikeine",
+       "sp-deletedcontributions-contribs": "E ki witcihehin",
        "linksearch-ok": "Nantokaskeritcikatek",
        "listusers-submit": "Wapata",
        "listgrouprights-namespaceprotection-namespace": "Ka ici masinasotcik",
        "namespace_association": "Taci e mamowisinasonaniwok",
        "blanknamespace": "(Ka ici ocitakiniwok)",
        "mycontris": "Wi kipitanikeine",
-       "anoncontribs": "Wi kipitanikeine",
+       "anoncontribs": "E ki witcihehin",
        "uctop": "(mekwatc)",
        "month": "Anotc pisimw ka akotcinitc (nac nte nictam):",
        "sp-contributions-talk": "ka ici arimowaniok",
        "whatlinkshere-page": "Masinhikan:",
        "linkshere": "Masinhikan ka ici tapitik <strong>[[:$1]]</strong>:",
        "isredirect": "masinhikan ke kweskiticohemikok",
+       "istemplate": "ka ki acotcipitcikatek",
        "isimage": "e ici tapitik masinahikaniwoc",
+       "whatlinkshere-prev": "{{PLURAL:$1|nictamictew|nictamictewa $1}}",
+       "whatlinkshere-next": "{{PLURAL:$1|minawa|minawa $1}}",
        "whatlinkshere-links": "← ka patiki",
        "whatlinkshere-hideredirs": "$1 itapihikina",
        "whatlinkshere-hidetrans": "$1 pitcititawina",
        "ipblocklist-submit": "Nantokaskeritcikatek",
        "blocklink": "nokipita",
        "contribslink": "wi kipitanikeine",
-       "movesubpagetalktext": "",
+       "movesubpagetalktext": "Neta ka arimotcikatek tipatcimosanikanik $1 {{PLURAL:$1|Nota paskickwemakan|Nota paskickwemakana}} kita masinatewa ota.",
        "export": "Matcetacaha masinhikana",
        "allmessages-filter-all": "Kaskina",
        "allmessages-filter-submit": "Tapowata",
        "thumbnail-more": "Micata",
        "tooltip-pt-userpage": "{{GENDER:|Ki masinahikan|Ki masinahikan}}",
+       "tooltip-pt-mytalk": "{{GENDER:|Kir}} paskickwemakanik taci e ici aiarimotcikatek",
+       "tooltip-pt-preferences": "{{GENDER:|Kir}} kirowe ka nahinaman",
+       "tooltip-pt-watchlist": "Enko ohwi ka masinateki kaskina ka ki meckotcisinahikateki",
+       "tooltip-pt-mycontris": "Masinatew ota {{GENDER:|kir}} ka ki ici witcihiweiin",
        "tooltip-pt-login": "Arimatc kika witen e icikasoin: nama tatakatc kitci kiskeritakosiin.",
        "tooltip-pt-logout": "Piskeapikenakan",
        "tooltip-pt-createaccount": "A arimatc kika ocitan kitci cenaman: nama aric tatakatc otcitakotc.",
        "exif-make": "Ka ki ocitatatc masinapiskihikaniw",
        "exif-model": "E icinakok masinapiskohewin",
        "exif-software": "Tipatcimocikimiwesinikan ka totcikatek",
+       "exif-exifversion": "Exif ka itasinatek",
        "exif-colorspace": "Icipekihikanik",
        "exif-datetimeoriginal": "E tato piponikak nictam ka masinohaniwok",
        "exif-datetimedigitized": "e tato konekisit pisimw ka capwapiskipitcikatek",
        "imgmultigo": "Tapowata!",
        "img-lang-go": "Tapowata",
        "table_pager_limit_submit": "Tapowata",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ka ici arimowaniwok]])",
        "version-ext-colheader-description": "E witcikemakak",
        "version-libraries-description": "E witcikemakak",
        "redirect-submit": "Tapowata",
        "fileduplicatesearch-submit": "Nantokaskeritcikatek",
        "specialpages": "Ka ici wectakaniok",
+       "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Kicawatcikanicic|Kicawatcikanica}}]] : $2)",
        "tags-source-header": "Ite wetciparik",
        "tags-active-yes": "Ehe",
        "tags-active-no": "Nama",
        "htmlform-no": "Nama",
        "htmlform-yes": "Ehe",
        "htmlform-cloner-delete": "Manina",
+       "logentry-delete-delete": "$1 {{GENDER:$2|ki maninam}} $3 ka arimotcikaterik",
+       "logentry-newusers-create": "Anahwe $1 aci {{GENDER:$2|ickwa ocitakiniwon}}",
        "feedback-cancel": "Ponipita",
        "searchsuggest-search": "Nantona {{SITENAME}}",
        "expand_templates_ok": "OK",
index 8bbbfd3..95397f5 100644 (file)
        "content-model-wikitext": "vikimətn",
        "content-model-text": "adi mətn",
        "content-model-javascript": "JavaScript",
+       "duplicate-args-warning": "<strong>Diqqət:</strong> [[:$1]] \"$3\" parametri üçün birdən artıq göstəricisi olan [[:$2]] şablonunu çağırır. Yalnız sonuncu göstərici istifadə ediləcək.",
        "expensive-parserfunction-category": "Kifayət qədər böyük sayda genişresurslu funksiyaların müraciət olunduğu səhifələr",
        "post-expand-template-inclusion-warning": "'''DİQQƏT!''' Daxil edilən şablonların həcmi həddindən artıq böyükdür.\nBəzi şablonlar əlavə olunmayacaq.",
        "post-expand-template-inclusion-category": "Şablonun daxil olduğu səhifələrin ölçüsü böyükdür.",
        "right-protect": "Mühafizə səviyyəsinin dəyişilməsi və kaskad mühafizə olunan səhifələrin redaktə edilməsi",
        "right-editprotected": "\"{{int:protect-level-sysop}}\" mühafizə səviyyəsinə malik səhifələrin redaktə edilməsi",
        "right-editinterface": "İstifadəçi interfeysini dəyişmək",
-       "right-editusercssjs": "Digər istifadəçilərin CSS və JavaScript fayllarını redaktə",
        "right-editusercss": "Digər istifadəçilərin CSS faylını redaktə",
        "right-edituserjs": "Digər istifadəçilərin JavaScript faylını redaktə",
        "right-markbotedits": "Geri qaytarılan dəyişikliklərin bot dəyişiklikləri kimi işarələnməsi",
        "undeleteviewlink": "görünüş",
        "undeleteinvert": "Seçilən xaricindəkiləri",
        "undeletecomment": "Səbəb:",
-       "undeletedrevisions": "Cəmi {{PLURAL:$1|1 redaktə|$1 redaktə}} geri qaytarıldı.",
-       "undeletedrevisions-files": "{{PLURAL:$1|1 versiya|$1 versiya}} və {{PLURAL:$2|1 fayl|$2 fayl}} bərpa edildi",
-       "undeletedfiles": "{{PLURAL:$1|1 fayl|$1 fayl}} bərpa olundu",
        "cannotundelete": "Bərpaetmə xətası:\n$1",
        "undeletedpage": "'''$1 bərpa edildi'''\n\nMəqalələrin bərpa edilməsi və silinməsi haqqında son dəyişiklikləri nəzərdən keçirmək üçün [[Special:Log/delete|silmə qeydlərinə]] baxın.",
        "undelete-header": "Son silinmiş səhifələrə baxmaq üçün [[Special:Log/delete|silmə qeydlərinə]] bax.",
        "badipaddress": "Səhv IP",
        "blockipsuccesssub": "Bloklandı",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] bloklanıb.<br />\nBlokları yoxlamaq üçün [[Special:BlockList|bloklama siyahısına]] baxın.",
-       "ipb-blockingself": "Özünü bloklayacaqsınız.! Bunu etmək istədiyinizdən əminsinizmi?",
+       "ipb-blockingself": "Özünüzü bloklayacaqsınız! Bunu etmək istədiyinizdən əminsinizmi?",
        "ipb-confirmhideuser": "Siz \"istifadəçini gizlə\" bəndini aktiv edərək istifadəçini bloklamaq üzrəsiniz. Bu halda istifadəçinin adı bütün siyahılarda və qeydiyyat jurnallarında görünməyəcək. Bunu etmək istədiyinizdən əminsinizmi?",
        "ipb-edit-dropdown": "Bloklama səbəblərini redaktə et",
        "ipb-unblock-addr": "$1 üzərindəki blok götürüldü",
index 3d6f8e3..8cea30d 100644 (file)
        "right-editsemiprotected": "рэдагаваньне старонак, абароненых у рэжыме «{{int:protect-level-autoconfirmed}}»",
        "right-editcontentmodel": "рэдагаваньне мадэлі зьместу старонкі",
        "right-editinterface": "рэдагаваньне інтэрфэйса карыстальніка",
-       "right-editusercssjs": "рэдагаваньне CSS і JS файлаў іншых удзельнікаў",
        "right-editusercss": "рэдагаваньне CSS файлаў іншых удзельнікаў",
        "right-edituserjs": "рэдагаваньне JS файлаў іншых удзельнікаў",
        "right-editmyusercss": "рэдагаваць уласныя карыстальніцкія CSS-файлы",
        "unblocked-id": "Блякаваньне $1 зьнятае",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] быў разблякаваны.",
        "blocklist": "Заблякаваныя ўдзельнікі",
+       "autoblocklist": "Аўтаблякаваньні",
        "ipblocklist": "Заблякаваныя ўдзельнікі",
        "ipblocklist-legend": "Пошук заблякаванага ўдзельніка",
        "blocklist-userblocks": "Схаваць блякаваньні рахункаў",
index 3216686..8ddda47 100644 (file)
        "right-editsemiprotected": "Редактиране на страници защитени като „{{int:protect-level-autoconfirmed}}“",
        "right-editcontentmodel": "Редактиране на модела на съдържанието на страница",
        "right-editinterface": "Редактиране на потребителския интерфейс",
-       "right-editusercssjs": "редактиране на CSS и JS файловете на други потребители",
        "right-editusercss": "Редактиране на CSS файловете на други потребители",
        "right-edituserjs": "Редактиране на JS файловете на други потребители",
        "right-editmyusercss": "Редактиране на собствените потребителски CSS файлове",
        "right-patrol": "Отбелязване на редакциите като проверени",
        "right-autopatrol": "Автоматично отбелязване на редакции като проверени",
        "right-patrolmarks": "Показване на отбелязаните като патрулирани последни промени",
-       "right-unwatchedpages": "преглеждане на списъка с ненаблюдаваните страници",
+       "right-unwatchedpages": "Ð\9fреглеждане на списъка с ненаблюдаваните страници",
        "right-mergehistory": "сливане на редакционни истории на страници",
        "right-userrights": "Редактиране на потребителските права",
        "right-userrights-interwiki": "редактиране на потребителски права на потребители в други уикита",
        "listgrouprights-removegroup-self-all": "Може да премахва всички групи от собствената сметка",
        "listgrouprights-namespaceprotection-header": "Ограничения на именните пространства",
        "listgrouprights-namespaceprotection-namespace": "Именно пространство",
+       "listgrouprights-namespaceprotection-restrictedto": "Права, които дават възможност на потребителите да редактират",
        "listgrants": "Разрешения",
        "listgrants-grant": "Разрешение",
        "listgrants-rights": "Права",
        "pageinfo-header-properties": "Характеристики на страницата",
        "pageinfo-display-title": "Показвано заглавие",
        "pageinfo-default-sort": "Ключ за сортиране по подразбиране",
-       "pageinfo-length": "Ð\94Ñ\8aлжина на страницата (в байтове)",
+       "pageinfo-length": "Ð\93олемина на страницата (в байтове)",
        "pageinfo-article-id": "Номер на страницата",
        "pageinfo-language": "Език на съдържанието на страницата",
        "pageinfo-language-change": "промяна",
index 5cb321e..16748c9 100644 (file)
        "right-editsemiprotected": "পাতা সম্পাদনা সুরক্ষিত রয়েছে,  \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "পাতার তথ্যের ধরণ সম্পাদনা করুন",
        "right-editinterface": "ব্যবহারকারী ইন্টারফেস সম্পাদনা",
-       "right-editusercssjs": "অন্য ব্যবহারকারীগণের CSS এবং JS ফাইল সম্পাদনা",
        "right-editusercss": "অন্য ব্যবহারকারীগণের CSS ফাইল সম্পাদনা",
        "right-edituserjs": "অন্য ব্যবহারকারীগণের JS ফাইল সম্পাদনা",
        "right-editmyusercss": "আপনার নিজস্ব ব্যবহারকারী সিএসএস ফাইল সম্পাদনা করুন",
        "rollback-missingparam": "অনুরোধে প্রয়োজনীয় প্যারামিটারগুলি অনুপস্থিত।",
        "rollback-missingrevision": "সংশোধনের উপাত্ত লোড করতে অক্ষম।",
        "cantrollback": "পূর্বের সংস্করণে ফেরত যাওয়া সম্ভব হল না, সর্বশেষ সম্পাদনাকারী এই নিবন্ধটির একমাত্র লেখক।",
-       "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|talk]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) দ্বারা সম্পাদিত সর্বশেষ [[:$1]] সম্পাদনাটি পুনর্বহাল করা যাচ্ছে না;\nঅন্য কোন ব্যবহারকারী এই পাতা ইতিমধ্যে সম্পাদনা বা পুনর্বহাল করেছেন।\n\nএই পাতায় সর্বোশেষে [[User:$3|$3]] ([[User talk:$3|talk]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]) দ্বারা সম্পাদিত।",
+       "alreadyrolled": "[[User:$2|$2]] ([[User talk:$2|আলাপ]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) দ্বারা সম্পাদিত [[:$1]]-এর সর্বশেষ সম্পাদনাটি পুনর্বহাল করা যাচ্ছে না;\nঅন্য কোন ব্যবহারকারী এই পাতা ইতিমধ্যে সম্পাদনা বা পুনর্বহাল করেছেন।\n\nএই পাতায় সর্বশেষ সম্পাদনা করেছেন [[User:$3|$3]] ([[User talk:$3|আলাপ]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]])।",
        "editcomment": "সম্পাদনা সারাংশ ছিল: \"''$1''\"।",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|আলাপ]]) এর সম্পাদিত সংস্করণ হতে [[User:$1|$1]] এর সম্পাদিত সর্বশেষ সংস্করণে ফেরত যাওয়া হয়েছে।",
        "revertpage-nouser": "একজন গোপন ব্যবহারকারী কর্তৃক সম্পাদিত সম্পাদনাটি বাতিলপূর্বক {{GENDER:$1|[[User:$1|$1]]}}-এর সর্বশেষ সম্পাদনায় ফেরত যাওয়া হয়েছে।",
        "unblocked-id": "$1 বাধাটি তুলে নেওয়া হয়েছে",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] কে অবরোধমুক্ত করা হয়েছে।",
        "blocklist": "বাধাপ্রাপ্ত ব্যবহারকারী",
+       "autoblocklist": "স্বয়ংক্রিয়বাধা",
+       "autoblocklist-submit": "অনুসন্ধান",
+       "autoblocklist-legend": "স্বয়ংক্রিয়বাধার তালিকা",
+       "autoblocklist-localblocks": "স্থানীয় {{PLURAL:$1|স্বয়ংবাধা|স্বয়ংবাধাসমূহ}}",
+       "autoblocklist-empty": "স্বয়ংক্রিয়বাধার তালিকাটি খালি।",
+       "autoblocklist-otherblocks": "অন্য {{PLURAL:$1|স্বয়ংবাধা|স্বয়ংবাধাসমূহ}}",
        "ipblocklist": "বাধাপ্রাপ্ত ব্যবহারকারী",
        "ipblocklist-legend": "বাধা দেওয়া কোন ব্যবহারকারীকে অনুসন্ধান করুন",
        "blocklist-userblocks": "অ্যাকাউন্ট বাধা লুকানো হোক",
index 47d504d..c8c2825 100644 (file)
        "right-editsemiprotected": "Uređivanje stranica pod zaštitom \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Uređivanje modela sadržaja stranice",
        "right-editinterface": "Uređivanje korisničkog interfejsa",
-       "right-editusercssjs": "Uređivanje CSS i JS datoteka drugih korisnika",
        "right-editusercss": "Uređivanje tuđih CSS datoteka",
        "right-edituserjs": "Uređivanje tuđih JavaScript datoteka",
        "right-editmyusercss": "Uređivanje vlastitih CSS datoteka",
index 3819e5b..ad5fcb6 100644 (file)
        "right-editprotected": "«{{int:protect-level-sysop}}» бахьанца ларйина агӀонаш нисъяр",
        "right-editsemiprotected": "«{{int:protect-level-autoconfirmed}}» бахьанца ларйина агӀонаш нисъяр",
        "right-editinterface": "лелош йолу интерфейсан хийцам бар",
-       "right-editusercssjs": "кхечу декъашхойн CSS- а, JS- а файлаш нисяр",
        "right-editusercss": "кхечу декъашхойн CSS-файлаш нсяр",
        "right-edituserjs": "кхечу декъашхойн JavaScript-файлаш нисяр",
        "right-editmyusercss": "Декъашхочун CSS файлаш таяр",
        "emailccsubject": "$1: $2 бохьуьтучу хааман копи",
        "emailsent": "Кехат дӀадахьийтина",
        "emailsenttext": "Хьан электроннан хаам дӏабахьийтина.",
-       "emailuserfooter": "Ð¥Ó\80аÑ\80а Ñ\85аам Ð±Ð°Ñ\85ийÑ\82инеÑ\80а $1 {{GENDER:$1|декÑ\8aаÑ\89Ñ\85оÑ\87о}} $2 {{GENDER:$2|декÑ\8aаÑ\89хочунга}} «декъашхочунга хаам» олучу функцин гӀоьнца {{SITENAME}} проектан.",
+       "emailuserfooter": "Ð¥Ó\80аÑ\80а Ñ\85аам Ð±Ð°Ñ\85ийÑ\82инеÑ\80а $1 {{GENDER:$1|декÑ\8aаÑ\88Ñ\85оÑ\87о}} $2 {{GENDER:$2|декÑ\8aаÑ\88хочунга}} «декъашхочунга хаам» олучу функцин гӀоьнца {{SITENAME}} проектан.",
        "usermessage-summary": "Битта системан хаам.",
        "usermessage-editor": "Системан дӀакхачор",
        "watchlist": "Тергаме могӀам",
index d1865db..36b0758 100644 (file)
        "right-editprotected": "دەستکاریی پەڕە پارێزراوەکانی وەک «{{int:protect-level-sysop}}»",
        "right-editsemiprotected": "دەستکاریی پەڕە پارێزراوەکانی وەک «{{int:protect-level-autoconfirmed}}»",
        "right-editinterface": "دەستکاریی ڕووکاری بەکارھێنەر",
-       "right-editusercssjs": "دەستکاریی پەڕگەکانی جاڤاسکریپت و CSSی بەکارھێنەرانی تر",
        "right-editusercss": "دەستکاریی پەڕگەکانی CSSی بەکارھێنەرانی تر",
        "right-edituserjs": "دەستکاریی پەڕگەکانی جاڤاسکریپتی بەکارھێنەرانی تر",
        "right-editmyusercss": "دەستکاریی پەڕگەکانی CSSی بەکارھێنەریی خۆی",
        "right-deletechangetags": "سڕینەوەی [[Special:Tags|tags]] لە بنکەی زانیاری",
        "grant-group-file-interaction": "مامەڵەکردن لەگەڵ میدیا",
        "grant-group-email": "ناردنی ئیمەیل",
+       "grant-blockusers": "بەربەستکردن و بەربەستنەکردنی بەکارھێنەران",
        "grant-createaccount": "دروستکردنی ھەژمار",
        "grant-createeditmovepage": "دروستکردن، دەستکاریکردن و گواستنەوەی پەڕەکان",
+       "grant-editmyoptions": "دەستکاریی ھەڵبژاردەکانی خۆت",
+       "grant-editmywatchlist": "دەستکاریکردنی لیستی چاودێرییەکەت",
+       "grant-editpage": "پەڕە ھەبووەکان دەستکاری بکە",
+       "grant-editprotected": "پەڕە پارێزراوەکان دەستکاری بکە",
+       "grant-privateinfo": "بینینی زانیارییە تایبەتییەکان",
+       "grant-protect": "پاراستن و نەپاراستنی پەڕەکان",
+       "grant-rollback": "گۆڕانکارییە گەڕاندنەوەییەکانی پەڕەکان",
        "grant-sendemail": "ناردنی ئیمەیل بۆ بەکارھێنەرانی تر",
        "grant-uploadfile": "بەڕگەی نوێ بار بکە",
        "grant-basic": "مافی سەرەکی",
        "action-deletedhistory": "دیتنی مێژووی سڕاوەی ئەم پەڕەیە",
        "action-browsearchive": "گەران لە نێو لاپەڕە سڕاوەکان",
        "action-undelete": "گەڕاندنەوەی ئەم پەڕەیە",
-       "action-suppressrevision": "چاوپێداخشان و هاردنوەی ئەم لاپەڕە شاراوە",
+       "action-suppressrevision": "چاوپێداخشان و هاوردنەوەی ئەم لاپەڕە شاراوە",
        "action-suppressionlog": "دیتنی ئەم لۆگە ئەهلیە",
        "action-block": "بەربەست کردنی ئەم بەکارهێنەرە بۆ دەستکاری‌کردن",
        "action-protect": "گۆڕینی ئاستی پاراستن بۆ ئەم پەڕەیە",
        "action-userrights-interwiki": "دەستکاری مافەکانی بەکارهێنەریی بەکارهێنەران لە ویکی‌یەکانی دیکە‌دا",
        "action-siteadmin": "داخستن یا کردنەوەی بنکەدراو",
        "action-sendemail": "ناردنی ئیمەیلەکان",
+       "action-editmyoptions": "دەستکاریی ھەڵبژاردەکانی خۆت",
        "action-editmywatchlist": "دیتنی پێرستی چاودێریت",
        "action-viewmywatchlist": "دیتنی پێرستی چاودێریت",
        "action-viewmyprivateinfo": "زانیارییە تایبەتییەکانت ببینە",
        "recentchanges-submit": "نیشانی بدە",
        "rcfilters-filterlist-whatsthis": "ئەمە چییە؟",
        "rcfilters-highlightmenu-title": "ڕەنگێکی نوێ ھەڵبژێرە",
+       "rcfilters-filter-registered-label": "تۆمارکراو",
+       "rcfilters-filter-registered-description": "ئەو بەکارھێنەرانەی لە ژوورەوەن",
+       "rcfilters-filter-unregistered-label": "تۆمارنەکراوەکان",
+       "rcfilters-filter-unregistered-description": "ئەو بەکارھێنەرانەی لە ژوورەوە نین",
        "rcfilters-filter-editsbyself-label": "مافەکانی خۆت",
        "rcfilters-filter-editsbyself-description": "دەستکارییەکانی خۆت.",
        "rcfilters-filter-editsbyother-label": "دەستکارییەکانی کەسانی تر",
        "rcfilters-filter-user-experience-level-newcomer-description": "کەمتر لە ١٠ دەستکاری و ٤ ڕۆژ لە چالاک بوون",
        "rcfilters-filter-user-experience-level-experienced-label": "بەکارھێنەرانی پێشکەوتوو",
        "rcfilters-filter-user-experience-level-experienced-description": "زیاتر لە ٣٠ ڕۆژ لە چالاکی و ٥٠٠ دەستکاری",
+       "rcfilters-filter-bots-label": "بۆت",
        "rcfilters-filter-humans-label": "مرۆڤ (بۆت نییە)",
        "rcfilters-filter-humans-description": "دەستکارییەکانی لەلایەن مرۆڤەکانەوە ئەنجام دراون",
        "rcfilters-filter-patrolled-label": "پاسدراو",
        "rcfilters-filter-patrolled-description": "ئەو دەستکارییانەی وەک پاسدراو دیاریکراون",
+       "rcfilters-filter-unpatrolled-label": "پاسنەدراوەکان",
+       "rcfilters-filter-unpatrolled-description": "ئەو دەستکارییانەی وەک پاسدراو دیارینەکراون",
        "rcfilters-filter-minor-label": "دەستکارییە بچووکەکان",
        "rcfilters-filter-minor-description": "ئەو دەستکارییانەی کە دەستکاریکەر وەک بچووک ناوی بردووە",
        "rcfilters-filter-major-label": "دەستکارییە نا-بچووکەکان",
+       "rcfilters-filter-pageedits-label": "دەستکارییەکانی پەڕە",
+       "rcfilters-filter-newpages-label": "دروستکردنی پەڕەکان",
+       "rcfilters-filter-categorization-label": "گۆڕانکاری پۆلەکان",
        "rcnotefrom": "ژێرەوە {{PLURAL:$5|گۆڕانکارییەکەیە|گۆڕانکارییەکانە}} لە strong>$3، $4</strong>ەوە (ھەتا <strong>$1</strong> نیشان دراوە).",
        "rclistfrom": "گۆڕانکارییە نوێکان نیشان بدە بە دەستپێکردن لە $3 $2",
        "rcshowhideminor": "دەستکارییە بچووکەکان $1",
        "upload-misc-error-text": "هەڵەیەکی نەناسراو لە کاتی بارکردن ڕووی‌دا.\nتکایە لە درووست‌بوون و دەست‌پێ گەیشتنی URL ئەرخەیان ببە و دیسان تاقی‌بکەوە.\nگەر کێشەکە هەر بەردەوام بوو پەیوەندی بکە بە [[Special:ListUsers/sysop|بەڕێوبەر]].",
        "upload-too-many-redirects": "URL ڕەوانەکەری زۆری لەخۆ گرتووە",
        "upload-http-error": "هەڵەیەکی HTTP ڕووئ داوە: $1",
+       "upload-dialog-title": "بارکردنی پەڕگە",
        "upload-dialog-button-cancel": "ھەڵوەشاندنەوە",
        "upload-dialog-button-back": "گەڕانەوە",
        "upload-dialog-button-done": "کرا",
        "uploadstash": "ئەمباری بارکردن",
        "uploadstash-errclear": "سڕینەوەی پەڕگەکان سەرکەوتوو نەبوو.",
        "uploadstash-refresh": "نوێکردنەوەی پێرستی پەڕگەکان",
+       "uploadstash-thumbnail": "بینینی وێنۆک",
        "img-auth-accessdenied": "تێپه‌ربوون ره‌تکرایه‌وه‌",
        "img-auth-nofile": "فایلی \"$1\" بوونی نیه‌",
        "img-auth-isdir": "هه‌وڵ ده‌ده‌ی بۆ کردنه‌وه‌ی بوخچه‌ی \"$1\" له‌ کاتێکدا ته‌نیا کردنه‌وه‌ی فایل رێپێدراوه‌",
        "randompage": "پەڕەی ھەڕەمەکی",
        "randompage-nopages": "ھیچ پەڕەیەک لە {{PLURAL:$2|بۆشایی ناو|بۆشایی ناوەکان}}ی خوارەوەدا نییە: $1.",
        "randomincategory": "پەڕەیەک بە ھەڵکەوت لە پۆلدا",
+       "randomincategory-category": "پۆل:",
+       "randomincategory-legend": "پەڕەیەک بە ھەڵکەوت لە پۆلدا",
        "randomincategory-submit": "بڕۆ",
        "randomredirect": "ڕەوانەکەری ھەڕەمەکی",
        "randomredirect-nopages": "لە ناوبۆشایی \"$1\" هیچ ڕەوانکەرێک نییە.",
        "protectedpages-page": "پەڕە",
        "protectedpages-params": "پارامەترەکانی پاراستن",
        "protectedpages-reason": "ھۆکار",
+       "protectedpages-unknown-timestamp": "نەزانراو",
+       "protectedpages-unknown-performer": "بەکارھێنەرێکی نەناسراو",
        "protectedtitles": "سەرناوە پارێزراوەکان",
        "protectedtitlesempty": "ھیچ سەرناوێک بەم سنوورانەوە ئێستا نەپارێزراوە.",
        "listusers": "پێرستی بەکارھێنەران",
        "pager-older-n": "{{PLURAL:$1|یەکێک کۆنتر|$1ی کۆنتر}}",
        "suppress": "چاودێری",
        "apisandbox-unfullscreen": "نیشاندانی پەڕە",
+       "apisandbox-submit": "داواکاری",
+       "apisandbox-reset": "سڕینەوە",
+       "apisandbox-retry": "ھەوڵداناوە",
+       "apisandbox-results": "ئاکامەکان",
+       "apisandbox-continue": "بەردەوامبوون",
+       "apisandbox-continue-clear": "سڕینەوە",
        "booksources": "سەرچاوەکانی کتێب",
        "booksources-search-legend": "گەڕان بۆ سەرچاوەکانی کتێب",
        "booksources-search": "بگەڕێ",
        "allpages-bad-ns": "{{SITENAME}} ناوبۆشایی نیە \"$1\".",
        "allpages-hide-redirects": "ڕەوانەکەرەکان بشارەوە",
        "cachedspecial-viewing-cached-ttl": "خەریکیت وەشانێکی حەشارکراوی ئەم پەڕەیە دەبینی کە دەتوانێت ھی $1 لەمەوبەر بێت.",
+       "cachedspecial-viewing-cached-ts": "تۆ وەشانێکی کاشکراوی ئەم پەڕەیە دەبینیت، لەوانەیە زانیارییەکان گۆڕانکارییان بەسەردا ھاتبێت.",
        "cachedspecial-refresh-now": "دواترین پیشانبدە",
        "categories": "پۆلەكان",
        "categories-submit": "نیشاندان",
        "activeusers-count": "$1 {{PLURAL:$1|کردەوە}} لە دوایین {{PLURAL:$3|ڕۆژ|$3 ڕۆژ}}دا",
        "activeusers-from": "نیشاندانی بەکارھێنەران بە دەستپێکردن لە:",
        "activeusers-noresult": "هیچ بەکارهێنەرێک نەدۆزرایەوە",
+       "activeusers-submit": "بەکارھێنەرە چالاکەکان نیشان بدە",
        "listgrouprights": "مافەکانی گرووپی بەکارھێنەر",
        "listgrouprights-summary": "ئەمە لیستێکە لە گرووپەکانی بەکارهێنەر لەسەر ئەم ویکی‌یە، دەگەڵ مافەکانی دەست‌پێ‌گەیشتنی هاوپەیوەندیان.\nلێرەدا لەوانەیە [[{{MediaWiki:Listgrouprights-helppage}}|زانیاری زیاترت]] دەست‌کەوێت سەبارەت بە مافە تاکەکەسیەکان.",
        "listgrouprights-key": "تێبینی:\n* <span class=\"listgrouprights-granted\">مافی دراوە</span>\n* <span class=\"listgrouprights-revoked\">مافی سەنراوە</span>",
        "listgrouprights-namespaceprotection-header": "سنوورداریی بۆشایی ناو",
        "listgrouprights-namespaceprotection-namespace": "بۆشایی ناو",
        "listgrouprights-namespaceprotection-restrictedto": "مافی رێ‌پێدراوی بەکارھێنەر بۆ دەستکاری",
+       "listgrants-rights": "مافەکان",
        "trackingcategories": "پۆلەکانی شوێنکەوتن",
        "trackingcategories-name": "ناوی پەیام",
+       "trackingcategories-nodesc": "ھیچ وردەکارییەک بەردەست نییە",
        "mailnologin": "ناونیشان بۆ ناردن نییە",
        "mailnologintext": "ده‌بێ له‌ [[Special:UserLogin|ژووره‌وه‌]] بیت و ناونیشانێکی بڕواپێ‌کراوی ئی‌مه‌یلت له‌ ناو [[Special:Preferences|هه‌ڵبژارده‌کان]] دیاری کردبێت تا بتوانی ئی‌مه‌یل بنێریت بۆ به‌کارهێنه‌رانی دیکه‌.",
        "emailuser": "ئیمەیل بنێرە بۆ ئەم بەکارھێنەرە",
        "wlshowtime": "ماوەی کات بۆ نیشاندان:",
        "wlshowhideminor": "دەستکارییە بچووکەکان",
        "wlshowhidebots": "بۆتەکان",
+       "wlshowhideliu": "بەکارھێنەرە تۆمارکراوەکان",
        "wlshowhideanons": "بەکارھێنەرە نەناسراوەکان",
+       "wlshowhidepatr": "دەستکارییە پاسدراوەکان",
        "wlshowhidemine": "دەستکارییەکانم",
        "wlshowhidecategorization": "پۆلێنکردنی پەڕە",
        "watchlist-options": "ھەڵبژاردەکانی لیستی چاودێری",
        "watching": "چاودێری...",
        "unwatching": "لابردنی چاودێری...",
+       "watcherrortext": "کێشەیەک دروست بوو لەکاتی گۆڕینی پێڕستی چاودێریت بۆ «$1».",
        "enotif_reset": "ھەموو پەڕەکان وەک بینراو دیاری بکە",
        "enotif_impersonal_salutation": "بەکارهێنەری \t{{SITENAME}}",
        "enotif_subject_deleted": "پەڕەی {{SITENAME}} $1 بە دەستی {{gender:$2|$2}} سڕایەوە.",
        "delete-edit-reasonlist": "دەستکاری کردنی ھۆکارەکانی سڕینەوە",
        "delete-toobig": "ئەم لاپەڕە مێژوویەکی دەستکاری زۆر گەورەی هەیە، زیاتر لە $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}.\nبۆ بەرگری لە خراپ‌بوونی چاوەڕوان نەکراوی {{SITENAME}}، سڕینەوەی لاپەڕەی وا بەربەست‌کراوە.",
        "delete-warning-toobig": "ئەم پەڕەیە مێژوویەکی دەستکاریی زۆر گەورەی ھەیە، زۆرتر لە $1 {{PLURAL:$1|پێداچوونەوە}}.\nسڕینەوەی ئەو پەڕەیە لەوانەی کارەکانی بنکەدراوەی {{SITENAME}} تووشی کێشە بکات؛\nبە سەرنجەوە بچۆ پێشەوە.",
-       "deleting-backlinks-warning": "'''ھۆشدار:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|پەڕەکانی تر]] بەم پەڕەیەی دەتەوێ بیسڕییەوە بەستەر دراوە.",
+       "deleteprotected": "تۆ ناتوانیت ئەم پەڕەیە بسڕیتەوە لەبەرئەوەی پارێزراوە.",
+       "deleting-backlinks-warning": "'''ئاگاداری:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|پەڕەکانی تر]] بەم پەڕەیەی دەتەوێ بیسڕییەوە بەستەر دراوە.",
        "rollback": "گەڕاندنەوەی دەستکارییەکان",
        "rollbacklink": "گەڕاندنەوە",
        "rollbacklinkcount": "گەڕاندنەوەی $1 {{PLURAL:$1|دەستکاری}}",
        "sessionfailure": "لەوەدەچی کێشەیەک لە دانیشتنی چوونەژوورەوەت (login session)دا ببێت.\nئەم کردەوە هەڵوەشێندرایەوە بۆ بەرگری لە دزینی دراوەکانی دانیشتن.\nتکایە بگەڕێوە بۆ پەڕەی پێشوو و نوێی بکەوە، ئینجا دیسان تاقیی بکەوە.",
        "changecontentmodel-title-label": "سەرناوی پەڕە",
        "changecontentmodel-reason-label": "هۆکار:",
+       "changecontentmodel-submit": "گۆڕین",
+       "logentry-contentmodel-change-revertlink": "گەڕاندنەوە",
+       "logentry-contentmodel-change-revert": "گەڕاندنەوە",
        "protectlogpage": "لۆگی پاراستن",
        "protectlogtext": "لە ژێرەوە پێرستێک لە گۆڕانکارییەکانی پەڕە پارێزراوەکان دەبینی.\nبۆ پێرستی ئەو پەڕانەی ئێستا پاراستنیان لە ئارادایە بڕوانە [[Special:ProtectedPages|پێرستی پەڕە پارێزراوەکان]].",
        "protectedarticle": "«[[$1]]»ی پاراست",
        "modifiedarticleprotection": "ئاستی پاراستنی «[[$1]]»ی گۆڕی",
        "unprotectedarticle": "پاراستنی لەسەر «[[$1]]» لابرد",
        "movedarticleprotection": "ڕێککارییەکانی پاراستن لە  «[[$2]]» گوازرایەوە بۆ «[[$1]]»",
+       "protectedarticle-comment": "«[[$1]]»ی {{GENDER:$2|پاراست}}",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|ئاستی پاراستنی گۆڕی}} بۆ «[[$1]]»",
        "unprotectedarticle-comment": "{{GENDER:$2|پاراستنی}} لەسەر ''[[$1]]'' لابرد",
        "protect-title": "گۆڕینی ئاستی پاراستنی \"$1\"",
        "protect-title-notallowed": "دیتنی ئاستی پاراستنی «$1»",
        "prot_1movedto2": "[[$1]] گوازرایەوە بۆ [[$2]]",
+       "protect-badnamespace-text": "ئەو پەڕانەی لەم بۆشایی ناوەدان ناتواندرێت بپارێزرێن.",
        "protect-legend": "پاراستن تەیید بکە",
        "protectcomment": "ھۆکار:",
        "protectexpiry": "ھەتا:",
        "protect-othertime": "کاتی تر:",
        "protect-othertime-op": "کاتی تر",
        "protect-existing-expiry": "ئەم کاتی بەسەرچوونی ماوە کە هەیە: $3، $2",
+       "protect-existing-expiry-infinity": "کاتی بەسەرچوون: بێ کۆتا",
        "protect-otherreason": "ھۆکاری تر/زیاتر:",
        "protect-otherreason-op": "ھۆکاری تر",
        "protect-dropdown": "*ھۆکارە باوەکانی پاراستن\n** خراپکاریی لەڕادەبەدەر\n** سپامی لەڕادەبەدەر\n** شەڕە دەستکاریی بێ‌سوود\n** پەڕەی زۆربینەردار",
        "undeletepagetext": "ئەم {{PLURAL:$1|سڕاوەتەوە|$1 لاپەڕە سڕاونەتەوە}} بەڵام لەبەر ئەوەی لە ئەرشیڤ‌دا هەن هێشتا دەتوانی بیانهێنیتەوە.\nئەرشیڤ چەن‌وەخت جارێ لە کاتی دیاری‌کراودا خاوێن‌دەکرێتەوە.",
        "undelete-fieldset-title": "هێنانەوەی پێداچوونەوەکان",
        "undeleteextrahelp": "بۆ ھێنانەوەی گشت مێژووی پەڕەکە، ھەموو چوارچێوەکانی نیشانکردن ھەڵنەبژێردراو بھێڵەوە و لە سەر '''''{{int:undeletebtn}}''''' کرتە بکە.\nبۆ ھێنانەوەی ھەڵبژێردراو، چوارچێوەی بەرامبەر بەو پێداچوونەویەی دەتەوێ بیھێنیتەوە، نیشان بکە و لە سەر '''''{{int:undeletebtn}}''''' کرتە بکە.",
-       "undeleterevisions": "$1 {{PLURAL:$1|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95}} Ø¦Û\95رشÛ\8cÚ¤â\80\8cکرا",
+       "undeleterevisions": "$1 {{PLURAL:$1|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95}} Ø³Ú\95دراÛ\8cÛ\95Ù\88Û\95",
        "undeletehistory": "ئەگەر پەڕەیەک بھێنیتەوە، ھەموو پێداچوونەوەکان دەگەڕێنەوە بۆ مێژووی پەڕە.\nئەگەر لە کاتی سڕانەوەی پەڕەکەوە، پەڕەیەک هەر بەو ناوەوە دروست کرابێت، پێداچوونەوە گەرێنراوەکان لە مێژووی پێشووەکەدا دەدرەکەوێت.",
        "undeletehistorynoadmin": "ئەم پەڕەیە سڕاوەتەوە.\nھۆکاری سڕینەوە و وردەکارییەکانی ئەو بەکارھێنەرانەی کە پێش سڕینەوەی دەستکارییان کردووە لە پۆختەی خوارەوەدا نیشان دراوە.\nدەقی ڕاستەقینەی ئەم پێداچوونەوە سڕراوانە تەنھا لەبەر دەستی بەڕێوەبەراندایە.",
        "undelete-revision": "پێداچوونەوەی سڕاوەی $1 (لە $4،  $5) لەلایەن $3:",
        "undeleteviewlink": "دیتن",
        "undeleteinvert": "ھەڵبژاردەکان پێچەوانە بکە",
        "undeletecomment": "هۆکار:",
-       "undeletedrevisions": "{{PLURAL:$1|$1 پێداچوونەوە}} هێنرایەوە",
-       "undeletedrevisions-files": "{{PLURAL:$1|1 پێداچوونەوە|$1 پێداچوونەوە}} و {{PLURAL:$2|1 پەڕگە|$2 پەڕگە}} هێنرایەوە",
-       "undeletedfiles": "{{PLURAL:$1|1 پەڕگە|$1 پەڕگە}} هێنرایەوه",
        "cannotundelete": "ھێنانەوە سەرکەوتوو نەبوو:\n$1",
        "undeletedpage": "'''$1 هێنراوەتەوە'''\n\nبۆ دیتنی پێشینەی دوایین سڕینەوەکان و هێنانەوەکان سەرنجی [[Special:Log/delete|لۆگی سڕینەوە]] بدە.",
        "undelete-header": "بۆ دیتنی ئەو لاپەڕانەی لەم داییانەدا سڕاونەتەوە چاو لە [[Special:Log/delete|لۆگی سڕینەوە]] بکە.",
        "undelete-no-results": "لە ئەرشیڤی سڕاوەکانی لاپەڕەیەکی هاوتا نەدۆزرایەوە.",
        "undelete-cleanup-error": "هەڵە لە سڕینەوەی ئەرشیڤی بەکەڵک نەهاتووی پەڕگە \"$1\".",
        "undelete-missing-filearchive": "ناکرێ ئەرشیڤی پەڕگە بە پێناسەی $1 بهێنیتەوە لەبەر ئەوەی لە ناو بنکەی دراوە‌دا نییە.\nلەوانەیە لە‌پێش‌دا هێنرابێتەوە.",
+       "undelete-error": "کێشە دروست بوو لەکاتی ھەوڵدان بۆ ھێنانەوەی پەڕەکە",
        "undelete-error-short": "هەڵە لە گەڕاندنەوەی سڕینەوەی پەڕگە: $1",
        "undelete-error-long": "هەڵەیەک لە کاتی گەڕاندنەوەی سڕینەوەی پەڕگە ڕووی‌دا:\n\n$1",
        "undelete-show-file-confirm": "ئایا ئەرخەیانی کە دەتەوێ پێداچوونەوە سراوەکەی پەڕگەی \"<nowiki>$1</nowiki>\" لە $2 لە $3 ببینی؟",
        "mycontris": "بەشدارییەکان",
        "anoncontribs": "بەشدارییەکان",
        "contribsub2": "بۆ {{GENDER:$3|$1}} ($2)",
+       "contributions-userdoesnotexist": "ھەژماری بەکارھێنەریی «$1» تۆمار نەکراوە.",
        "nocontribs": "هیچ گۆڕانکاریەکی هاوتای ئەم پێوەرانە نودۆزرایەوە",
        "uctop": "(ھەنووکە)",
        "month": "لە مانگی (و پێشترەوە):",
        "badipaddress": "ناونیشانی ئای‌پی نەگونجاو",
        "blockipsuccesssub": "بەربەست کردن سەرکەوتوو بوو",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] بەربەست کرا.<br />\nبڕوانە [[Special:BlockList|پێرستی بەربەستن]] بۆ بەسەرداچوونەوەی بەربەستنەکان.",
+       "ipb-blockingself": "تۆ خەریکە خۆت بەربەست دەکەیت! دڵنیایت کە دەتەوێت ئەم کارە بکەیت؟",
        "ipb-edit-dropdown": "دەستکاری هۆکارەکانی بەربەست",
        "ipb-unblock-addr": "لە بەربەست‌دەرهێنانی $1",
        "ipb-unblock": "لە بەربەست‌دەرهێنانی ناوی بەکارهێنەریەک یا ناونیشانێکی ئای‌پی",
        "ipb-blocklist": "دیتنی ئەو بەربەستانەی وا هەیە",
        "ipb-blocklist-contribs": "بەشدارییەکانی {{GENDER:$1|$1}}",
+       "ipb-blocklist-duration-left": "$1 ماوە",
        "unblockip": "لە بەربەست‌دەرهێنانی بەکارهێنەر",
        "unblockiptext": "بۆ گەڕاندنەوەی دەست‌پی‌گەیشتنی نووسین بۆ ئەو دوایین ئای‌پی یان بەکارهێنەری بەربەست کراوە، لەو فۆرمەی خوارەوە کەڵک وەرگرە.",
        "ipusubmit": "لابردنی ئەم بەربەستە",
        "unblocked": "[[User:$1|$1]] لە بەربەست دەرهێنرا",
+       "unblocked-range": "بەربەست لەسەر $1 لابرا.",
        "unblocked-id": "بەربەستی $1 لابرا",
+       "unblocked-ip": "بەربەست لەسەر [[Special:Contributions/$1|$1]] لابرا.",
        "blocklist": "بەکارھێنەرە بەربەستکراوەکان",
+       "autoblocklist": "بەربەستی ئۆتۆماتیکی",
+       "autoblocklist-submit": "گەڕان",
        "ipblocklist": "بەکارھێنەرە بەربەستکراوەکان",
        "ipblocklist-legend": "دۆزینەوەی بەکارهێنەرێکی بەربەست‌کراو",
        "blocklist-userblocks": "ھەژمارە بەربەستکراوەکان بشارەوە",
        "sorbsreason": "ناونیشانی ئای‌پی تۆ لە DNSBLدا کە {{SITENAME}} کەڵکی لێ‌وەر دەگرێ، وەک پرۆکسیەکی کراوە لیست کراوە.",
        "sorbs_create_account_reason": "ناونیشانی ئای‌پی تۆ لە DNSBLدا کە {{SITENAME}} کەڵکی لێ‌وەر دەگرێ، وەک پرۆکسیەکی کراوە لیست کراوە.\nبۆیە ناتوانی هەژمارە درووست‌بکەی.",
        "ipbblocked": "ناتوانی بەکارھێنەرانی تر بەربەست بکەیت یان بکەیتەوە، چونکوو خۆت بەربەست کراوی.",
+       "ipbnounblockself": "تۆ ڕێگە پێ نەدراویت کە بەربەست لەسەر خۆت لابەریت.",
        "lockdb": "داخستنی بنکەدراوە",
        "unlockdb": "کردنەوەی بنکەدراوە",
        "lockdbtext": "داخستنی بنکەدراوە ئەبێتە هۆی ڕاگرتنی توانای هەموو بەکارهێنەران بۆ دەستکاری لاپەڕەکان، گۆڕانی هەڵبژاردەکانیان، دەستکاری لیستی چاودێرییەکانیان و هەموو ئەموو ئەو شتانە وا پێویستی بە گۆرانکاری لە بنکەدراوە هەیە.\nتکایە ئەرخەیان بە ئەمە هەر ئەوەیە کە دەتەوێ بیکەی و دوای چاکسازیەکەت لەیادت بێ کە بنکەدراوەکە بکەیتەوە.",
        "allmessages-prefix": "پاڵێو بە پێشگر:",
        "allmessages-language": "زمان:",
        "allmessages-filter-submit": "بڕۆ",
+       "allmessages-filter-translate": "وەرگێڕان",
        "thumbnail-more": "گەورە کردنەوە",
        "filemissing": "ون‌بوونی پەڕگە",
        "thumbnail_error": "هەڵە کاتی درووست‌کردنی هێما: $1",
        "tooltip-pt-preferences": "{{GENDER:|هەڵبژاردەکانت}}",
        "tooltip-pt-watchlist": "پێڕستی ئەو پەڕانەی کە چاودێریی گۆڕانکارییەکانیان دەکەیت",
        "tooltip-pt-mycontris": "پێڕستی بەشدارییەکان",
+       "tooltip-pt-anoncontribs": "پێڕستی ئەو دەستکارییانەی لەم ناونیشانی ئای-پییەوە کراوە",
        "tooltip-pt-login": "پێشنیارت پێدەکرێ بچیتە ژوورەوە؛ ھەرچەندە زۆرت لێناکرێ",
        "tooltip-pt-logout": "دەرچوون",
        "tooltip-pt-createaccount": "تۆ ھان دەدرێیت کە ھەژمارێک دروست بکەیت و بچیتە ژوورەوە، ئەمە سەرەکی نییە بەھەرحاڵ",
        "tooltip-feed-atom": "Atom feed بۆ ئەم پەڕە",
        "tooltip-t-contributions": "پێڕستی بەشدارییەکانی {{GENDER:$1|ئەم بەکارھێنەرە}}",
        "tooltip-t-emailuser": "ئیمەیڵێک بنێرە بۆ {{GENDER:$1|ئەم بەکارھێنەرە}}",
+       "tooltip-t-info": "زانیاری زیاتر لەبارەی ئەم پەڕەیەوە",
        "tooltip-t-upload": "پەڕگە بار بکە",
        "tooltip-t-specialpages": "پێڕستی ھەموو پەڕە تایبەتەکان",
        "tooltip-t-print": "وەشانی چاپی ئەم پەڕەیە",
        "tooltip-ca-nstab-category": "بینینی پەڕەی پۆلەکە",
        "tooltip-minoredit": "ئەمە وەک گۆڕانکارییەکی بچووک دیاری بکە",
        "tooltip-save": "گۆڕانکارییەکانی خۆت پاشکەوت بکە",
+       "tooltip-publish": "پاشەکەوتکردنی گۆڕانکارییەکان",
        "tooltip-preview": "پێش بینینی گۆڕانکارییەکان، تکایە پێش پاشکەوت کردن ئەمە بەکار بھێنە",
        "tooltip-diff": "نیشان دانی گۆڕانکارییەکانت لە دەقەکەدا",
        "tooltip-compareselectedversions": "جیاوازییەکانی دوو وەشانە دیاریکراوەی ئەم پەڕەیە ببینە.",
        "pageinfo-length": "قەبارەی پەڕە (بایت)",
        "pageinfo-article-id": "زنجیرەی پەڕە",
        "pageinfo-language": "زمانی ناوەرۆکی پەڕە",
+       "pageinfo-language-change": "گۆڕین",
        "pageinfo-content-model": "شێوازی ناوەرۆکی پەڕە",
+       "pageinfo-content-model-change": "گۆڕین",
        "pageinfo-robot-policy": "پێرستکردن بە بۆتەکان",
        "pageinfo-robot-index": "ڕێ پێدراو",
        "pageinfo-robot-noindex": "ڕێ پێنەدراوه",
        "pageinfo-hidden-categories": "{{PLURAL:$1|پۆلی شاردراوە|پۆلە شاردراوەکان}} ($1)",
        "pageinfo-templates": "{{PLURAL:$1|داڕێژەی|داڕێژە}} {{PLURAL:$1|بەکارگیراو|بەکارگیراوەکان}} ($1)",
        "pageinfo-toolboxlink": "زانیاریی پەڕە",
+       "pageinfo-redirectsto": "ڕەوانە دەکرێت بۆ",
        "pageinfo-redirectsto-info": "زانیاری",
        "pageinfo-contentpage": "ھەژمارکراو وەک پەڕەی بەناوەرۆک",
        "pageinfo-contentpage-yes": "بەڵێ",
        "patrol-log-page": "لۆگی پاسدان",
        "patrol-log-header": "ئەمە لۆگێکی پێداچوونەوە پاس دراوەکانە.",
        "log-show-hide-patrol": "لۆگی پاسدان $1",
+       "confirm-markpatrolled-button": "باشە",
        "deletedrevision": "پێداچوونەوەی کۆنی سڕاوە $1",
        "filedeleteerror-short": "هەڵە لە سڕینەوەی پەڕگە: $1",
        "filedeleteerror-long": "کاتی سڕینەوەی ئەم پەڕگەی ڕووبەڕووی کێشە بووینەوە:\n\n$1",
        "newimages-summary": "ئەم پەڕە تایبەتە دوایین پەڕگە بارکراوەکان نیشان دەدات.",
        "newimages-legend": "پاڵاوتن",
        "newimages-label": "ناوی پەڕگە (یان بەشێکیی):",
+       "newimages-user": "ناونیشانی ئای-پی یان ناوی‌ بەکارھێنەر",
+       "newimages-showbots": "بارکردنی بۆتەکان پیشان بدە",
+       "newimages-hidepatrolled": "شاردنەوەی بارکردنە پاسدراوەکان",
        "noimages": "هیچ بۆ بینین نییە.",
        "ilsubmit": "بگەڕێ",
        "bydate": "بەپێی ڕێکەوت",
        "exif-model": "جۆری کامێرا",
        "exif-software": "نەرمەواڵەی بەکارهاتوو",
        "exif-artist": "نووسەر",
+       "exif-copyright": "ھەڵگری مۆڵەتنامە",
        "exif-exifversion": "وەشانی exif",
        "exif-colorspace": "بۆشایی ره‌نگ",
        "exif-pixelxdimension": "پانی وێنە",
index 79e2bf7..39494b8 100644 (file)
        "right-editsemiprotected": "Editace stránek zamčených na „{{int:protect-level-autoconfirmed}}“",
        "right-editcontentmodel": "Editace modelu obsahu stránky",
        "right-editinterface": "Editace zpráv uživatelského rozhraní",
-       "right-editusercssjs": "Editace CSS a JS souborů jiných uživatelů",
        "right-editusercss": "Editace CSS souborů jiných uživatelů",
        "right-edituserjs": "Editace JavaScriptových souborů jiných uživatelů",
        "right-editmyusercss": "Editace vlastních uživatelských CSS souborů",
index b74fbb1..07cd763 100644 (file)
        "right-editsemiprotected": "Seiten bearbeiten, die als „{{int:protect-level-autoconfirmed}}“ geschützt sind",
        "right-editcontentmodel": "Das Inhaltsmodell einer Seite bearbeiten",
        "right-editinterface": "Systemnachrichten und Benutzeroberflächen bearbeiten",
-       "right-editusercssjs": "Fremde CSS- und JavaScript-Dateien bearbeiten",
        "right-editusercss": "Fremde CSS-Dateien bearbeiten",
        "right-edituserjs": "Fremde JavaScript-Dateien bearbeiten",
        "right-editmyusercss": "Eigene Benutzer-CSS-Dateien bearbeiten",
index 735f273..552b1f2 100644 (file)
        "shown-title": "Her pele sero $1 {{PLURAL:$1|netici|netica}} bımocne",
        "viewprevnext": "($1 {{int:pipe-separator}} $2) ($3) bıviné",
        "searchmenu-exists": "''Ena 'Wikipediya de ser \"[[:$1]]\" yew pel esto'''",
-       "searchmenu-new": "<strong>Na wiki de pela \"[[:$1]]\" vıraze!</strong> {{PLURAL:$2|0=|Sewbina pela ke şıma geyrayê cı aye bıvênê.|Yew zi neticanê cıgeyrayışê xo bıvênê.}}",
+       "searchmenu-new": "<strong>Ena wiki de perra \"[[:$1]]\" vıraze!</strong> {{PLURAL:$2|0=|Sewbina pela ke şıma geyrayê cı aye bıvênê.|Yew zi peyniyanê cıgeyrayışê xo bıvênê.}}",
        "searchprofile-articles": "Perrê zerreki",
        "searchprofile-images": "Multimedya",
        "searchprofile-everything": "Pêro çi",
        "right-editsemiprotected": "Xısusi pera timaryayış \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Modelê zerrekê pele bıvurne",
        "right-editinterface": "Interfaceê karberi sero bıgureye",
-       "right-editusercssjs": "CSS u dosyanê JSiê karberanê binan sero bıgureye",
        "right-editusercss": "Dosyanê CSSiê karberanê binan sero bıgureye",
        "right-edituserjs": "Dosyanê JSiê karberanê binan sero bıgureye",
        "right-editmyusercss": "CSS dosyaya karberinda ğo timar ke",
index 30cc41c..cb9065f 100644 (file)
        "right-block": "अरु प्रयोगकर्तानलाई सम्पादन गद्दाकी ब्लक गर",
        "right-unblockself": "आफुलाई खुल्ला गर ।",
        "right-editprotected": "\"{{int:protect-level-sysop}}\" को हैसियतले सुरक्षित पानाहरू सम्पादन गद्या",
-       "right-editusercssjs": "अन्य प्रयोगकर्ताको सी.एस.एस. रे जाभास्क्रिप्ट फाइलहरू सम्पादन गद्या",
        "right-editusercss": "अन्य प्रयोगकर्ताको सी. एस. एस. फाइलहरू सम्पादन गद्या",
        "right-edituserjs": "अरु प्रयोकर्ताका जाभास्क्रिप्ट फाइलहरू सम्पादन गर्न्या",
        "right-rollback": "पछिल्लो प्रयोगकर्ताको सम्पादनहरूलाई छरितो रुपमी पछाडि पर्काउन्या",
        "filehist-user": "प्रयोगकर्ता",
        "filehist-dimensions": "आयाम",
        "filehist-comment": "टिप्पणी",
-       "imagelinks": "फाà¤\87लà¤\95à¥\8b à¤ªà¥\8dरयà¥\8bà¤\97हरà¥\81",
+       "imagelinks": "फाà¤\87लà¤\95à¥\8b à¤ªà¥\8dरयà¥\8bà¤\97हरà¥\82",
        "linkstoimage": "यै चित्रमी निम्न{{PLURAL:$1|पाना जोडिनान{{PLURAL:$1|}}|$1 पानाहरू जोडिनान्}}:",
        "nolinkstoimage": "यो चित्रसित लिंकभयाकि कोइ पाना नाइथी",
        "morelinkstoimage": "यै फाइलको [[Special:WhatLinksHere/$1|थप लिंकहरू]] हेर ।",
        "tooltip-n-mainpage-description": "खास पन्नामी झाऽ",
        "tooltip-n-portal": "आयोजनाका बारेमी , तम कि अद्द सकन्छौ , समान काखाइ  भेटौन्या",
        "tooltip-n-currentevents": "हालैका घटनाको बारेमी पृष्ठभूमि जानकारी पत्ता लागाइदिय",
-       "tooltip-n-recentchanges": "विà¤\95िमà¥\80 à¤¹à¤¾à¤²à¥\88 à¤\85रियाà¤\95ा à¤«à¥\87रबदलà¥\88 à¤¶à¥\81à¤\9aि ।",
+       "tooltip-n-recentchanges": "विà¤\95िमà¥\80 à¤¹à¤¾à¤²à¥\88 à¤\85रियाà¤\95ा à¤«à¥\87रबदलà¥\88 à¤¸à¥\82à¤\9aà¥\80 ।",
        "tooltip-n-randompage": "क्रमरहित पन्ना खोलऽ",
        "tooltip-n-help": "खोज्जु पड्ड्या ठौर ।",
        "tooltip-t-whatlinkshere": "सप्पै विकि पन्नाअनै शुचि जो याँखाइ जोणीजान",
index 582f5f7..a003a10 100644 (file)
        "readonlywarning": "<strong>Warning: The database has been locked for maintenance, so you will not be able to save your edits right now.</strong>\nYou may wish to copy and paste your text into a text file and save it for later.\n\nThe system administrator who locked it offered this explanation: $1",
        "protectedpagewarning": "<strong>Warning: This page has been protected so that only users with administrator privileges can edit it.</strong>\nThe latest log entry is provided below for reference:",
        "semiprotectedpagewarning": "<strong>Note:</strong> This page has been protected so that only registered users can edit it.\nThe latest log entry is provided below for reference:",
-       "cascadeprotectedwarning": "<strong>Warning:</strong> This page has been protected so that only users with administrator privileges can edit it because it is transcluded in the following cascade-protected {{PLURAL:$1|page|pages}}:",
+       "cascadeprotectedwarning": "<strong>Warning:</strong> This page has been protected so that only users with [[Special:ListGroupRights|specific rights]] can edit it because it is transcluded in the following cascade-protected {{PLURAL:$1|page|pages}}:",
        "titleprotectedwarning": "<strong>Warning: This page has been protected so that [[Special:ListGroupRights|specific rights]] are needed to create it.</strong>\nThe latest log entry is provided below for reference:",
        "templatesused": "{{PLURAL:$1|Template|Templates}} used on this page:",
        "templatesusedpreview": "{{PLURAL:$1|Template|Templates}} used in this preview:",
index 32cb092..4754332 100644 (file)
        "right-editsemiprotected": "Redakti paĝojn protektitajn kiel \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Redakti paĝan enhavmodelon",
        "right-editinterface": "Redakti la uzantointerfacon",
-       "right-editusercssjs": "Redaktu CSS- kaj JS-dosierojn de aliaj uzantoj",
        "right-editusercss": "Redaktu CSS-dosierojn de aliaj uzantoj",
        "right-edituserjs": "Redaktu JS-dosierojn de aliaj uzantoj",
        "right-editmyusercss": "Redakti viajn proprajn CSS-dosierojn",
index 3cecd14..f7a9fb8 100644 (file)
        "right-editsemiprotected": "Editar páginas protegidas como «{{int:protect-level-autoconfirmed}}»",
        "right-editcontentmodel": "Editar el modelo de contenido de una página",
        "right-editinterface": "Editar la interfaz de usuario",
-       "right-editusercssjs": "Editar las páginas de CSS y JavaScript de otros usuarios",
        "right-editusercss": "Editar las páginas de CSS de otros usuarios",
        "right-edituserjs": "Editar las páginas de JavaScript de otros usuarios",
        "right-editmyusercss": "Editar tus archivos CSS",
        "unblocked-id": "Se ha eliminado el bloqueo $1",
        "unblocked-ip": "Se ha desbloqueado a [[Special:Contributions/$1|$1]].",
        "blocklist": "Usuarios bloqueados",
+       "autoblocklist-submit": "Buscar",
        "ipblocklist": "Usuarios bloqueados",
        "ipblocklist-legend": "Encontrar a un usuario bloqueado",
        "blocklist-userblocks": "Ocultar bloqueos de cuenta",
index bce9bf8..e98e639 100644 (file)
        "right-editprotected": "Babestutako orrialdeak aldatu (babes jauzirik gabe)",
        "right-editsemiprotected": "Aldatu \"{{int:protect-level-autoconfirmed}}\" babesa duten orrialdeak",
        "right-editinterface": "Erabiltzailearen interfazea aldatu",
-       "right-editusercssjs": "Beste lankideen CSS eta JS fitxategiak aldatu",
        "right-editusercss": "Beste lankideen CSS fitxategiak aldatu",
        "right-edituserjs": "Beste lankideen JS fitxategiak aldatu",
        "right-editmyusercss": "Aldatu zure CSS fitxategi propioak",
index 3769c68..7a3e8ac 100644 (file)
        "right-editsemiprotected": "ویرایش صفحه حفاظت‌شده به عنوان \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "ویرایش مدل محتوای یک صفحه",
        "right-editinterface": "ویرایش واسط کاربری",
-       "right-editusercssjs": "ویرایش صفحه‌های CSS و JS دیگر کاربرها",
        "right-editusercss": "ویرایش صفحه‌های CSS دیگر کاربرها",
        "right-edituserjs": "ویرایش صفحه‌های JS دیگر کاربرها",
        "right-editmyusercss": "پرونده‌های سی‌اس‌اس کاربری خود را ویرایش کنید",
index 1f7cde0..ce27543 100644 (file)
        "right-editsemiprotected": "Muokata sivuja, jotka on suojattu tasolle \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Muokata sivun sisältömallia (content model)",
        "right-editinterface": "Muokata käyttöliittymätekstejä",
-       "right-editusercssjs": "Muokata toisten käyttäjien CSS- ja JavaScript-tiedostoja",
        "right-editusercss": "Muokata toisten käyttäjien CSS-tiedostoja",
        "right-edituserjs": "Muokata toisten käyttäjien JavaScript-tiedostoja",
        "right-editmyusercss": "Muokata omia CSS-tiedostoja",
index 1f49bcc..5ef3445 100644 (file)
        "right-editsemiprotected": "Modifier les pages protégées avec « {{int:protect-level-autoconfirmed}} »",
        "right-editcontentmodel": "Modifier le modèle de contenu d’une page",
        "right-editinterface": "Modifier l'interface utilisateur",
-       "right-editusercssjs": "Modifier les fichiers CSS et JavaScript d'autres utilisateurs",
        "right-editusercss": "Modifier les fichiers CSS d'autres utilisateurs",
        "right-edituserjs": "Modifier les fichiers JavaScript d'autres utilisateurs",
        "right-editmyusercss": "Modifier vos propres fichiers CSS utilisateur",
        "unblocked-id": "Le blocage $1 a été enlevé",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] a été débloqué.",
        "blocklist": "Utilisateurs bloqués",
+       "autoblocklist": "Blocages automatiques",
+       "autoblocklist-submit": "Rechercher",
+       "autoblocklist-legend": "Lister les blocages automatiques",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Blocage automatique local|Blocages automatiques locaux}}",
+       "autoblocklist-empty": "La liste des blocages automatiques est vide.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Autre blocage automatique|Autres blocages automatiques}}",
        "ipblocklist": "Utilisateurs bloqués",
        "ipblocklist-legend": "Chercher un utilisateur bloqué",
        "blocklist-userblocks": "Masquer les blocages de comptes",
index 85fee97..43adfac 100644 (file)
        "right-protect": "Befeiligingsnivo's feroarje en beskerme siden bewurkje",
        "right-editprotected": "Befeilige siden bewurkje (sûnder cascading-befeiliging)",
        "right-editinterface": "Brûkersinterface bewurkje",
-       "right-editusercssjs": "De CSS- en JS-triemmen fan oare brûkers bewurkje",
        "right-editusercss": "De CSS-JS-triemmen fan oare brûkers bewurkje",
        "right-edituserjs": "De JS-triemmen fan oare brûkers bewurkje",
        "right-rollback": "Gau de lêste bewurking(s) fan in brûker fan in side tebekdraaie",
index 7894932..9c0808e 100644 (file)
        "right-editsemiprotected": "Editar páxinas protexidas con \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Editar o modelo de contido dunha páxina",
        "right-editinterface": "Editar a interface de usuario",
-       "right-editusercssjs": "Editar os ficheiros CSS e JavaScript doutros usuarios",
        "right-editusercss": "Editar os ficheiros CSS doutros usuarios",
        "right-edituserjs": "Editar os ficheiros JavaScript doutros usuarios",
        "right-editmyusercss": "Editar os ficheiros CSS propios",
index 7983c95..a356550 100644 (file)
        "unprotectthispage": "ubawa dudaha halaman botiye",
        "newpage": "Halaman bohu",
        "talkpage": "Bisalayi halaman boti",
-       "talkpagelinktext": "lo'iya",
+       "talkpagelinktext": "bisala",
        "specialpage": "Halaman uda'a",
        "personaltools": "Pilaakasi lo hihilawo",
        "articlepage": "Bilohi tuango halaman",
        "nstab-template": "Templat",
        "nstab-help": "Halaman tulungi",
        "nstab-category": "Kategori",
-       "mainpage-nstab": "Halaman Bungaliyo",
+       "mainpage-nstab": "Halaman bungaliyo",
        "nosuchaction": "Diya'a huhutu boyito",
        "nosuchactiontext": "Huhutu u hepohile lo URL ja valid.\nYi'o lotalawa lopomaso lo URL, meyalo lodudu'a pranala u ja banari.\nUtiye olo kira-kira tuwotiyo woluwo bug to pilaakasi u hepomake {{SITENAME}}",
        "nosuchspecialpage": "Diya'a halaman istimewa boyito",
        "login": "Tumuwoto log",
        "login-security": "Po'opatata tita yi'o",
        "nav-login-createaccount": "Tumuwoto log / mohutu akun",
-       "userlogin": "Tumuwoto log / mohutu akun",
-       "userloginnocreate": "Tumuwoto log",
        "logout": "Lumuwalo log",
        "userlogout": "Lumuwalo log",
        "notloggedin": "Diipo tilumuwoto log",
        "userlogin-noaccount": "Diipo o akun",
        "userlogin-joinproject": "Motiwayito {{SITENAME}}",
-       "nologin": "Diipo o akun? $1",
-       "nologinlink": "Mohutu akun bohu",
        "createaccount": "Mohutu akun",
-       "gotaccount": "Ma yilohutu akun? $1",
-       "gotaccountlink": "Tumuwoto log",
-       "userlogin-resetlink": "Ilolipata detail habari tumuwotumu?",
        "userlogin-resetpassword-link": "Ilolipata tahe u'unti?",
        "userlogin-helplink2": "Wubodu tumuwoto log",
        "userlogin-loggedin": "Yi'o ma tilumuwoto odelo {{GENDER:$1|$1}}\nPopohunawa formulir formulir to tibawa botiye odelo pengguna uweewo.",
        "createacct-another-email-ph": "Tuwanga alamat tuladu email",
        "createaccountmail": "Popohunawa tahu u'unti ja kakali wawu lawola ode tuladu elektronik u pilohile",
        "createacct-realname": "Tanggula banari (tulawoto)",
-       "createaccountreason": "Alaasani",
        "createacct-reason": "Alaasani",
        "createacct-reason-ph": "Longola Y'io mohutu akun uweewo.",
        "createacct-reason-help": "Tahuli u pilopobilohu to delomo log mohutu akun",
index e6d3e06..aef5bd5 100644 (file)
        "right-editsemiprotected": "Mit «{{protect-level-autoconfirmed}}» gschützti Syten ändere",
        "right-editcontentmodel": "Inhaltsmodäll vo’re Syten ändere",
        "right-editinterface": "Benutzerinterface bearbeite",
-       "right-editusercssjs": "Bearbeite vu CSS- und JS-Dateie vu andere Benutzer",
        "right-editusercss": "Bearbeite vu CSS-Dateie vu andere Benutzer",
        "right-edituserjs": "Bearbeite vu JS-Dateie vu andere Benutzer",
        "right-editmyusercss": "Dyni eigete CSS-Dateien ändere",
index a69343a..5b808ab 100644 (file)
        "readonlywarning": "'''אזהרה: בסיס הנתונים ננעל לצורך תחזוקה. בזמן זה לא ניתן לשמור את הטקסט הערוך.'''\nבאפשרותך להעתיק ולהדביק את הטקסט לתוך קובץ טקסט ולשמור אותו למועד מאוחר יותר.\n\nמנהל המערכת שנעל את בסיס הנתונים סיפק את ההסבר הבא: $1",
        "protectedpagewarning": "'''אזהרה: דף זה מוגן כך שרק מפעילי מערכת יכולים לערוך אותו.'''\nפעולת היומן האחרונה מוצגת להלן:",
        "semiprotectedpagewarning": "'''הערה:''' דף זה מוגן כך שרק משתמשים רשומים יכולים לערוך אותו.\nפעולת היומן האחרונה מוצגת להלן:",
-       "cascadeprotectedwarning": "<strong>×\90×\96×\94ר×\94:</strong> ×\93×£ ×\96×\94 ×\9e×\95×\92×\9f ×\9b×\9a ×©×¨×§ ×\9eפע×\99×\9c×\99 ×\9eער×\9bת יכולים לערוך אותו, כי הוא מוכלל {{PLURAL:$1|בדף הבא, שמופעלת עליו|בדפים הבאים, שמופעלת עליהם}} הגנה מדורגת:",
+       "cascadeprotectedwarning": "<strong>×\90×\96×\94ר×\94:</strong> ×\93×£ ×\96×\94 ×\9e×\95×\92×\9f ×\9b×\9a ×©×¨×§ ×\9eשת×\9eש×\99×\9d ×¢×\9d [[Special:ListGroupRights|×\94רש×\90×\95ת ×\9eס×\95×\99×\9e×\95ת]] יכולים לערוך אותו, כי הוא מוכלל {{PLURAL:$1|בדף הבא, שמופעלת עליו|בדפים הבאים, שמופעלת עליהם}} הגנה מדורגת:",
        "titleprotectedwarning": "'''אזהרה: דף זה מוגן כך שדרושות [[Special:ListGroupRights|הרשאות מסוימות]] כדי ליצור אותו.'''\nפעולת היומן האחרונה מוצגת להלן:",
        "templatesused": "{{PLURAL:$1|תבנית המופיעה|תבניות המופיעות}} בדף זה:",
        "templatesusedpreview": "{{PLURAL:$1|תבנית המופיעה|תבניות המופיעות}} בתצוגה המקדימה הזאת:",
        "right-editsemiprotected": "עריכת דפים המוגנים ברמת ההגנה \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "שינוי מודל התוכן של דפים",
        "right-editinterface": "עריכת ממשק המשתמש",
-       "right-editusercssjs": "עריכת קובצי CSS ו־JavaScript של משתמשים אחרים",
        "right-editusercss": "עריכת קובצי CSS של משתמשים אחרים",
        "right-edituserjs": "עריכת קובצי JavaScript של משתמשים אחרים",
        "right-editmyusercss": "עריכת קובצי CSS של המשתמש עצמו",
        "ipb_expiry_temp": "חסימות הכוללות הסתרת שם משתמש חייבות להיות לזמן בלתי מוגבל.",
        "ipb_hide_invalid": "לא ניתן להעלים את החשבון הזה; {{PLURAL:$1|בוצעה ממנו יותר מעריכה אחת|בוצעו ממנו יותר מ‏‏֫־$1 עריכות}}.",
        "ipb_already_blocked": "המשתמש \"$1\" כבר נחסם.",
-       "ipb-needreblock": "ה{{GENDER:$1|משתמש|משתמשת}} \"$1\" כבר {{GENDER:$1|חסום|חסומה}}. האם ברצונך לשנות את הגדרות החסימה?",
+       "ipb-needreblock": "$1 כבר {{GENDER:$1|חסום|חסומה}}. האם ברצונך לשנות את הגדרות החסימה?",
        "ipb-otherblocks-header": "{{PLURAL:$1|חסימה אחרת|חסימות אחרות}}",
        "unblock-hideuser": "אין באפשרותך לשחרר את החסימה של המשתמש הזה, כיוון ששם המשתמש שלו הוסתר.",
        "ipb_cant_unblock": "שגיאה: חסימה מספר $1 לא נמצאה. ייתכן שהיא כבר שוחררה.",
        "tooltip-pt-mytalk": "דף השיחה שלך",
        "tooltip-pt-anontalk": "דיון על העריכות שנעשו מכתובת ה־IP הזאת",
        "tooltip-pt-preferences": "ההעדפות שלך",
-       "tooltip-pt-watchlist": "רשימת הדפים ש{{GENDER:|אתה עוקב|את עוקבת}} אחרי השינויים בהם",
+       "tooltip-pt-watchlist": "רשימת הדפים {{GENDER:|שאתה עוקב|שאת עוקבת}} אחרי השינויים בהם",
        "tooltip-pt-mycontris": "רשימת העריכות שביצעת",
        "tooltip-pt-anoncontribs": "רשימת העריכות שנעשו מכתובת ה־IP הזאת",
        "tooltip-pt-login": "מומלץ להיכנס לחשבון, אך אין חובה לעשות זאת",
index b734764..9986b24 100644 (file)
        "right-editsemiprotected": "उन पृष्ठों को सम्पादित करें जिनका सुरक्षा स्तर है \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "एक पेज की सामग्री मॉडल को संपादित।",
        "right-editinterface": "सॉफ़्टवेयर इंटरफ़ेस सम्पादित करें",
-       "right-editusercssjs": "अन्य सदस्यों के सी॰एस॰एस और जावास्क्रिप्ट पृष्ठ सम्पादित करें",
        "right-editusercss": "अन्य सदस्यों के सी॰एस॰एस पृष्ठ सम्पादित करें",
        "right-edituserjs": "अन्य सदस्यों के जावास्क्रिप्ट पृष्ठ सम्पादित करें",
        "right-editmyusercss": "अपनी सदस्य स्तर की सी॰एस॰एस फ़ाइलें सम्पादित करें",
index 20d15d5..37b4418 100644 (file)
        "right-editsemiprotected": "Uređivanje stranica zaštićenih kao \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Odredi modela sadržaja stranice",
        "right-editinterface": "Uređivanje suradničkog sučelja",
-       "right-editusercssjs": "Uređivanje CSS i JS stranica drugih suradnika",
        "right-editusercss": "Uređivanje CSS stranica drugih suradnika",
        "right-edituserjs": "Uređivanje JS stranica drugih suradnika",
        "right-editmyusercss": "Uređivanje vlastitih CSS stranica",
index edb8a7c..976ebbf 100644 (file)
@@ -17,6 +17,7 @@
        "tog-hideminor": "Kache tout modifikasyon resan yo ki tou piti",
        "tog-hidepatrolled": "Kache modifikasyon yo ki fèk fèt pou moun ki ap veye yo",
        "tog-newpageshidepatrolled": "Kache paj ki siveye yo nan mitan lis nouvo paj yo",
+       "tog-hidecategorization": "Kache kategori ki nan paj la",
        "tog-extendwatchlist": "Etann lis swivi pou ou kapab wè tout chanjman yo, pa sèlman sa ki fèk fèt yo",
        "tog-usenewrc": "Sanble modifikasyon pou chak paj nan chanjman resan ak paj an vèy",
        "tog-numberheadings": "Nimewote otomatikman tit yo",
@@ -27,6 +28,7 @@
        "tog-watchdefault": "Ajoute paj mwen chanje yo nan lis swivi mwen",
        "tog-watchmoves": "Ajoute paj mwen deplase yo nan lis swivi mwen",
        "tog-watchdeletion": "Ajoute paj mwen efase yo nan lis swivi mwen",
+       "tog-watchuploads": "Ajoute paj nouvo nan favori m'",
        "tog-watchrollback": "Ajoute paj kote mwen ranvèse chanjman yo nan lis swivi mwen",
        "tog-minordefault": "Make tout modifikasyon kòm «&nbsp;tou piti&nbsp;» pa defo",
        "tog-previewontop": "Montre kout je anvan zòn modifikasyon",
@@ -36,7 +38,7 @@
        "tog-enotifminoredits": "Voye yon imèl ban mwen pou ti chanjman paj ak fichye",
        "tog-enotifrevealaddr": "Montre adrès imèl mwen nan kominikasyon notifikasyon yo",
        "tog-shownumberswatching": "Montre kantite itlizatè k’ap swiv",
-       "tog-oldsig": "Siyati ki la deja a:",
+       "tog-oldsig": "Siyati ki egziste deja ou",
        "tog-fancysig": "Konsidere siyati sa tankou yon wikitèks (san lyen ki ta otomatik)",
        "tog-uselivepreview": "Sèvi ak vizyònman dirèk",
        "tog-forceeditsummary": "Notifye m lè m ap antre yon somè modifikasyon vid",
@@ -67,8 +69,8 @@
        "thursday": "jedi",
        "friday": "vandredi",
        "saturday": "samdi",
-       "sun": "dim",
-       "mon": "len",
+       "sun": "dimanch",
+       "mon": "lendi",
        "tue": "mad",
        "wed": "mèk",
        "thu": "jed",
        "searcharticle": "Ale",
        "history": "Istorik paj la",
        "history_short": "Istorik",
+       "history_small": "Istwa",
        "updatedmarker": "Aktyalize depi dènyè visit mwen",
        "printableversion": "Vèsyon ou kapab enprime",
        "permalink": "Lyen pou tout tan",
        "nstab-template": "Modèl",
        "nstab-help": "Paj èd",
        "nstab-category": "Kategori",
+       "mainpage-nstab": "paj prensipal",
        "nosuchaction": "Pa gen bagay konsa",
        "nosuchactiontext": "Wiki a pa rekonèt aksyon ki espesifye pa URL la.\nOu gendwa mal ekri URL la oubyen ou te swiv yon movè lyen.\nSa kapab di tou gen yon erè nan lojisyèl ki itilize nan sit {{SITENAME}}.",
        "nosuchspecialpage": "Pa gen paj especial konsa",
        "yourname": "Non itilizatè ou an :",
        "userlogin-yourname": "Non itilizatè",
        "userlogin-yourname-ph": "Rantre non itilizatè w",
+       "createacct-another-username-ph": "Antre non itilizatè a",
        "yourpassword": "Mopas ou an :",
        "userlogin-yourpassword": "Modpas",
        "userlogin-yourpassword-ph": "Rantre modpas ou",
        "createacct-yourpasswordagain-ph": "Rantre modpas la ankò",
        "userlogin-remembermypassword": "Pa dekonekte m",
        "userlogin-signwithsecure": "Sèvi ak yon koneksyon sekirize",
+       "cannotloginnow-title": "Ou pa ka siyen nan kounye a",
        "yourdomainname": "Domèn ou an",
        "password-change-forbidden": "Ou pa ka chanje modpas sou wiki sa a.",
        "externaldberror": "Li sanble ke yon erè pwodui ak bazdone a pou idantifikasyon ki pa nan sistèm an, oubyen ou pa otorize pou mete a jou kont ou genyen nan lòt sistèm yo.",
        "login": "Konekte ou",
        "nav-login-createaccount": "Kreye yon kont oubyen konekte ou",
-       "userlogin": "Kreye yon kont oubyen konekte ou",
-       "userloginnocreate": "Konekte ou",
        "logout": "Dekonekte ou",
        "userlogout": "Dekoneksyon",
        "notloggedin": "Ou pa konekte",
        "userlogin-noaccount": "Ou pa gen yon kont?",
        "userlogin-joinproject": "Enskri nan {{SITENAME}}",
-       "nologin": "Ou pa genyen yon kont ? '''$1'''.",
-       "nologinlink": "Kreye yon kont",
        "createaccount": "Kreye yon kont",
-       "gotaccount": "Ou deja genyen yon kont ? '''$1'''.",
-       "gotaccountlink": "Idantifye ou",
        "userlogin-resetpassword-link": "Ou bliye modpas ou?",
        "userlogin-helplink2": "Èd pou konekte",
+       "createacct-emailrequired": "adrès imel ou",
        "createacct-emailoptional": "Adrès imèl (fakiltatif)",
        "createacct-email-ph": "Rantre adrès imèl ou",
-       "createaccountmail": "pa imèl",
-       "createaccountreason": "Rezon:",
+       "createacct-another-email-ph": "Antre nan adrès imel ou",
+       "createaccountmail": "Sèvi ak yon modpas pou yon ti tan ak o aza lè sa a, voye li nan adrès imel la espesifye",
        "createacct-reason": "Rezon",
        "createacct-reason-ph": "Poukisa w ap ouvri yon lòt kont?",
        "createacct-submit": "Ouvri kont ou",
        "htmlform-reset": "Revoke chanjman yo",
        "revdelete-restricted": "aplike restriksyon sa yo pou administratè yo",
        "logentry-newusers-create": "Kont itilizatè $1 a kreye",
-       "revdelete-summary": "somè pou modifikasyon",
        "searchsuggest-search": "Chèche"
 }
index 2fbb756..510892c 100644 (file)
        "right-editsemiprotected": "Modificar paginas protegite como \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Modificar le modello de contento de un pagina",
        "right-editinterface": "Modificar le interfacie de usator",
-       "right-editusercssjs": "Modificar le files CSS e JS de altere usatores",
        "right-editusercss": "Modificar le files CSS de altere usatores",
        "right-edituserjs": "Modificar le files JS de altere usatores",
        "right-editmyusercss": "Modificar le proprie files CSS de usator",
index 9de536f..9078e93 100644 (file)
        "right-editsemiprotected": "Sunting halaman yang dilindungi sebagai \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Edit model konten halaman",
        "right-editinterface": "Menyunting antarmuka pengguna",
-       "right-editusercssjs": "Menyunting arsip CSS dan JS pengguna lain",
        "right-editusercss": "Menyunting berkas CSS pengguna lain",
        "right-edituserjs": "Menyunting berkas JS pengguna lain",
        "right-editmyusercss": "Sunting berkas CSS pengguna Anda",
index 9104972..4ec9a1a 100644 (file)
        "changepassword-success": "Nasukatanen ti kontraseniasmo!",
        "changepassword-throttled": "Nakaaramidka kadagiti adu unay a nabiit a panangipadas ti panagserrek.\nPangngaasi nga aguray iti $1 sakbay a padasen manen.",
        "botpasswords": "Dagiti kontrasenias ti bot",
-       "botpasswords-summary": "<em>Dagiti kontrasenias ti bot</em> ket mangpalubos a maserrekan ti pakabilangan ti agar-aramat babaen ti API a saan nga agusar kadagiti nangruna a kredensial ti pakabilangan. Dagiti magun-od a karbengan ti agar-aramat no nakastrek iti kontrasenias ti bot ket mabalin a nagawidan.\n\nNo saanmo nga ammo no apay a kayatmo nga aramiden daytoy, mabalin a saanmo koma nga aramiden daytoy. Awan koma ti mangdamag kaniam iti agpataud iti maysa kadagitoy ken itedmo kaniada.",
+       "botpasswords-summary": "<em>Dagiti kontrasenias ti bot</em> ket mangipalubos a maserrekan ti pakabilangan ti agar-aramat babaen ti API a saan nga agusar kadagiti nangruna a kredensial ti pakabilangan. Dagiti magun-od a karbengan ti agar-aramat no nakastrek iti kontrasenias ti bot ket mabalin a nagawidan.\n\nNo saanmo nga ammo no apay a kayatmo nga aramiden daytoy, mabalin a saanmo koma nga aramiden daytoy. Awan koma ti mangdamag kaniam iti agpataud iti maysa kadagitoy ken itedmo kaniada.",
        "botpasswords-disabled": "Nabaldado dagiti kontrasenias ti bot.",
        "botpasswords-no-central-id": "Ti agusar kadagiti kontrasenias ti bot, nasken a nakastrekka iti sentralisado a pakabilangan.",
        "botpasswords-existing": "Dagiti adda a kontrasenias ti bot",
        "changeemail-throttled": "Adu unay ti panagpadasmo a sumrek.\nPangngaasi nga aguray ti $1 sakbay a padasen manen.",
        "changeemail-nochange": "Pangngaasi nga agikabil iti sabali a baro nga adres ti esurat.",
        "resettokens": "Isaad manen dagiti tandaan",
-       "resettokens-text": "Mabalinmo nga isaad manen dagiti tandaan a mangpalubos ti panagserrek ti naisangayan a pribado datos a mainaig ti pakabilangam ditoy.\n\nAramidem daytoy no aksidente nga inbingaymo dagitoy iti sabali wenno ti pakabilangam ket nakomprimiso.",
+       "resettokens-text": "Mabalinmo nga isaad manen dagiti tandaan a mangipalubos ti panagserrek iti naisangayan a pribado datos a mainaig iti pakabilangam ditoy.\n\nAramidem daytoy no aksidente nga inbingaymo dagitoy iti sabali wenno ti pakabilangam ket nakomprimiso.",
        "resettokens-no-tokens": "Awan dagiti maisaad manen a tandaan.",
        "resettokens-tokens": "Dagiti tandaan:",
        "resettokens-token-label": "$1 (agdama a pateg: $2)",
        "previewnote": "<strong>Laglagipem a daytoy ket panagipadas laeng.</strong>\nDagiti sinukatam ket saan pay a naidulin!",
        "continue-editing": "Mapan idiay pagurnosan a lugar",
        "previewconflict": "Daytoy a panagpadas ket mangipakita ti teksto iti lugar ti akinngato a pangurnosan ti teksto a kasla agparang no piliem nga idulin.",
-       "session_fail_preview": "Pasensia! Saanmi a maproseso ti panagurnosmo gapu ta naawanan ti sesion ti datos.\n\nMabalin a nakaruarka. <strong>Pangngaasi a pasingkedan a nakastrekka pay laeng ken padasen manen</strong>.\n \t\nNo saan pay a mabalin, padasen ti [[Special:UserLogout|rummuar]] ken sumrek manen, ken kitaen no ti pagbasabasam ket mangpalubos kadagiti galieta manipud iti daytoy a sitio.",
-       "session_fail_preview_html": "Pasensia! Saanmi a maproseso ti panagurnosmo gapu ta naawanan ti sesion ti datos.\n\n<em>Gapu ta ti {{SITENAME}} ket addaan iti naata a HTML a nakapabaelan, ti panagpadas ket nailemmeng a kas pagan-annadan kadagiti panagraut iti dakes a JavaScript.</em>\n\n<strong>No daytoy ket pudno a panagurnos, pangngaasi a padasem manen.</strong>\nNo saan pay a mabalin, padasen ti [[Special:UserLogout|rummuar]] ken sumrek manen, ken kitaen no ti pagbasabasam ket mangpalubos kadagiti galieta manipud iti daytoy a sitio.",
+       "session_fail_preview": "Pasensia! Saanmi a maproseso ti panagurnosmo gapu ta naawanan ti sesion ti datos.\n\nMabalin a nakaruarka. <strong>Pangngaasi a pasingkedan a nakastrekka pay laeng ken padasen manen</strong>.\n \t\nNo saan pay a mabalin, padasen ti [[Special:UserLogout|rummuar]] ken sumrek manen, ken kitaen no ti pagbasabasam ket mangipalubos kadagiti galieta manipud iti daytoy a sitio.",
+       "session_fail_preview_html": "Pasensia! Saanmi a maproseso ti panagurnosmo gapu ta naawanan ti sesion ti datos.\n\n<em>Gapu ta ti {{SITENAME}} ket addaan iti naata a HTML a nakapabaelan, ti panagpadas ket nailemmeng a kas pagan-annadan kadagiti panagraut iti dakes a JavaScript.</em>\n\n<strong>No daytoy ket pudno a panagurnos, pangngaasi a padasem manen.</strong>\nNo saan pay a mabalin, padasen ti [[Special:UserLogout|rummuar]] ken sumrek manen, ken kitaen no ti pagbasabasam ket mangipalubos kadagiti galieta manipud iti daytoy a sitio.",
        "token_suffix_mismatch": "<strong>Ti panagurnosmo ket saan a naawat ngamin ket ti klientem ket dinadaelna dagiti karakter ti tuldek iti tandaan ti panagurnos.</strong>\nTi panagurnos ket saan a naawat tapno mapawilan ti pannakadadael ti teksto ti panid.\nSagpaminsan a mapasamak daytoy no agus-usarka ti saan a nasayaat a naibatay ti web ti di ammo a pannakbagi a serbisio.",
        "edit_form_incomplete": "<strong>Adda dagiti paset ti pagurnosan a porma a saan a nakadanon dita server; mamindua a kitaen dagiti panagurnosmo ket sibubukel ken padasen manen.</strong>",
        "editing": "Ur-urnosen ti $1",
        "right-editsemiprotected": "Agurnos kadagiti panid a nasalakniban a kas \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Urnosen ti modelo ti linaon iti panid",
        "right-editinterface": "Agurnos iti interface ti agar-aramat",
-       "right-editusercssjs": "Agurnos kadagiti papales ti CSS ken JavaScript dagiti sabali nga agar-aramat",
        "right-editusercss": "Agurnos kadagiti papeles ti CSS dagiti sabali nga agar-aramat",
        "right-edituserjs": "Agurnos kadagiti papales ti JavaScript dagiti sabali nga agar-aramat",
        "right-editmyusercss": "Agurnos kadagiti bukodmo a papeles ti CSS ti agar-aramat",
        "rcfilters-invalid-filter": "Imbalido a sagat",
        "rcfilters-empty-filter": "Awan dagiti aktibo a sagat. Naipakita amin dagiti kontribusion.",
        "rcfilters-filterlist-title": "Dagiti sagat",
+       "rcfilters-filterlist-whatsthis": "Ania daytoy?",
        "rcfilters-highlightmenu-title": "Agpili iti maris",
        "rcfilters-filterlist-noresults": "Awan dagiti nabirukan a sagat",
        "rcfilters-filter-registered-label": "Nakarehistro",
        "rcfilters-filter-registered-description": "Dagiti nakastrek nga editor.",
        "rcfilters-filter-unregistered-label": "Saan a nakarehistro",
        "rcfilters-filter-unregistered-description": "Dagiti editor a saan a nakastrek.",
+       "rcfilters-filter-editsbyself-label": "Dagiti bukodmo nga inurnos",
+       "rcfilters-filter-editsbyself-description": "Dagiti inurnosmo.",
+       "rcfilters-filter-editsbyother-label": "Dagiti inurnos ti sabali",
+       "rcfilters-filter-editsbyother-description": "Dagiti inurnos a pinartuat babaen dagiti sabali nga agar-aramat (saan a sika).",
        "rcfilters-filter-user-experience-level-newcomer-label": "Dagiti agdadamo",
        "rcfilters-filter-user-experience-level-newcomer-description": "Basbassit ngem 10 nga inur-urnos ken 4 nga aldaw iti aktibidad.",
        "rcfilters-filter-user-experience-level-learner-label": "Dagiti agad-adal",
        "rcfilters-filter-patrolled-description": "Dagiti inurnos a namarkaan a kas napatruliaan.",
        "rcfilters-filter-unpatrolled-label": "Di napatruliaan",
        "rcfilters-filter-unpatrolled-description": "Dagiti inurnos a saan a namarkaan a kas napatruliaan.",
+       "rcfilters-filter-minor-label": "Dagiti bassit a panagurnos",
+       "rcfilters-filter-minor-description": "Dagiti panagurnos a minarkaan ti mannurat a kas bassit.",
+       "rcfilters-filter-major-label": "Dagiti saan a bassit a panagurnos",
+       "rcfilters-filter-major-description": "Dagiti panagurnos a saan a namarkaan a kas bassit.",
        "rcfilters-filtergroup-changetype": "Kita ti panagbaliw",
+       "rcfilters-filter-pageedits-label": "Dagiti panagurnos ti panid",
+       "rcfilters-filter-pageedits-description": "Dagiti panagurnos iti linaon ti wiki, tungtungan, dagiti deskripsion ti kategoria....",
+       "rcfilters-filter-newpages-label": "Dagiti panagpartuat ti panid",
+       "rcfilters-filter-newpages-description": "Dagiti panagurnos a nakaaramid kadagiti baro a panid.",
+       "rcfilters-filter-categorization-label": "Dagiti panagbaliw ti kategoria",
+       "rcfilters-filter-categorization-description": "Dagiti rekord ti pampanid a mainaynayon wenno maik-ikkat manipud kadagiti kategoria.",
+       "rcfilters-filter-logactions-label": "Dagiti aksion a nailista",
+       "rcfilters-filter-logactions-description": "Dagiti aksion nga administratibo, dagiti panagpartuat iti pakabilangan, dagiti panagikkat iti panid, dagiti panangikarga....",
        "rcnotefrom": "Dita baba ket {{PLURAL:$5|ti sinukatan|dagiti sinukatan}} manipud idi <strong>$3, $4</strong> (aginggana iti <strong>$1</strong> a naipakita).",
        "rclistfrom": "Ipakita dagiti kabarbaro a sinukatan a mangrugi manipud idi $2, $3",
        "rcshowhideminor": "$1 dagiti bassit a panagurnos",
        "mostinterwikis": "Dagiti panid a kaaduan kadagiti interwiki",
        "mostrevisions": "Dagiti panid a kaaduan kadagiti rebision",
        "prefixindex": "Amin a pampanid nga addaan iti pasakbay",
-       "prefixindex-namespace": "Amin a pampanid nga addaan iti pasaruno (nagan ti espasio ti $1)",
+       "prefixindex-namespace": "Amin a pampanid nga agraman iti pasakbay (nagan ti espasio ti $1)",
        "prefixindex-submit": "Ipakita",
        "prefixindex-strip": "Ikkaten ti pasakbay iti listaan",
        "shortpages": "Dagiti ababa a panid",
        "listgrouprights-removegroup-self-all": "Ikkatem amin dagiti grupo manipud iti bukod a pakabilangan",
        "listgrouprights-namespaceprotection-header": "Dagiti panangigawid ti nagan ti espasio",
        "listgrouprights-namespaceprotection-namespace": "Nagan ti espasio",
-       "listgrouprights-namespaceprotection-restrictedto": "Karbengan wenno karkarbengan a mangpalubos nga agurnos ti agar-aramat",
+       "listgrouprights-namespaceprotection-restrictedto": "Karbengan wenno karkarbengan a mangipalubos nga agurnos ti agar-aramat",
        "listgrants": "Dagiti sagut",
        "listgrants-summary": "Ti sumagand ket listaan dagiti sagut nga agraman kadagiti mainaig a panagserrek kadagiti karbengan ti agar-aramat. Dagiti agar-aramat ket mabalinda ti mangipalubos kadagiti aplikasion a mausarda iti bukodda a pakabilangan, ngem addaan iti limitado a pammalubos a naibatay kadagiti sagut nga inted ti agar-aramat iti aplikasion. Nupay kasta ti maysa nga aplikasion nga agtigtignay para iti agar-aramat ket saan a pudno a makausar kadagiti karbengan nga awanan iti agar-aramat.\nMabalin nga adda iti [[{{MediaWiki:Listgrouprights-helppage}}|maipatinayon a pakaammo]] a maipanggep kadagiti indibidual a karbengan.",
        "listgrants-grant": "Sagut",
        "whatlinkshere-filters": "Dagiti sagat",
        "whatlinkshere-submit": "Inkan",
        "autoblockid": "Auto a panagserra #$1",
-       "block": "Seraan ti agar-aramat",
+       "block": "Serraan ti agar-aramat",
        "unblock": "Ikkaten ti serra ti agar-aramat",
        "blockip": "Serraan ti {{GENDER:$1|agar-aramat}}",
        "blockip-legend": "Serraan ti agar-aramat",
        "unblocked-id": "Naikkaten ti serra ti $1.",
        "unblocked-ip": "Naikkaten ti serra ni [[Special:Contributions/$1|$1]] .",
        "blocklist": "Dagiti naserraan nga agar-aramat",
+       "autoblocklist-submit": "Agbiruk",
        "ipblocklist": "Dagiti naserraan nga agar-aramat",
        "ipblocklist-legend": "Agbiruk ti naserraan nga agar-aramat",
        "blocklist-userblocks": "Ilemmeng dagiti serra ti pakabilangan",
        "allmessages-filter-unmodified": "Saan a nabaliwan",
        "allmessages-filter-all": "Amin",
        "allmessages-filter-modified": "Nabaliwan",
-       "allmessages-prefix": "Sagaten babaen ti pasaruno:",
+       "allmessages-prefix": "Sagaten babaen ti pasakbay:",
        "allmessages-language": "Pagsasao:",
        "allmessages-filter-submit": "Inkan",
        "allmessages-filter-translate": "Ipatarus",
        "import-error-bad-location": "Ti rebision ti $2 nga agus-usar ti modelo a linaon ti $3 ket saan a maipenpen iti \"$1\" iti daytoy a wiki, gapu ta dayta a modelo ket saan a nasuportaran iti dayta a panid.",
        "import-options-wrong": "Saan a husto {{PLURAL:$2|a pagpilian|a pagpilpilian}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Ti naited a ramut ti panid ket imbalido a titulo.",
-       "import-rootpage-nosubpage": "Ti nagan ti espasio ti \"$1\" iti ramut ti panid ket saan a mangpalubos kadagiti subpanid.",
+       "import-rootpage-nosubpage": "Ti nagan ti espasio ti \"$1\" iti ramut ti panid ket saan a mangipalubos kadagiti subpanid.",
        "importlogpage": "Listaan ti panagala",
        "importlogpagetext": "Dagiti administratibo a panagala kadagiti panid nga addaan iti pakasaritaan ti panagurnos manipud kadagiti sabali a wiki.",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|a rebision|kadagiti rebision}} ti naala",
        "tooltip-recreate": "Partuaten manen ti panid urayno dati a naikkat.",
        "tooltip-upload": "Irugi ti panagikarga",
        "tooltip-rollback": "\"Baliktaden\"  isubli ti inurnos (dagiti inurnos) iti daytoy a panid iti naudi a kontributor iti maysa a pindut",
-       "tooltip-undo": "\"Ibabawi\" ipasubli daytoy nga urnos ken lukatanna ti porma ti pagurnosan iti panagpadas a moda. Mangpalubos daytoy ti agikabil ti rason iti pakabuklan.",
+       "tooltip-undo": "\"Ibabawi\" isubli daytoy nga urnos ken lukatanna ti porma ti pagurnosan iti moda ti panagpadas. Mangipalubos daytoy ti agikabil ti rason iti pakabuklan.",
        "tooltip-preferences-save": "Idulin dagiti kakaykayatam",
        "tooltip-summary": "Agikabil ti bassit a pakabuklan",
        "anonymous": "Di ammo {{PLURAL:$1|nga agar-aramat|kadagiti agar-aramat}} iti {{SITENAME}}",
index 128586b..03ad579 100644 (file)
        "right-editsemiprotected": "Modifica pagine protette con \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Modifica il modello di contenuto di una pagina",
        "right-editinterface": "Modifica l'interfaccia utente",
-       "right-editusercssjs": "Modifica i file CSS e JS di altri utenti",
        "right-editusercss": "Modifica i file CSS di altri utenti",
        "right-edituserjs": "Modifica i file JS di altri utenti",
        "right-editmyusercss": "Modifica il file CSS del proprio utente",
        "unblocked-id": "Il blocco $1 è stato rimosso",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] è stato sbloccato.",
        "blocklist": "Utenti bloccati",
+       "autoblocklist": "Autoblocchi",
+       "autoblocklist-submit": "Ricerca",
+       "autoblocklist-legend": "Elenca autoblocchi",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Autoblocco locale|Autoblocchi locali}}",
+       "autoblocklist-empty": "L'elenco dei autoblocchi è vuoto.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Altro autoblocco|Altri autoblocchi}}",
        "ipblocklist": "Utenti bloccati",
        "ipblocklist-legend": "Cerca un utente bloccato",
        "blocklist-userblocks": "Nascondi i blocchi degli utenti registrati",
index 1e8ee00..876e2dc 100644 (file)
        "right-editsemiprotected": "「{{int:protect-level-autoconfirmed}}」の保護を設定されたページを編集",
        "right-editcontentmodel": "ページのコンテンツモデルを編集",
        "right-editinterface": "ユーザーインターフェースを編集",
-       "right-editusercssjs": "他の利用者のCSSファイル/JavaScriptファイルを編集",
        "right-editusercss": "他の利用者のCSSファイルを編集",
        "right-edituserjs": "他の利用者のJavaScriptファイルを編集",
        "right-editmyusercss": "自身のCSSファイルを編集",
index be38848..beaa517 100644 (file)
        "right-editprotected": "Owah kaca-kaca sing direksa (tanpa pangreksan runtun)",
        "right-editsemiprotected": "Owah kaca-kaca sing direksa dadi \"{{int:protect-level-autoconfirmed}}\"",
        "right-editinterface": "Besut antarmuka panganggo",
-       "right-editusercssjs": "Besut barkas-barkas CSS lan JavaScript panganggo liya",
        "right-editusercss": "Besut barkas-barkas CSS panganggo liya",
        "right-edituserjs": "Besut barkas-barkas JavaScript panganggo liya",
        "right-editmyusercss": "Owahi berkas CSS panganggo sampeyan",
index 97b3e87..904c5b3 100644 (file)
        "right-editsemiprotected": "გვერდების რედაქტირება რომლებიც დაცულია როგორც „{{int:protect-level-autoconfirmed}}“",
        "right-editcontentmodel": "გვერდის კონტენტური მოდელის რედაქტირება",
        "right-editinterface": "მომხმარებლის ინტერფეისის შეცვლა",
-       "right-editusercssjs": "სხვა მომხმარებლების CSS- и JS- ფაილების შესწორება",
        "right-editusercss": "სხვა მომხმარებლების CSS- ფაილების შესწორება",
        "right-edituserjs": "სხვა მომხმარებლების JS- ფაილების შესწორება",
        "right-editmyusercss": "თქვენი საკუთარი CSS-ფაილების რედაქტირება",
index 8d1450a..35ec6d9 100644 (file)
        "right-editsemiprotected": "\"{{int:protect-level-autoconfirmed}}\"로 보호된 문서 편집",
        "right-editcontentmodel": "문서의 콘텐츠 모델을 편집",
        "right-editinterface": "사용자 인터페이스를 편집",
-       "right-editusercssjs": "다른 사용자의 CSS와 자바스크립트 문서를 편집",
        "right-editusercss": "다른 사용자의 CSS 문서를 편집",
        "right-edituserjs": "다른 사용자의 자바스크립트 문서를 편집",
        "right-editmyusercss": "자신의 사용자 CSS 파일 편집하기",
        "unblocked-id": "$1 차단이 해제되었습니다.",
        "unblocked-ip": "[[Special:Contributions/$1|$1]]님이 차단 해제되었습니다.",
        "blocklist": "차단된 사용자 목록",
+       "autoblocklist": "자동차단",
+       "autoblocklist-submit": "검색",
+       "autoblocklist-legend": "자동차단 목록",
+       "autoblocklist-localblocks": "로컬 자동 차단 {{PLURAL:$1|기록|기록들}}",
+       "autoblocklist-empty": "자동차단 목록이 비어 있습니다.",
+       "autoblocklist-otherblocks": "다른 자동 차단 {{PLURAL:$1|기록|기록들}}",
        "ipblocklist": "차단된 사용자",
        "ipblocklist-legend": "차단된 사용자 찾기",
        "blocklist-userblocks": "계정에 대한 차단 숨기기",
        "logentry-delete-delete_redir": "$1님이 덮어쓰기를 통해 $3 문서를 {{GENDER:$2|삭제했습니다}}",
        "logentry-delete-restore": "$1님이 $3 문서를 {{GENDER:$2|되살렸습니다}} ($4)",
        "logentry-delete-restore-nocount": "$1님이 $3 문서를 {{GENDER:$2|되살렸습니다}}",
-       "restore-count-revisions": "{{PLURAL:$1|1개의 판|$1개의 판}}",
-       "restore-count-files": "{{PLURAL:$1|1개의 파일|$1개의 파일}}",
+       "restore-count-revisions": "{{PLURAL:$1|판 1개|판 $1개}}",
+       "restore-count-files": "{{PLURAL:$1|파일 1개|파일 $1개}}",
        "logentry-delete-event": "$1님이 $3의 {{PLURAL:$1|기록 $5개}}에 대해 보이기 설정을 {{GENDER:$2|바꾸었습니다}}: $4",
        "logentry-delete-revision": "$1님이 $3 문서의 {{PLURAL:$5|$5개 편집}}의 설정을 {{GENDER:$2|바꾸었습니다}}: $4",
        "logentry-delete-event-legacy": "$1님이 $3 문서 기록의 보이기 설정을 {{GENDER:$2|바꾸었습니다}}",
        "pageid": "페이지 ID $1",
        "gotointerwiki": "{{SITENAME}}을(를) 떠납니다",
        "gotointerwiki-invalid": "지정된 제목이 올바르지 않습니다.",
-       "gotointerwiki-external": "ë³\84ê°\9cì\9d\98 ì\9b¹ì\82¬ì\9d´í\8a¸ì\9d¸ [[$2]]ì\9d\98 ë°©ë¬¸ì\9d\84 ì\9c\84í\95´ {{SITENAME}}ì\9d\84(를) ë\96 ë\82\98려고 í\95©ë\8b\88ë\8b¤.\n\n[$1 $1(ì\9c¼)ë¡\9c ê³\84ì\86\8d ì§\84í\96\89í\95\98려면 ì\97¬ê¸°ë¥¼ í\81´ë¦­í\95\98ì\8b­ì\8b\9cì\98¤].",
+       "gotointerwiki-external": "ë\8b¤ë¥¸ ì\9b¹ì\82¬ì\9d´í\8a¸ [[$2]]ì\9d\84(를) ë°©ë¬¸í\95\98기 ì\9c\84í\95´ {{SITENAME}}ì\9d\84(를) ë\96 ë\82\98려고 í\95©ë\8b\88ë\8b¤.\n\n[$1 $1(ì\9c¼)ë¡\9c ê³\84ì\86\8d ì§\84í\96\89í\95\98려면 ì\97¬ê¸°ë¥¼ ë\88\8cë\9f¬ì£¼ì\84¸ì\9a\94].",
        "undelete-cantedit": "이 문서를 편집할 권한이 없으므로 이 문서를 복구할 수 없습니다.",
        "undelete-cantcreate": "이 이름으로 된 문서가 없고 이 문서를 만들 권한이 없으므로 이 문서를 복구할 수 없습니다."
 }
index 266b25b..8f318fc 100644 (file)
        "right-editsemiprotected": "Säiten déi als  \"{{int:protect-level-autoconfirmed}}\" gespaart sinn änneren",
        "right-editcontentmodel": "De Modell vum Inhalt vun enger Säit änneren",
        "right-editinterface": "De Benotzerinterface änneren",
-       "right-editusercssjs": "Anere Benotzer hir CSS a JS Fichieren änneren",
        "right-editusercss": "Anere Benotzer hir CSS Fichieren änneren",
        "right-edituserjs": "Anere Benotzer hir JavaScript Fichieren änneren",
        "right-editmyusercss": "Är eegen CSS-Fichieren änneren",
        "unblocked-id": "D'Spär $1 gouf opgehuewen",
        "unblocked-ip": "D'Spär vum [[Special:Contributions/$1|$1]] gouf opgehuewen.",
        "blocklist": "Gespaart Benotzer",
+       "autoblocklist": "Automatesch Spären",
+       "autoblocklist-submit": "Sichen",
+       "autoblocklist-legend": "Automatesche Spären opzielen",
+       "autoblocklist-empty": "D'Lëscht vun den automatesche Spären ass eidel.",
        "ipblocklist": "Gespaart Benotzer",
        "ipblocklist-legend": "No engem gespaarte Benotzer sichen",
        "blocklist-userblocks": "Benotzerspäre verstoppen",
index 08bff71..54f0e61 100644 (file)
        "right-editsemiprotected": "Taisyti puslapius, apsaugotus kaip \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Redaguoti puslapio turinio modelį",
        "right-editinterface": "Keisti naudotojo aplinką",
-       "right-editusercssjs": "Redaguoti kitų naudotojų CSS ir JS failus",
        "right-editusercss": "Redaguoti kitų naudotojų CSS failus",
        "right-edituserjs": "Redaguoti kitų naudotojų JS failus",
        "right-editmyusercss": "Redaguoti savo vartotojo CSS failus",
        "modifiedarticleprotection": "pakeistas „[[$1]]“ apsaugos lygis",
        "unprotectedarticle": "atrakino „[[$1]]“",
        "movedarticleprotection": "perkelti apsaugos nustatymai iš „[[$2]]“ į „[[$1]]“",
-       "protectedarticle-comment": "{{GENDER:$2|Apsaugojo}} „[[$1]]“",
+       "protectedarticle-comment": "{{GENDER:$2|Užrakino}} „[[$1]]“",
        "modifiedarticleprotection-comment": "{{GENDER:$2|Pakeitė „[[$1]]“ apsaugos lygį}}",
        "unprotectedarticle-comment": "{{GENDER:$2|Pašalino apsaugą}} iš „[[$1]]“",
        "protect-title": "Nustatomas apsaugos lygis puslapiui „$1“",
index c0035b9..cf8b463 100644 (file)
        "login": "Pieslēgties",
        "login-security": "Apstiprini savu identitāti",
        "nav-login-createaccount": "Izveidot jaunu lietotāju vai doties iekšā",
-       "userlogin": "Izveidot jaunu lietotāju vai doties iekšā",
-       "userloginnocreate": "Pieslēgties",
        "logout": "Iziet",
        "userlogout": "Iziet",
        "notloggedin": "Neesi iegājis",
        "userlogin-noaccount": "Nav dalībnieka konta?",
        "userlogin-joinproject": "Pievienojieties {{SITENAME}}",
-       "nologin": "Nav lietotājvārda? $1.",
-       "nologinlink": "Reģistrējies",
        "createaccount": "Izveidot jaunu lietotāju",
-       "gotaccount": "Tev jau ir lietotājvārds? '''$1'''!",
-       "gotaccountlink": "Pieslēgties",
-       "userlogin-resetlink": "Esat aizmirsis savu pieslēgšanās informāciju?",
        "userlogin-resetpassword-link": "Aizmirsi savu paroli?",
        "userlogin-helplink2": "Palīdzība ar pieslēgšanos",
        "userlogin-loggedin": "Tu esi pieslēdzies ar lietotājvārdu {{GENDER:$1|$1}}.\nLai pieslēgtos ar citu lietotājvārdu, aizpildi šo formu.",
        "createacct-another-email-ph": "Ievadiet e-pasta adresi",
        "createaccountmail": "Izmantot nejauši ģenerētu pagaidu paroli un nosūtīt to uz norādīto e-pasta adresi",
        "createacct-realname": "Īstais vārds (nav obligāts)",
-       "createaccountreason": "Iemesls:",
        "createacct-reason": "Iemesls",
        "createacct-reason-ph": "Kāpēc jūs veidojat citu kontu",
        "createacct-submit": "Izveidot savu kontu",
        "userrights-nodatabase": "Datubāze $1 neeksistē vai nav lokāla.",
        "userrights-changeable-col": "Grupas, kuras tu vari izmainīt",
        "userrights-unchangeable-col": "Grupas, kuras tu nevari izmainīt",
+       "userrights-expiry-othertime": "Cits laiks:",
        "group": "Grupa:",
        "group-user": "Dalībnieki",
        "group-autoconfirmed": "Automātiski apstiprinātie dalībnieki",
        "right-editprotected": "Labot aizsargātās lapas (bez kaskādes aizsardzības)",
        "right-editcontentmodel": "Labot lapas satura modeli",
        "right-editinterface": "Izmainīt dalībnieka interfeisu",
-       "right-editusercssjs": "Izmainīt citu dalībnieku CSS un JS failus",
        "right-editusercss": "Izmainīt citu dalībnieku CSS failus",
        "right-edituserjs": "Izmainīt citu dalībnieku JS failus",
        "right-editmyusercss": "Rediģējiet savus dalībnieka CSS failus",
        "grant-editmywatchlist": "Labot uzraugāmo rakstu sarakstu",
        "grant-editpage": "Labot esošās lapas",
        "grant-editprotected": "Labot aizsargātās lapas",
+       "grant-uploadfile": "Augšupielādēt jaunus failus",
        "grant-basic": "Pamattiesības",
        "grant-viewdeleted": "Skatīt dzēstos failus un lapas",
        "newuserlogpage": "Jauno dalībnieku reģistrs",
        "action-deletelogentry": "dzēst žurnāla ierakstus",
        "action-deletedhistory": "skatīt šīs lapas dzēsto vēsturi",
        "action-browsearchive": "meklēt dzēstās lapas",
-       "action-undelete": "atjaunot šo lapu",
-       "action-suppressrevision": "pārskatīt un atjaunot šo slēpto versiju",
+       "action-undelete": "atcelt lapu dzēšanu",
+       "action-suppressrevision": "pārskatīt un atjaunot slēptās versijas",
        "action-suppressionlog": "apskatīt šo privāto reģistru",
        "action-block": "bloķēt šo dalībnieku pret rakstu turpmāku labošanu",
        "action-protect": "izmainīt aizsardzības līmeņus šai lapai",
-       "action-import": "importēt šo lapu no citas viki",
+       "action-import": "importēt lapas no citas vikivietnes",
        "action-importupload": "importēt šo lapu no failu augšupielādes",
        "action-patrol": "atzīmēt citu labojumus kā pārbaudītus",
        "action-autopatrol": "iespēja savus labojumus atzīmēt kā pārbaudītus",
        "recentchanges-legend-heading": "<strong>Apzīmējumi:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (skatīt arī [[Special:NewPages|jaunās lapas]])",
        "recentchanges-submit": "Rādīt",
+       "rcfilters-activefilters": "Aktīvie filtri",
+       "rcfilters-restore-default-filters": "Atjaunot noklusētos filtrus",
+       "rcfilters-clear-all-filters": "Noņemt visus filtrus",
+       "rcfilters-search-placeholder": "Filtrēt pēdējās izmaiņas (pārlūko vai sāc rakstīt)",
        "rcfilters-invalid-filter": "Nederīgs filtrs",
+       "rcfilters-empty-filter": "Nav aktīvu filtru. Tiek rādītas visas izmaiņas.",
        "rcfilters-filterlist-title": "Filtri",
+       "rcfilters-filterlist-whatsthis": "Kas tas ir?",
+       "rcfilters-highlightbutton-title": "Izcelt rezultātus",
+       "rcfilters-highlightmenu-title": "Izvēlies krāsu",
+       "rcfilters-highlightmenu-help": "Izvēlies krāsu, lai izceltu šo īpašību",
        "rcfilters-filterlist-noresults": "Filtri nav atrasti",
        "rcfilters-filtergroup-registration": "Lietotāja reģistrācija",
+       "rcfilters-filter-registered-label": "Reģistrēti",
+       "rcfilters-filter-registered-description": "Pieslēgušies redaktori.",
+       "rcfilters-filter-unregistered-label": "Nereģistrēti",
+       "rcfilters-filter-unregistered-description": "Nepieslēgušies redaktori.",
+       "rcfilters-filter-editsbyself-label": "Tavi labojumi",
+       "rcfilters-filter-editsbyself-description": "Tevis veiktie labojumi.",
+       "rcfilters-filter-editsbyother-label": "Citu labojumi",
+       "rcfilters-filter-editsbyother-description": "Citu dalībnieku veiktie labojumi (bez taviem).",
+       "rcfilters-filtergroup-userExpLevel": "Pieredzes līmenis (tikai reģistrētiem dalībniekiem)",
+       "rcfilters-filtergroup-reviewstatus": "Pārskatīšanas statuss",
+       "rcfilters-filter-patrolled-label": "Patrulēti",
+       "rcfilters-filter-patrolled-description": "Labojumi, kas atzīmēti kā patrulēti.",
+       "rcfilters-filter-unpatrolled-label": "Nepatrulēti",
+       "rcfilters-filter-unpatrolled-description": "Labojumi, kas nav atzīmēti kā patrulēti.",
+       "rcfilters-filtergroup-significance": "Nozīmīgums",
+       "rcfilters-filter-minor-label": "Maznozīmīgi labojumi",
+       "rcfilters-filter-minor-description": "Labojumi, kas atzīmēti kā maznozīmīgi.",
+       "rcfilters-filter-major-label": "Nozīmīgi labojumi",
+       "rcfilters-filter-major-description": "Labojumi, kas nav atzīmēti kā maznozīmīgi.",
        "rcfilters-filtergroup-changetype": "Izmaiņu veids",
        "rcfilters-filter-pageedits-label": "Lapu labojumi",
        "rcfilters-filter-pageedits-description": "Labojumi vikivietnes saturā, diskusijā, kategoriju aprakstos...",
        "undeleteviewlink": "skatīt",
        "undeleteinvert": "Izvēlēties pretēji",
        "undeletecomment": "Iemesls:",
-       "undeletedrevisions": "$1 {{PLURAL:$1|versijas|versija|versijas}} {{PLURAL:$1|atjaunotas|atjaunota|atjaunotas}}",
-       "undeletedrevisions-files": "{{PLURAL:$1|$1 versijas|1 versija|$1 versijas}} un {{PLURAL:$2|$2 faili|1 fails|$2 faili}} atjaunoti",
-       "undeletedfiles": "{{PLURAL:$1|$1 faili atjaunoti|$1 fails atjaunots|$1 faili atjaunoti}}",
        "cannotundelete": "Atjaunošana neizdevās:\n$1",
        "undeletedpage": "'''$1 tika atjaunots'''\n\n[[Special:Log/delete|Dzēšanas reģistrā]] ir informācija par pēdējām dzēšanām un atjaunošanām.",
        "undelete-header": "Nesen dzēstajām lapām skatīt [[Special:Log/delete|dzēšanas reģistru]].",
        "unblocked-range": "$1 tika atbloķēts",
        "unblocked-id": "Bloks $1 tika noņemts",
        "blocklist": "Bloķētie lietotāji",
+       "autoblocklist-submit": "Meklēt",
        "ipblocklist": "Bloķētie lietotāji",
        "ipblocklist-legend": "Meklēt bloķētu lietotāju",
        "blocklist-userblocks": "Paslēpt kontu bloķējumus",
        "logentry-delete-delete": "$1 {{GENDER:$2|izdzēsa}} lapu $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|izdzēsa}} pāradresāciju $3 pārrakstot",
        "logentry-delete-restore": "$1 {{GENDER:$2|atjaunoja}} lapu $3",
+       "restore-count-files": "{{PLURAL: $1|$1 faili|$1 fails|$1 faili}}",
        "revdelete-content-hid": "saturs slēpts",
        "revdelete-summary-hid": "labojuma kopsavilkums slēpts",
        "revdelete-uname-hid": "lietotājvārds slēpts",
        "logentry-upload-upload": "$1 {{GENDER:$2|augšupielādēja}} $3",
        "logentry-upload-overwrite": "$1 augšupielādēja jaunu $3 versiju",
        "rightsnone": "(nav)",
-       "revdelete-summary": "izmaiņu kopsavilkums",
        "feedback-adding": "Atsauksmes tiek pievienotas lapai...",
        "feedback-back": "Atpakaļ",
        "feedback-bugnew": "Es pārbaudīju. Ziņot par jaunu kļūdu",
index 31b5304..d42e0e1 100644 (file)
        "right-editsemiprotected": "Hanova ny pejy narovna ho \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Hanova ny modelim-botoatin'ny pejy",
        "right-editinterface": "Manova ny interface ny mpikambana",
-       "right-editusercssjs": "Manova ny rakitra CSS sy JS ny mpikambana hafa",
        "right-editusercss": "Manova ny rakitra CSS ny mpikambana hafa",
        "right-edituserjs": "Manova ny rakitra JS an'ny mpikambana hafa",
        "right-editmyusercss": "Manova ny rakitra CSS-nao",
index c6bb80a..904c12f 100644 (file)
        "right-editsemiprotected": "Уредување на страници заштитени како „{{int:protect-level-autoconfirmed}}“",
        "right-editcontentmodel": "Уредување на содржинскиот модел на страница",
        "right-editinterface": "Уредување на кориснички посредник",
-       "right-editusercssjs": "Уредување на CSS и JS податотеки на други корисници",
        "right-editusercss": "Уредување на CSS податотеки на други корисници",
        "right-edituserjs": "Уредување на JS податотеки на други корисници",
        "right-editmyusercss": "Уредување на сопствени кориснички каскадни стилски податотеки (CSS)",
        "unblocked-id": "Блокирањето $1 беше отстрането",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] е одблокирана.",
        "blocklist": "Блокирани корисници",
+       "autoblocklist": "Автоблокови",
+       "autoblocklist-submit": "Пребарај",
+       "autoblocklist-legend": "Испис на автоблокови",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Месен автоблок|Месни автоблокови}}",
+       "autoblocklist-empty": "Списокот на автоблокови е празен.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Друг автоблок|Други автоблокови}}",
        "ipblocklist": "Блокирани корисници",
        "ipblocklist-legend": "Најди блокиран корисник",
        "blocklist-userblocks": "Скриј блокирања на корис. сметки",
index f386599..e76fd30 100644 (file)
        "right-editsemiprotected": "Menyunting halaman-halaman yang dilindungi sebagai \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Menyunting model kandungan laman",
        "right-editinterface": "Menyunting antara muka pengguna",
-       "right-editusercssjs": "Menyunting fail CSS dan JavaScript pengguna lain",
        "right-editusercss": "Menyunting fail CSS pengguna lain",
        "right-edituserjs": "Menyunting fail JavaScript pengguna lain",
        "right-editmyusercss": "Menyunting fail CSS pengguna sendiri",
index 46ecd0e..dd7a627 100644 (file)
        "right-editsemiprotected": "Redigere beskyttede sider som er «{{int:protect-level-autoconfirmed}}»",
        "right-editcontentmodel": "Redigere innholdsmodellen til en side",
        "right-editinterface": "Redigere brukergrensesnittet",
-       "right-editusercssjs": "Redigere andre brukeres CSS- og JS-filer",
        "right-editusercss": "Redigere andre brukeres CSS-filer",
        "right-edituserjs": "Redigere andre brukeres JS-filer",
        "right-editmyusercss": "Redigere sine egne CSS-filer",
        "unblocked-id": "Blokkering $1 ble fjernet",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] har blitt avblokkert.",
        "blocklist": "Blokkerte brukere",
+       "autoblocklist": "Automatiske blokkeringer",
+       "autoblocklist-submit": "Søk",
+       "autoblocklist-legend": "Liste over automatiske blokkeringer",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Lokal automatisk blokkering|Lokale automatiske blokkeringer}}",
+       "autoblocklist-empty": "Listen over automatiske blokkeringer er tom.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Annen automatisk blokkering|Andre automatiske blokkeringer}}",
        "ipblocklist": "Blokkerte IP-adresser og brukernavn",
        "ipblocklist-legend": "Finn en blokkert bruker",
        "blocklist-userblocks": "Skjul kontoblokkeringer",
index bc84842..3b6f134 100644 (file)
        "externaldberror": "यहाँ प्रमाणिकरण डेटाबेस त्रुटि भयो या त तपाईंलाई आफ्नो बाहिरी खाता अद्यतन गर्ने अनुमति छैन।",
        "login": "प्रवेश",
        "nav-login-createaccount": "प्रवेश गर्ने/नयाँ खाता बनाउने",
-       "userlogin": "प्रवेश गर्ने / नयाँ खाता बनाउने",
-       "userloginnocreate": "लग इन",
        "logout": "निर्गमन",
        "userlogout": "निर्गमन (लग आउट)",
        "notloggedin": "प्रवेश (लग ईन) नगरिएको",
        "userlogin-noaccount": "के खाता छैन ?",
        "userlogin-joinproject": "{{SITENAME}} मा खाता खोल्नुहोस् ।",
-       "nologin": "तपाईंको खाता छैन ? $1।",
-       "nologinlink": "नयाँ खाता खोल्नुहोस्",
        "createaccount": "खाता खोल्नुहोस्",
-       "gotaccount": "के तपाईँसँग पहिले देखि नै खाता छ ? '''$1''' ।",
-       "gotaccountlink": "लग इन",
-       "userlogin-resetlink": "प्रवेश सम्बन्धी विवरणहरू बिर्सनु भयो?",
        "userlogin-resetpassword-link": "पासवर्ड भुल्नुभयो?",
        "userlogin-helplink2": "प्रवेश गर्नको लागि सहयोग",
        "userlogin-loggedin": "तपाईं {{GENDER:$1|$1}}को रूपमा प्रवेश (लग इन) भइ सक्नु भयो ।\nअर्को प्रयोगकर्ताको रूपमा प्रवेश (लग इन) गर्न तलको फारम प्रयोग गर्नुहोस् ।",
        "createacct-another-email-ph": "इमेल ठेगाना भर्नुहोस्",
        "createaccountmail": "कुनै अस्थाई र श्रिजित पासवर्ड प्रयोग गर्ने र खुलाईएको इमेलमा पठाउने",
        "createacct-realname": "वास्तविक नाम (ऐच्छिक)",
-       "createaccountreason": "कारण:",
        "createacct-reason": "कारण",
        "createacct-reason-ph": "किन तपाईं नयाँ खाता खोलिरहनु भएको हो ?",
        "createacct-submit": "तपाईंको खाता सिर्जना गर्नुहोस",
        "right-editsemiprotected": "\"{{int:protect-level-autoconfirmed}}\" अनुरूप सुरक्षित गरिएको पृष्ठहरूलाई सम्पादन गर्नुहोस्",
        "right-editcontentmodel": "पृष्ठको सामग्री नमुना सम्पादन",
        "right-editinterface": "प्रयोगकर्ता अन्तरमोहडा सम्पादन गर्ने",
-       "right-editusercssjs": "अरु प्रयोगकर्ताको CSS र JS फाइलहरू सम्पादन गर्ने",
        "right-editusercss": "अरु प्रयोगकर्ताको CSS फाइलहरू सम्पादन गर्ने",
        "right-edituserjs": "अरु प्रयोकर्ताको जाभास्क्रिप्ट फाइलहरू सम्पादन गर्ने",
        "right-editmyusercss": "तपाईंको आफ्नो CSS फाइलहरू सम्पादन गर्नुहोस्",
        "linksearch-text": "\"*.wikipedia.org\" वाइल्डकार्डको रुपमा प्रयोग गर्न सकिने।\nकम्तिमा \".org\" जस्तो कुनै उच्च-स्तरीय डोमेनको आवश्यकता छ।<br />\nसमर्थित प्रोटोकल:$1 (यदि कुनै {{PLURAL:$2|प्रोटोकल|प्रोटोकलहरू}} दिइएको छैन भने http:// को प्रयोग गर्न सकिन्छ)",
        "linksearch-line": "$1 $2सित जोड़िएको छ।",
        "linksearch-error": "मूलनामको सुरुमा मात्र वाइल्डकार्ड देखापर्न सक्छ।",
-       "listusersfrom": "पà¥\8dरयà¥\8bà¤\97हरà¥\81 देखाउन शुरु हुने यहाँ:",
+       "listusersfrom": "पà¥\8dरयà¥\8bà¤\97हरà¥\82 देखाउन शुरु हुने यहाँ:",
        "listusers-submit": "देखाउनुहोस्",
        "listusers-noresult": "प्रयोगकर्ताहरू भेटिएनन्।",
        "listusers-blocked": "(प्रतिबन्धित)",
        "undeleteviewlink": "अवलोकन",
        "undeleteinvert": " चयन उल्ट्याउने",
        "undeletecomment": "कारण :",
-       "undeletedrevisions": "{{PLURAL:$1|एउटा संशोधन|$1 संशोधनहरू}} पुनर्स्थापित गरियो",
-       "undeletedrevisions-files": "{{PLURAL:$1|एउटा संशोधन|$1 संशोधनहरू}} र {{PLURAL:$2|एउटा फाइल|$2 फाइलहरू}} पुनर्स्थापित गरियो",
-       "undeletedfiles": "{{PLURAL:$1|१ फाइल|$1 फाइलहरू }} पूर्वस्थितिमा ल्याइयो",
        "cannotundelete": "मेटाएको रद्द गर्ने काम असफल भयो:\n$1",
        "undeletedpage": "'''$1लाई पूर्वावस्थामा ल्याइयो'''\nभर्खरै मेटाइएको रिकर्डहरु र पुनर्स्थापनाहरु हेर्न [[Special:Log/delete|मेटाइएको लग]]मा जानुहोस्।",
        "undelete-header": "भर्खर मेटिएका पृष्ठहरू हेर्न [[Special:Log/delete|मेटाइएका लग]]मा जानुहोस्।",
        "logentry-tag-update-revision": "$1 {{GENDER:$2|अपडेट गरियो}} ट्याग संशोधन $4 मा पृष्ठ $3 सँग ({{PLURAL:$7|जोडियो}} $6; {{PLURAL:$9|हटाइयो}} $8)",
        "logentry-tag-update-logentry": "$1 {{GENDER:$2|अपडेट गरियो}} ट्याग संशोधन $5 मा पृष्ठ $3 सँग ({{PLURAL:$7|जोडियो}} $6; {{PLURAL:$9|हटाइयो}} $8)",
        "rightsnone": "(कुनैपनि होइन)",
-       "revdelete-summary": "सम्पादन सारांश",
        "feedback-adding": "पृष्ठमा प्रतिक्रिया थप गर्दै...",
        "feedback-back": "अघिल्लो",
        "feedback-bugcheck": "राम्रो! जाँच्नुस की कतै [ $1 ज्ञात बगहरू] पहिले देखि नै नहोस्।",
index 7f7b847..0a9d671 100644 (file)
        "right-editsemiprotected": "Pagina's bewerken die beveiligd zijn als \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Het paginainhoudmodel bewerken",
        "right-editinterface": "De gebruikersinterface bewerken",
-       "right-editusercssjs": "De CSS- en JavaScriptbestanden van andere gebruikers bewerken",
        "right-editusercss": "De CSS-bestanden van andere gebruikers bewerken",
        "right-edituserjs": "De JavaScriptbestanden van andere gebruikers bewerken",
        "right-editmyusercss": "Uw eigen CSS-pagina's bewerken",
        "unblocked-id": "Blokkade $1 is opgeheven",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] is gedeblokkeerd.",
        "blocklist": "Geblokkeerde gebruikers",
+       "autoblocklist": "Automatische blokkades",
+       "autoblocklist-submit": "Zoeken",
+       "autoblocklist-legend": "Automatische blokkades tonen",
+       "autoblocklist-localblocks": "Lokale {{PLURAL:$1|automatische blokkades}}",
+       "autoblocklist-empty": "De lijst met automatische blokkades is leeg.",
+       "autoblocklist-otherblocks": "Andere {{PLURAL:$1|automatische blokkades}}",
        "ipblocklist": "Geblokkeerde gebruikers",
        "ipblocklist-legend": "Een geblokkeerde gebruiker zoeken",
        "blocklist-userblocks": "Geblokkeerde accounts verbergen",
index 1659f65..3779656 100644 (file)
        "right-editsemiprotected": "Edycja stron zabezpieczonych na poziomie „{{int:protect-level-autoconfirmed}}”",
        "right-editcontentmodel": "Edycja modelu zawartości strony",
        "right-editinterface": "Edycja interfejsu użytkownika",
-       "right-editusercssjs": "Edycja plików CSS i JS innych użytkowników",
        "right-editusercss": "Edycja plików CSS innych użytkowników",
        "right-edituserjs": "Edycja plików JS innych użytkowników",
        "right-editmyusercss": "Edycja swoich plików CSS",
        "unblocked-id": "Blokada $1 została zdjęta",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] został odblokowany.",
        "blocklist": "Zablokowani użytkownicy",
+       "autoblocklist": "Blokady automatyczne",
+       "autoblocklist-submit": "Szukaj",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Lokalna blokada automatyczna|Lokalne blokady automatyczne}}",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Inna blokada automatyczna|Inne blokady automatyczne}}",
        "ipblocklist": "Zablokowani użytkownicy",
        "ipblocklist-legend": "Znajdź zablokowanego użytkownika",
        "blocklist-userblocks": "Ukryj blokady konta",
index 5f0d19d..62ffff5 100644 (file)
        "page_first": "primeira",
        "page_last": "última",
        "histlegend": "Como selecionar: marque as caixas de seleção das versões que deseja comparar e pressione enter ou clique no botão na parte inferior do formulário.<br />\nLegenda: <strong>({{int:cur}})</strong> = diferenças em relação a última versão, <strong>({{int:last}})</strong> = diferenças em relação a versão anterior, <strong>{{int:minoreditletter}}</strong> = edição menor.",
-       "history-fieldset-title": "Navegar pelo histórico",
-       "history-show-deleted": "Apenas as eliminadas",
+       "history-fieldset-title": "Pesquisar revisões",
+       "history-show-deleted": "Apenas as revisões excluídas",
        "histfirst": "Mais antigas",
        "histlast": "Mais novas",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
        "saveusergroups": "Salvar grupos de{{GENDER:$1|usuário}}",
        "userrights-groupsmember": "Membro de:",
        "userrights-groupsmember-auto": "Membro implícito de:",
-       "userrights-groups-help": "É possível alterar os grupos em que {{GENDER:$1|este usuário|esta usuária|este(a) usuário(a)}} se encontra:\n* Uma caixa de seleção selecionada significa que {{GENDER:$1|o usuário|a usuária|o(a) usuário(a)}} encontra-se no grupo.\n* Uma caixa de seleção não selecionada significa que {{GENDER:$1|o usuário|a usuária|o(a) usuário(a)}} não se encontra no grupo.\n* Um * indica que não pode remover o grupo depois de o adicionar, ou vice-versa.",
+       "userrights-groups-help": "É possível alterar os grupos em que {{GENDER:$1|este usuário|esta usuária|este(a) usuário(a)}} se encontra:\n* Uma caixa de seleção selecionada significa que {{GENDER:$1|o usuário|a usuária|o(a) usuário(a)}} encontra-se no grupo.\n* Uma caixa de seleção não selecionada significa que {{GENDER:$1|o usuário|a usuária|o(a) usuário(a)}} não se encontra no grupo.\n* Um * indica que não pode remover o grupo depois de o adicionar, ou vice-versa.\n* Um # indica que você só pode atrasar o tempo de expiração dos membros deste grupo; você não pode aumentá-lo.",
        "userrights-reason": "Motivo:",
        "userrights-no-interwiki": "Você não tem permissão para alterar privilégios de usuários em outros wikis.",
        "userrights-nodatabase": "O banco de dados $1 não existe ou não é um banco de dados local.",
        "userrights-expiry-options": "1 dia:1 day,1 semana:1 week,1 mês:1 month,3 meses:3 months,6 meses:6 months,1 ano:1 year",
        "userrights-invalid-expiry": "O tempo de expiração para o grupo \"$1\" é inválido.",
        "userrights-expiry-in-past": "O tempo de expiração para o grupo \"$1\" está no passado.",
-       "userrights-cannot-shorten-expiry": "Você não pode antecipar a expiração do grupo \"$1\". Somente usuários com permissão para adicionar e remover este grupo pode apresentar tempos de expiração.",
+       "userrights-cannot-shorten-expiry": "Você não pode antecipar a expiração dos membros no grupo \"$1\". Somente usuários com permissão para adicionar e remover este grupo podem.",
        "userrights-conflict": "Há um comflito de permissões de usuário! Por favor, revise e confirme as alterações novamente.",
        "group": "Grupo:",
        "group-user": "Usuários",
        "right-editsemiprotected": "Editar páginas protegidas como \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Editar o modelo de uma pagina",
        "right-editinterface": "Editar a interface de usuário",
-       "right-editusercssjs": "Editar os arquivos CSS e JS de outros usuários",
        "right-editusercss": "Editar os arquivos CSS de outros usuários",
        "right-edituserjs": "Editar os arquivos JS de outros usuários",
        "right-editmyusercss": "Edite seu próprio arquivo CSS de usuário",
        "rcfilters-filterlist-feedbacklink": "Forneça feedback sobre os novos filtros (beta)",
        "rcfilters-highlightbutton-title": "Realçar os resultados",
        "rcfilters-highlightmenu-title": "Selecione uma cor",
+       "rcfilters-highlightmenu-help": "Selecione uma cor para realçar esta propriedade",
        "rcfilters-filterlist-noresults": "Nenhum filtro encontrado",
        "rcfilters-noresults-conflict": "Nenhum resultado encontrado porque os critérios de pesquisa estão em conflito",
+       "rcfilters-state-message-subset": "Este filtro não tem efeito porque seus resultados estão incluídos com {{PLURAL:$2|o seguinte filtro mais amplo|os seguintes filtros mais amplos}} (tente realçar para distingui-lo): $1",
+       "rcfilters-state-message-fullcoverage": "Selecionar todos os filtros em um grupo é o mesmo que não selecionar nenhum, portanto este filtro não tem efeito. O grupo inclui: $1",
        "rcfilters-filtergroup-registration": "Registro de usuário",
        "rcfilters-filter-registered-label": "Registrado",
        "rcfilters-filter-registered-description": "Editores conectados.",
        "rcfilters-filter-unregistered-label": "Não registrado",
        "rcfilters-filter-unregistered-description": "Editores que não estão conectados.",
+       "rcfilters-filter-unregistered-conflicts-user-experience-level": "Este filtro entra em conflito com {{PLURAL:$2|o seguinte filtro|os seguintes filtros}} de Experiência, que {{PLURAL:$2|encontra|encontram}} somente usuários registrados: $1",
        "rcfilters-filtergroup-authorship": "Editar autoria",
        "rcfilters-filter-editsbyself-label": "Suas próprias edições",
        "rcfilters-filter-editsbyself-description": "Edições por você.",
        "rcfilters-filter-editsbyother-label": "Edições de outros",
        "rcfilters-filter-editsbyother-description": "Edições criadas por outros usuários (não você.)",
        "rcfilters-filtergroup-userExpLevel": "Nível de experiência (apenas para usuário registados)",
+       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered": "Os filtros de experiência encontram apenas usuários registados, assim este filtro entra em conflito com o filtro “Não registado”.",
+       "rcfilters-filtergroup-user-experience-level-conflicts-unregistered-global": "O filtro \"Não Registrado\" entra em conflito com um ou mais filtros de Experiência, que localizam apenas usuários registrados. Os filtros em conflito são marcados na área Filtros Ativos, acima.",
        "rcfilters-filter-user-experience-level-newcomer-label": "Recém-chegados",
        "rcfilters-filter-user-experience-level-newcomer-description": "Menos de 10 edições e 4 dias de atividade.",
        "rcfilters-filter-user-experience-level-learner-label": "Aprendizes",
        "rcfilters-filter-bots-description": "Edições feitas por ferramentas automatizadas.",
        "rcfilters-filter-humans-label": "Humano (não bot)",
        "rcfilters-filter-humans-description": "Edições feitas por editores humanos.",
+       "rcfilters-filtergroup-reviewstatus": "Estado da revisão",
+       "rcfilters-filter-patrolled-label": "Patrulhado",
+       "rcfilters-filter-patrolled-description": "Edições marcadas como patrulhadas.",
        "rcfilters-filter-unpatrolled-label": "Não patrulhadas",
        "rcfilters-filter-unpatrolled-description": "Edições não marcadas como patrulhadas.",
        "rcfilters-filtergroup-significance": "Significado",
        "rcfilters-filter-categorization-description": "Registros de páginas que estão sendo adicionadas ou removidas de categorias.",
        "rcfilters-filter-logactions-label": "Acções registadas",
        "rcfilters-filter-logactions-description": "Ações administrativas, criação de contas, eliminação de páginas, carregamentos ...",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "O filtro \"Edições menores\" conflita com um ou mais filtros de Tipo de Alteração, porque certos tipos de alteração não podem ser designadas como \"menores\". Os filtros em conflito estão marcados na área Filtros Ativos, acima.",
+       "rcfilters-hideminor-conflicts-typeofchange": "Determinados tipos de alteração não podem ser designados como \"menor\", portanto, este filtro entra em conflito com os seguintes filtros de Tipo de Alteração: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "Este filtro de Tipo de Alteração entra em conflito com o filtro \"Edições menores\". Certos tipos de mudança não podem ser designadas como \"menores\".",
        "rcnotefrom": "Abaixo {{PLURAL:$5|é a mudança|são as mudanças}} desde <strong>$3, $4</strong> (up to <strong>$1</strong> shown).",
+       "rclistfromreset": "Redefinir seleção da data",
        "rclistfrom": "Mostrar as novas alterações a partir das $2 de $3",
        "rcshowhideminor": "$1 edições menores",
        "rcshowhideminor-show": "Exibir",
        "php-uploaddisabledtext": "O envio de arquivos via PHP está desativado.\nVerifique a configuração file_uploads.",
        "uploadscripted": "Este arquivo contém HTML ou código que pode ser erroneamente interpretado por um navegador web.",
        "upload-scripted-pi-callback": "Não é possível fazer upload de um arquivo que contém instruções de processamento de folha de estilo XML.",
+       "upload-scripted-dtd": "Não é possível carregar arquivos SVG que contenham uma declaração DTD não padrão.",
        "uploaded-script-svg": "Encontrado elemento de script \"$1\" no arquivo SVG carregado.",
        "uploaded-hostile-svg": "Encontrado CSS inseguro no elemento de estilo do arquivo SVG carregado.",
        "uploaded-event-handler-on-svg": "Não é permitido configurar atributos que manipulem eventos  <code>$1=\"$2\"</code> em arquivos SVG.",
        "editcomment": "O sumário de edição era: <em>$1</em>.",
        "revertpage": "Foram revertidas as edições de [[Special:Contributions/$2|$2]] ([[User talk:$2|disc]]) para a última versão por [[User:$1|$1]]",
        "revertpage-nouser": "Revertidas as edições de um usuário oculto para a última revisão de {{GENDER:$1|[[User:$1|$1]]}}",
-       "rollback-success": "Foram revertidas as edições de $1, com o conteúdo passando a estar como na última edição de $2.",
+       "rollback-success": "Edições revertidas por {{GENDER:$3|$1}};\nalterado para a última revisão por {{GENDER:$4|$2}}.",
        "rollback-success-notify": "Revertidas as edições de $1;\nMudança para a última revisão de $2. [$3 Mostrar alterações]",
        "sessionfailure-title": "Erro de sessão",
        "sessionfailure": "Foram detetados problemas com a sua sessão;\nEsta ação foi cancelada como medida de proteção contra a intercepção de sessões.\nExperimente usar o botão \"Voltar\" e atualizar a página de onde veio e tente novamente.",
        "unblocked-id": "O bloqueio de $1 foi removido com sucesso",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] foi desbloqueado.",
        "blocklist": "Usuários bloqueados",
+       "autoblocklist": "Bloqueios automáticos",
+       "autoblocklist-submit": "Pesquisar",
+       "autoblocklist-legend": "Listar bloqueios automáticos",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Bloqueio automático local|Bloqueios automáticos locais}}",
+       "autoblocklist-empty": "A lista de bloqueios automáticos está vazia.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Outro bloqueio automático|Outros bloqueios automáticos}}",
        "ipblocklist": "Usuários bloqueados",
        "ipblocklist-legend": "Procurar por um usuário bloqueado",
        "blocklist-userblocks": "Esconder bloqueios de contas",
        "htmlform-user-not-valid": "<strong>$1</strong> não é um nome de usuário válido.",
        "logentry-delete-delete": "$1 apagou a página $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|eliminou}} o redirecionamento $3, sobrescrevendo-o",
-       "logentry-delete-restore": "$1 restaurou a página $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|restaurou}} a página $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|restaurou}} a página $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 revisão|$1 revisões}}",
+       "restore-count-files": "{{PLURAL:$1|1 arquivo|$1 arquivos}}",
        "logentry-delete-event": "$1 alterou a visibilidade {{PLURAL:$5|de uma entrada|de $5 entradas}} do registro $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|alterou}} a visibilidade de {{PLURAL:$5|uma revisão|$5 revisões}} na página $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|alterou}} a visibilidade de entradas de registo em $3",
        "special-characters-group-thai": "Tailandês",
        "special-characters-group-lao": "Laociano",
        "special-characters-group-khmer": "Cambojano",
+       "special-characters-group-canadianaboriginal": "Aborígine Canadense",
        "special-characters-title-endash": "traço",
        "special-characters-title-emdash": "travessão",
        "special-characters-title-minus": "sinal de menos",
        "restrictionsfield-label": "Intervalos IP permitidos:",
        "restrictionsfield-help": "Um endereço IP ou intervalo CIDR por linha. Para ativar tudo, use\n<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revisão $1",
-       "pageid": "ID da página $1"
+       "pageid": "ID da página $1",
+       "rawhtml-notallowed": "As tags &lt;html&gt; não podem ser usadas fora das páginas normais.",
+       "gotointerwiki": "Saindo {{SITENAME}}",
+       "gotointerwiki-invalid": "O título especificado é invalido.",
+       "gotointerwiki-external": "Você está prestes a sair {{SITENAME}} para visitar [[$2]] que é um site externo.\n\n[$1 Clique aqui para continuar para $1].",
+       "undelete-cantedit": "Você não pode restaurar esta página, porque você não está autorizado a editar esta página.",
+       "undelete-cantcreate": "Você não pode restaurar esta página, pois não há uma página com este nome e você não está autorizado a criar esta página."
 }
index 8905262..6e7ad8c 100644 (file)
        "right-editsemiprotected": "Editar páginas protegidas com \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Editar o modelo de conteúdo de uma página",
        "right-editinterface": "Editar a interface de utilizador",
-       "right-editusercssjs": "Editar os ficheiros CSS e JS de outros utilizadores",
        "right-editusercss": "Editar os ficheiros CSS de outros utilizadores",
        "right-edituserjs": "Editar os ficheiros JS de outros utilizadores",
        "right-editmyusercss": "Editar os seus próprios ficheiros CSS de utilizador",
        "undeleteviewlink": "ver",
        "undeleteinvert": "Inverter seleção",
        "undeletecomment": "Motivo:",
-       "undeletedrevisions": "$1 {{PLURAL:$1|edição restaurada|edições restauradas}}",
-       "undeletedrevisions-files": "$1 {{PLURAL:$1|edição restaurada|edições restauradas}} e $2 {{PLURAL:$2|ficheiro restaurado|ficheiros restaurados}}",
-       "undeletedfiles": "{{PLURAL:$1|ficheiro restaurado|$1 ficheiros restaurados}}",
        "cannotundelete": "Algumas ou todas as restaurações falharam:\n$1",
        "undeletedpage": "'''$1 foi restaurada'''\n\nConsulte o [[Special:Log/delete|registo de eliminações]] para um registo das eliminações e restaurações mais recentes.",
        "undelete-header": "Consulte o [[Special:Log/delete|registo de eliminações]] para ver as páginas eliminadas recentemente.",
        "unblocked-id": "O bloqueio de $1 foi removido com sucesso",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] foi desbloqueado.",
        "blocklist": "Utilizadores bloqueados",
+       "autoblocklist": "Bloqueios automáticos",
+       "autoblocklist-submit": "Pesquisar",
+       "autoblocklist-legend": "Lista de bloqueios automáticos",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Bloqueio automático local|Bloqueios automáticos locais}}",
+       "autoblocklist-empty": "A lista de bloqueio automático está vazia.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Outro bloqueio automático|Outros bloqueios automáticos}}",
        "ipblocklist": "Utilizadores bloqueados",
        "ipblocklist-legend": "Procurar um utilizador bloqueado",
        "blocklist-userblocks": "Ocultar bloqueios de contas",
        "htmlform-user-not-valid": "<strong>$1</strong> não é um nome de utilizador válido.",
        "logentry-delete-delete": "$1 apagou a página $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|eliminou}} o redirecionamento $3, sobrescrevendo-o",
-       "logentry-delete-restore": "$1 restaurou a página $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|restaurou}} a página $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|restaurou}} a página $3",
+       "restore-count-revisions": "{{PLURAL:$1|1 revisão|$1 revisões}}",
+       "restore-count-files": "{{PLURAL:$1|1 ficheiro|$1 ficheiros}}",
        "logentry-delete-event": "$1 alterou a visibilidade de {{PLURAL:$5|uma entrada|$5 entradas}} em $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|alterou}} a visibilidade de {{PLURAL:$5|uma revisão|$5 revisões}} em $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|alterou}} a visibilidade de entradas de registo em $3",
        "special-characters-group-thai": "Tailandês",
        "special-characters-group-lao": "Laociano",
        "special-characters-group-khmer": "Cambojano",
+       "special-characters-group-canadianaboriginal": "Aborígene Canadense",
        "special-characters-title-endash": "hífen",
        "special-characters-title-emdash": "travessão",
        "special-characters-title-minus": "sinal de subtração",
        "restrictionsfield-label": "Gamas de endereços IP permitidas:",
        "restrictionsfield-help": "Um endereço IP ou uma gama CIDR por linha. Para ativar todos,\nuse: <pre>0.0.0.0/0\n::/0</pre>",
        "revid": "revisão $1",
-       "pageid": "identificador de página $1"
+       "pageid": "identificador de página $1",
+       "rawhtml-notallowed": "As etiquetas &lt;html&gt; não podem ser utilizadas fora de páginas normais.",
+       "gotointerwiki": "A sair de {{SITENAME}}",
+       "gotointerwiki-invalid": "O título especificado é inválido.",
+       "gotointerwiki-external": "Está prestes a sair de {{SITENAME}} para visitar [[$2]], que é um sítio web externo.\n\n[$1 Clique aqui para continuar para $1]"
 }
index b5fed9f..5f1c62e 100644 (file)
        "right-editsemiprotected": "Cange le pàggene prutette cumme a \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Cange 'u modelle de condenute de 'na pàgene",
        "right-editinterface": "Cange l'inderfacce utende",
-       "right-editusercssjs": "Cange 'u CSS e 'u JS de l'otre utinde",
        "right-editusercss": "Cange 'u CSS de l'otre utinde",
        "right-edituserjs": "Cange 'u JS de l'otre utinde",
        "right-editmyusercss": "Cange le file tune de CSS",
index aaf4370..726abbd 100644 (file)
        "post-expand-template-argument-category": "Страницы, содержащие пропущенные аргументы шаблонов",
        "parser-template-loop-warning": "Обнаружена петля в шаблонах: [[$1]]",
        "template-loop-category": "Страницы с петлями в шаблонах",
+       "template-loop-category-desc": "Эта страница содержит петлю в шаблоне, т.е. шаблон, который рекурсивно вызывает себя самого.",
        "parser-template-recursion-depth-warning": "Превышен предел глубины рекурсии шаблона ($1)",
        "language-converter-depth-warning": "Превышен предел глубины преобразователя языков ($1)",
        "node-count-exceeded-category": "Страницы, на которых превышено число узлов",
        "right-editsemiprotected": "правка страниц, защищённых как «{{int:protect-level-autoconfirmed}}»",
        "right-editcontentmodel": "редактирование контентной модели страницы",
        "right-editinterface": "изменение пользовательского интерфейса",
-       "right-editusercssjs": "правка CSS- и JS-файлов других участников",
        "right-editusercss": "правка CSS-файлов других участников",
        "right-edituserjs": "правка JavaScript-файлов других участников",
        "right-editmyusercss": "редактирование своих пользовательских CSS-файлов",
        "rcfilters-highlightmenu-title": "Выберите цвет",
        "rcfilters-highlightmenu-help": "Выберите цвет, чтобы подсветить это свойство",
        "rcfilters-filterlist-noresults": "Фильтры не найдены",
+       "rcfilters-noresults-conflict": "Результатов не найдено из-за конфликта критериев поиска",
        "rcfilters-filtergroup-registration": "Регистрация участников",
        "rcfilters-filter-registered-label": "Зарегистрированные",
        "rcfilters-filter-registered-description": "Вошедшие редакторы.",
        "unblocked-id": "Блокировка $1 была снята",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] был разблокирован.",
        "blocklist": "Заблокированные участники",
+       "autoblocklist-submit": "Найти",
        "ipblocklist": "Заблокированные участники",
        "ipblocklist-legend": "Поиск заблокированного участника",
        "blocklist-userblocks": "Скрыть блокировки учётных записей",
        "revid": "версия $1",
        "pageid": "ID страницы $1",
        "rawhtml-notallowed": "&lt;html&gt; теги могут быть использованы только в пределах обычных страниц.",
-       "gotointerwiki": "Покидаем {{grammar:genitive|{{SITENAME}}}}...",
+       "gotointerwiki": "Покидаем {{grammar:accusative|{{SITENAME}}}}...",
        "gotointerwiki-invalid": "Указан некорректный заголовок.",
-       "gotointerwiki-external": "Вы покидаете {{grammar:genitive|{{SITENAME}}}} для посещения сайта [[$2]].\n\n[$1 Нажмите здесь, чтобы перейти на $1].",
+       "gotointerwiki-external": "Вы покидаете {{grammar:accusative|{{SITENAME}}}} для посещения сайта [[$2]].\n\n[$1 Нажмите здесь, чтобы перейти на $1].",
        "undelete-cantedit": "Вы не можете восстановить эту страницу, поскольку у вас недостаточно прав для ее редактирования.",
        "undelete-cantcreate": "Вы не можете восстановить эту страницу, поскольку она не существует, а у вас недостаточно прав для ее создания."
 }
index 33f7fd3..ec34495 100644 (file)
        "right-editsemiprotected": "Eedit pages protected aes \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Eedit the content model o ae page",
        "right-editinterface": "Eedit the uiser interface",
-       "right-editusercssjs": "Eedit ither uisers' CSS n JavaScript files",
        "right-editusercss": "Eedit ither uisers' CSS files",
        "right-edituserjs": "Eedit ither uisers' JavaScript files",
        "right-editmyusercss": "Eidit yer ain uiser CSS files",
index 61c06bd..c77f077 100644 (file)
        "right-editsemiprotected": "Urejanje strani, zaščitenih kot »{{int:protect-level-autoconfirmed}}«",
        "right-editcontentmodel": "Urejanje vsebinskega modela strani",
        "right-editinterface": "Urejanje uporabniškega vmesnika",
-       "right-editusercssjs": "Urejanje CSS- in JS-datotek drugih uporabnikov",
        "right-editusercss": "Uredi CSS datotek drugih uporabnikov",
        "right-edituserjs": "Uredi JS datotek drugih uporabnikov",
        "right-editmyusercss": "Uredite svoje uporabniške datoteke CSS",
        "unblocked-id": "Blokada $1 je odstranjena",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] smo odblokirali.",
        "blocklist": "Blokirani uporabniki",
+       "autoblocklist": "Samodejne blokade",
+       "autoblocklist-submit": "Išči",
+       "autoblocklist-legend": "Seznam samodejnih blokad",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Lokalna samodejna blokada|Lokalni samodejni blokadi|Lokalne samodejne blokade}}",
+       "autoblocklist-empty": "Seznam samodejnih blokad je prazen.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Druga samodejna blokada|Drugi samodejni blokadi|Druge samodejne blokade}}",
        "ipblocklist": "Blokirani uporabniki",
        "ipblocklist-legend": "Poišči blokiranega uporabnika",
        "blocklist-userblocks": "skrij blokade računov",
index 08a1a82..76ade66 100644 (file)
        "right-editsemiprotected": "Redakto faqet e mbrojtura, si \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Redakto modelin e përmbajtjes së një faqeje",
        "right-editinterface": "Ndrysho parapamjen e përdoruesit",
-       "right-editusercssjs": "Redakto skedat CSS dhe JS të përdoruesve tjerë",
        "right-editusercss": "Redakto skedat CSS të përdoruesve tjerë",
        "right-edituserjs": "Redakto skedat JS të përdoruesve tjerë",
        "right-editmyusercss": "Redakto CSS - skedat e tua të përdoruesit",
index 9ea137f..bf00f7d 100644 (file)
        "right-editsemiprotected": "уређивање страница под заштитом „{{int:protect-level-autoconfirmed}}“",
        "right-editcontentmodel": "мењање модела садржаја странице",
        "right-editinterface": "уређивање корисничког окружења",
-       "right-editusercssjs": "уређивање туђих CSS и јаваскрипт датотека",
        "right-editusercss": "уређивање туђих CSS датотека",
        "right-edituserjs": "уређивање туђих JavaScript датотека",
        "right-editmyusercss": "уређивање сопствених CSS датотека",
index 141dea8..b3a2adf 100644 (file)
        "right-editprotected": "uređivanje stranice pod zaštitom „{{int:protect-level-sysop}}“",
        "right-editsemiprotected": "uređivanje stranica pod zaštitom „{{int:protect-level-autoconfirmed}}“",
        "right-editinterface": "uređivanje korisničkog okruženja",
-       "right-editusercssjs": "uređivanje tuđih CSS i javaskript datoteka",
        "right-editusercss": "uređivanje tuđih CSS datoteka",
        "right-edituserjs": "uređivanje tuđih JavaScript datoteka",
        "right-editmyusercss": "uređivanje sopstvenih CSS datoteka",
index 92c0899..86f240b 100644 (file)
@@ -38,7 +38,7 @@
        "tog-enotifminoredits": "Béjaan ogé (ngaliwatan surélék) lamun aya parobahan leutik dina kaca jeung berkasna",
        "tog-enotifrevealaddr": "Témbongkeun alamat surélék kuring dina surat émbaran",
        "tog-shownumberswatching": "Témbongkeun jumlah nu ngawaskeun",
-       "tog-oldsig": "Paraf nu geus aya:",
+       "tog-oldsig": "Tawisan anjeun nu nyampak:",
        "tog-fancysig": "Témbongkeun tanda tangan salaku wikitext (tanpa tutumbu otomatis)",
        "tog-uselivepreview": "Paké pratayang langsung",
        "tog-forceeditsummary": "Mun kotak ringkesan éditan masih kosong, béjaan!",
        "category-article-count": "{{PLURAL:$2|Ieu kategori ngan ngawengku nu di handap.|{{PLURAL:$1|kaca|$1 kaca}} ti $2 di handap asup kana ieu kategori.}}",
        "category-article-count-limited": "{{PLURAL:$1|Kaca|$1 kaca}} di handap kaasup kana kategori.",
        "category-file-count": "{{PLURAL:$2|Ieu kategori ngan boga berkas di handap.|{{PLURAL:$1|berkas|$1 berkas}} di handap aya dina ieu kategori, ti jumlah $2.}}",
-       "category-file-count-limited": "{{PLURAL:$1|berkas|$1 berkas}} di handap aya dina kategori ieu.",
+       "category-file-count-limited": "{{PLURAL:$1|berkas|$1 berkas}} di handap aya dina ieu kategori.",
        "listingcontinuesabbrev": "(samb.)",
        "index-category": "Kaca nu diindéks",
        "noindex-category": "Kaca nu teu diindéks",
        "createacct-reason-ph": "Naha bet nyieun akun séjén",
        "createacct-submit": "Jieun akun anjeun",
        "createacct-another-submit": "Jieun akun",
+       "createacct-continue-submit": "Tuluykeun panyieunan akun",
+       "createacct-another-continue-submit": "Tuluykeun panyieunan akun",
        "createacct-benefit-heading": "{{SITENAME}} téh dijieun ku jalma-jalma siga anjeun.",
        "createacct-benefit-body1": "{{PLURAL:$1|édit|édit}}",
        "createacct-benefit-body2": "{{PLURAL:$1|kaca|kaca}}",
        "right-protect": "Ngarobah hambalan protéksi jeung édit kaca anu dikonci",
        "right-editprotected": "Edit kaca anu dikonci salaku \"{{int:protect-level-sysop}}\"",
        "right-editinterface": "Édit antarbenget pamaké",
-       "right-editusercssjs": "Édit berkas CSS jeung JS pamaké séjén",
        "right-editusercss": "Édit berkas CSS pamaké séjén",
        "right-edituserjs": "Ngédit berkas JS pamaké séjén",
        "right-viewmywatchlist": "Tempo awaskeuneun anjeun",
        "fileexists-extension": "Geus aya berkas anu ngaranna sarupa: [[$2|thumb]]\n* Ngaran berkas nu dimuat: <strong>[[:$1]]</strong>\n* Ngaran berkas nu geus aya: <strong>[[:$2]]</strong>\nPilih ngaran séjén.",
        "fileexists-forbidden": "Berkas  nu ngaranna kitu geus aya sarta teu bisa ditimpah.\nMun anjeun keukeuh rék ngunggahkeun berkas anjeun, mangga balik deui sarta paké ngaran anyar.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Gening berkas téh geus aya nu ngaranna sarua dina répositori berkas reujeung.\nMun anjeun keukeuh hayang ngunjal ieu berkas, sok ganti heula ngaranna ku ngaran nu béda. [[File:$1|thumb|center|$1]]",
-       "file-exists-duplicate": "Gambar ieu duplikat ti {{PLURAL:$1|gambar|gambar}}:",
+       "file-exists-duplicate": "Ieu berkas téh duplikat jeung nu di handap {{PLURAL:$1|berkas}}:",
        "file-deleted-duplicate": "Berkas anu sarua jeung [[:$1]] geus kungsi dihapus.\nPariksa heula jujutan hapusanana saméméh neruskeun ngamuat deui éta berkas.",
        "uploadwarning": "Pépéling ngamuat",
        "uploadwarning-text": "Ropéa pedaran berkas di handap terus cobaan deui.",
        "nbytes": "$1 {{PLURAL:$1|bait|bait}}",
        "ncategories": "$1 {{PLURAL:$1|kategori|kategori}}",
        "ninterwikis": "$1 {{PLURAL:$1|interwiki|interwiki}}",
-       "nlinks": "$1 {{PLURAL:$1|tutumbu|tutumbu}}",
+       "nlinks": "$1 {{PLURAL:$1|tutumbu}}",
        "nmembers": "$1 {{PLURAL:$1|kontributor|kontributor}}",
        "nmemberschanged": "$1 → $2 {{PLURAL:$2|anggota|anggota}}",
        "nrevisions": "$1 {{PLURAL:$1|révisi|révisi}}",
        "mostlinkedcategories": "Paling loba ditumbukeun ka kategori",
        "mostlinkedtemplates": "Citakan nu panglobana ditumbu",
        "mostcategories": "Artikel nu paling loba ngandung kategori",
-       "mostimages": "Berkas anu panglobana ditutumbukeun",
+       "mostimages": "Berkas anu panglobana ditumbukeun",
        "mostrevisions": "Artikel nu pangmindengna dirévisi",
        "prefixindex": "Kabeh kaca maké awalan",
        "shortpages": "Kaca-kaca parondok",
index 87d00c2..df3d133 100644 (file)
        "right-editsemiprotected": "Redigera skyddade sidor som \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Ändra innehållsmodellen för en sida",
        "right-editinterface": "Redigera användargränssnittet",
-       "right-editusercssjs": "Redigera andra användares CSS- och JS-filer",
        "right-editusercss": "Redigera andra användares CSS-filer",
        "right-edituserjs": "Redigera andra användares JavaScript-filer",
        "right-editmyusercss": "Redigera din egen användares CSS-filer",
index 39e8627..32f99ad 100644 (file)
        "revdelete-offender": "Revizyon yazarı:",
        "suppressionlog": "Gizleme günlüğü",
        "suppressionlogtext": "Aşağıdaki, hizmetlilerden gizlenen içerik içeren silinmelerin ve engellemelerin listesidir.\nŞu anda işlevsel olan yasak ve engellemelerin listesi için [[Special:BlockList|engelleme listesine]] bakın.",
-       "mergehistory": "Sayfa geçmişlerini takas et.",
+       "mergehistory": "Sayfa geçmişlerini birleştir",
        "mergehistory-header": "Bu sayfa, bir kaynak sayfanın geçmiş revizyonlarını yeni bir sayfaya birleştirmenize olanak sağlar.\nBu değişikliğin geçmişe ait sayfa devamlılığını devam ettirdiğinden emin olun.",
        "mergehistory-box": "İki sayfanın revizyonlarını birleştir:",
        "mergehistory-from": "Kaynak sayfa:",
        "right-editsemiprotected": "\"{{int:protect-level-autoconfirmed}}\" olarak korunan sayfalarda değişiklik yap",
        "right-editcontentmodel": "Sayfanın içerik modelini düzenle",
        "right-editinterface": "Kullanıcı arayüzünü değiştirmek",
-       "right-editusercssjs": "Diğer kullanıcıların CSS ve JS dosyalarında değişiklik yap",
        "right-editusercss": "Diğer kullanıcıların CSS dosyalarında değişiklik yap",
        "right-edituserjs": "Diğer kullanıcıların JS dosyalarında değişiklik yap",
        "right-editmyusercss": "Kendi kullanıcı CSS dosyaları düzenle",
        "mostlinkedtemplates": "En çok dahil edilen sayfalar",
        "mostcategories": "En fazla kategoriye bağlanmış sayfalar",
        "mostimages": "En çok bağlantı verilmiş dosyalar",
-       "mostinterwikis": "En çok interwiki'ye sahip sayfalar",
+       "mostinterwikis": "En çok intervikiye sahip sayfalar",
        "mostrevisions": "En çok değişikliğe uğramış sayfalar",
        "prefixindex": "Önek ile tüm sayfalar",
        "prefixindex-namespace": "Önek ile tüm sayfalar ($1 ad alanında)",
        "logentry-contentmodel-change-revert": "Eski haline döndür",
        "protectlogpage": "Koruma günlüğü",
        "protectlogtext": "Aşağıdaki, sayfa korumalarına değişikliklerin bir listesidir.\nŞu anda uygulanan sayfa korumaları için [[Special:ProtectedPages|koruma altına alınmış sayfalar listesine]] bakabilirsiniz.",
-       "protectedarticle": "\"[[$1]]\" koruma altında alındı",
+       "protectedarticle": "\"[[$1]]\" adlı sayfayı koruma altına aldı",
        "modifiedarticleprotection": "\"[[$1]]\" için koruma düzeyi değiştirildi",
        "unprotectedarticle": "koruma kaldırıldı: \"[[$1]]\"",
        "movedarticleprotection": "koruma ayarları \"[[$2]]\" sayfasından \"[[$1]]\" sayfasına taşındı",
+       "protectedarticle-comment": "\"[[$1]]\" adlı sayfayı {{GENDER:$2|koruma altına aldı}}",
        "modifiedarticleprotection-comment": "\"[[$1]]\" için {{GENDER:$2|koruma düzeyini değiştirdi}}",
        "protect-title": "\"$1\" için bir koruma seviyesi seçiniz",
        "protect-title-notallowed": "\"$1\" için koruma seviyesini görüntüleyin",
        "autosumm-blank": "Sayfa boşaltıldı",
        "autosumm-replace": "Sayfa içeriği '$1' ile değiştirildi",
        "autoredircomment": "[[$1]] sayfasına yönlendirildi",
-       "autosumm-new": "Yeni sayfa: \"$1\"",
+       "autosumm-new": "\"$1\" içeriğiyle yeni sayfa oluşturdu",
        "autosumm-newblank": "Boş bir sayfa oluşturdu",
        "lag-warn-normal": "$1 {{PLURAL:$1|saniyeden|saniyeden}} yeni değişiklikler bu listede görünmeyebilir.",
        "lag-warn-high": "Veritabanı sunucusundaki aşırı gecikmeden dolayı, $1 {{PLURAL:$1|saniyeden|saniyeden}} yeni değişiklikler bu listede görünmeyebilir.",
        "logentry-newusers-create2": "$3 kullanıcı hesabı $1 tarafından {{GENDER:$2|oluşturuldu}}",
        "logentry-newusers-byemail": "$3 kullanıcı hesabı $1 tarafından {{GENDER:$2|oluşturuldu}} ve şifre e-posta ile gönderildi",
        "logentry-newusers-autocreate": "$1 kullanıcı hesabı otomatik olarak {{GENDER:$2|oluşturuldu}}",
+       "logentry-protect-unprotect": "$1, $3 sayfasının korumasını {{GENDER:$2|kaldırdı}}",
        "logentry-rights-rights": "$1, $3 için grup üyeliğini $4 iken $5 olarak {{GENDER:$2|değiştirdi}}",
        "logentry-rights-rights-legacy": "$1, $3 için grup üyeliğini {{GENDER:$2|değiştirdi}}",
        "logentry-rights-autopromote": "$1, $4 iken $5 olarak otomatik {{GENDER:$2|terfi edildi}}",
index a5dbfef..4a7a018 100644 (file)
        "category_header": "«$1» категориысь бамъёс",
        "subcategories": "Подкатегориос",
        "category-media-header": "«$1» категориысь файлъёс",
-       "category-empty": "''Та категориын али бамъёс но, файлъёс но ӧвӧл.''",
+       "category-empty": "<em>Та категориын али бамъёс но, файлъёс но ӧвӧл.</em>",
        "hidden-categories": "{{PLURAL:$1|1=Ватэм категория|Ватэм категориос}}",
        "hidden-category-category": "Ватэм категориос",
        "category-subcat-count": "{{PLURAL:$2|1=Со категориын одӥг подкатегория гинэ.|Возьматэмын $1 {{PLURAL:$1|подкатегория|подкатегориос}} $2 пӧлысь.}}",
        "viewyourtext": "Тӥ быгатӥськоды та бамез <strong>тӥляд тупатонъёстылэсь</strong> кодзэс учкыны но кӧчырыны.",
        "protectedinterface": "Та бам возе интерфейс текстэз та викилэн программной обеспечениезлы. Вандализмез палэнтон понна со утемын воштонъёслэсь.\nВань викиослы берыктэмъёсты ватсалляны яке вошъяны вылысь, тауна, MediaWiki локализацияя сайтэ выжелэ — [https://translatewiki.net/ translatewiki.net].",
        "editinginterface": "<strong>Сак луэ:</strong> Тӥ тупатӥськоды бамез, кудӥз возе программной обеспеченилэсь интерфейс текстсэ.\nТа бамез тупатон воштоз интерфейсэз возьматонэз мукет викиавторъёслы та викиын.",
-       "namespaceprotected": "Тон дорын редактировать карыны бам ӧвӧл юаське <кужмо>$1</strong> инты нимъёс.",
+       "namespaceprotected": "Тон дорын редактировать карыны бам ӧвӧл юаське <strong>$1</strong> инты нимъёс.",
        "exception-nologin": "Ӧд пыре системае",
        "logouttext": "<strong>Тӥ ужан сеансэз йылпумъяды.</strong>\n\nКуд-огез бамъёс возьматӥськыны на быгато озьы, тӥ авторизовать каремын на кадь. Талы пумит нюръяськон понна бушатэ браузерлэсь кэшсэ.",
        "welcomeuser": "Гажаса ӧтиськом, $1!",
        "yourdomainname": "Тӥляд доменды:",
        "login": "Пырыны",
        "nav-login-createaccount": "Нимдэс вераны / Регистрациез ортчытыны",
-       "userlogin": "Регистрациез ортчытыны яке Википедие пырыны",
-       "userloginnocreate": "Пырыны",
        "logout": "Кошкыны",
        "userlogout": "Потыны",
        "notloggedin": "Ӧд пыре системае",
        "userlogin-noaccount": "Ас учётной записьты ӧвӧл?",
        "userlogin-joinproject": "Проектэ пыриськоно",
-       "nologin": "Учётной запись ӧвӧл? $1.",
-       "nologinlink": "Учётной записез кылдытыны",
        "createaccount": "Выль викиавторлэн регистрациез",
-       "gotaccountlink": "Пырелэ",
        "userlogin-resetpassword-link": "Тӥлесьтыд парольдэс куштыны?",
        "userlogin-helplink2": "Пыронъя юрттэт",
        "createacct-emailrequired": "Электрон почталэн адресэз",
        "currentrevisionlink": "Алиез версия",
        "cur": "али",
        "last": "азьв.",
-       "history-fieldset-title": "Историез учкыны",
-       "history-show-deleted": "Ӵушылэмъёссэ гинэ",
+       "history-fieldset-title": "Историез воштӥськон понна",
+       "history-show-deleted": "Ӵотаны ӵушылэмъёссэ гинэ",
        "rev-delundel": "возьматыны/ватыны",
        "rev-showdeleted": "возьматоно",
        "revdelete-show-file-submit": "Бен",
        "prefs-editing": "Тупатон",
        "yourlanguage": "Интерфейслэн кылыз:",
        "prefs-preview": "Бамез эскерон",
-       "userrights": "Пыриськисьлэн правоосыныз кивалтон",
+       "userrights": "Пыриськисьлэн правоосыныз",
        "editusergroup": "Викиавторлэсь группаоссэ возьматыны",
        "group-autoconfirmed": "Авто-юнматэм викиавторъёс",
        "group-bot": "Ботъёс",
        "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|1=Метка|Меткаос}}]]: $2)",
        "tags-title": "Меткаос",
        "logentry-delete-delete": "$1 {{GENDER:$2|быдтӥз}} $3 бамез",
-       "logentry-delete-restore": "$1 {{GENDER:$2|берен сётӥз}} $3 бамез",
+       "logentry-delete-restore": "$1 {{GENDER:$2|берен сётӥз}} $3 бамез ($4)",
        "logentry-block-block": "$1 {{GENDER:$2|заблокировать кариз}} {{GENDER:$4|$3}} дырлы: $5 $6",
+       "logentry-block-unblock": "$1 {{GENDER:$2|разблокировать кариз}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|воштӥз}} блокировкалэсь йылпумъянзэ {{GENDER:$4|$3}} понна дырлы: $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|заблокировать кариз}} {{GENDER:$4|$3}} дырлы: $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|воштӥз}} блокировкалэсь йылпумъянзэ {{GENDER:$4|$3}} понна дырлы: $5 $6",
index b4e4c93..5514f29 100644 (file)
        "right-editsemiprotected": "редагування сторінок з рівнем захисту «{{int:protect-level-autoconfirmed}}»",
        "right-editcontentmodel": "Редагувати модель вмісту сторінки",
        "right-editinterface": "редагування інтерфейсу користувача",
-       "right-editusercssjs": "редагування CSS- і JS-файлів інших користувачів",
        "right-editusercss": "редагування CSS-файлів інших користувачів",
        "right-edituserjs": "редагування JS-файлів інших користувачів",
        "right-editmyusercss": "редагування власних CSS-файлів користувача",
        "rcfilters-hideminor-conflicts-typeofchange": "Певні типи змін не можна позначити як «незначні», тож цей фільтр конфліктує з такими фільтрами за типом змін: $1",
        "rcfilters-typeofchange-conflicts-hideminor": "Цей фільтр за типом змін конфліктує з фільтром «Незначні редагування». Певні типи змін не можна позначати як «незначні».",
        "rcnotefrom": "Нижче знаходяться {{PLURAL:$5|редагування}} з <strong>$3, $4</strong> (відображено до <strong>$1</strong>).",
+       "rclistfromreset": "Скинути вибір дати",
        "rclistfrom": "Показати редагування починаючи з $3 $2.",
        "rcshowhideminor": "$1 незначні редагування",
        "rcshowhideminor-show": "Показати",
        "php-uploaddisabledtext": "Завантаження файлів вимкнене у налаштуваннях PHP. Будь ласка, перевірте значення file_uploads.",
        "uploadscripted": "Файл містить HTML-код або скрипт, який може неправильно обробитися браузером.",
        "upload-scripted-pi-callback": "Неможливо завантажити файл, що містить інструкції опрацювання таблиці стилів XML.",
+       "upload-scripted-dtd": "Неможливо завантажувати SVG-файли, які містять нестандартну декларацію DTD.",
        "uploaded-script-svg": " \t\t\nЗнайдений небезпечний елемент з підтримкою сценаріїв «$1» в завантаженому файлі SVG.",
        "uploaded-hostile-svg": " \t\nЗнайдений небезпечний CSS-код в елементі стилю завантаженого файлу SVG.",
        "uploaded-event-handler-on-svg": " \t\nУстановка атрибутів обробника подій <code>$1=\"$2\"</code> не дозволено для SVG-файлів.",
        "unblocked-id": "Блокування $1 було зняте.",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] розблоковано.",
        "blocklist": "Заблоковані користувачі",
+       "autoblocklist": "Автоблокування",
+       "autoblocklist-submit": "Пошук",
+       "autoblocklist-legend": "Вивести список автоблокувань",
+       "autoblocklist-localblocks": "{{PLURAL:$1|Локальне|Локальні}} автоблокування",
+       "autoblocklist-empty": "Список автоблокувань порожній.",
+       "autoblocklist-otherblocks": "{{PLURAL:$1|Інше|Інші}} автоблокування",
        "ipblocklist": "Список заблокованих адрес та користувачів",
        "ipblocklist-legend": "Пошук заблокованого користувача",
        "blocklist-userblocks": "Сховати блокування облікових записів",
        "htmlform-user-not-valid": "<strong>$1</strong> не є дійсним іменем користувача.",
        "logentry-delete-delete": "$1 {{GENDER:$2|вилучив|вилучила}} сторінку $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|вилучив|вилучила}} перенаправлення $3 шляхом перезапису",
-       "logentry-delete-restore": "$1 {{GENDER:$2|відновив|відновила}} сторінку $3",
+       "logentry-delete-restore": "$1 {{GENDER:$2|відновив|відновила}} сторінку $3 ($4)",
+       "logentry-delete-restore-nocount": "$1 {{GENDER:$2|відновив|відновила}} сторінку $3",
+       "restore-count-revisions": "{{PLURAL:$1|$1 версія|$1 версії|$1 версій}}",
+       "restore-count-files": "{{PLURAL:$1|$1 файл|$1 файли|$1 файлів}}",
        "logentry-delete-event": "$1 {{GENDER:$2|змінив|змінила}} видимість {{PLURAL:$5 запису журналу|$5 записів журналу}} на $3: $4",
        "logentry-delete-revision": "$1 {{GENDER:$2|змінив|змінила}} видимість {{PLURAL:$5|$5 версії|$5 версій}} на сторінці $3: $4",
        "logentry-delete-event-legacy": "$1 {{GENDER:$2|змінив|змінила}} видимість записів журналу подій $3",
        "special-characters-group-thai": "Тайські",
        "special-characters-group-lao": "Лаоські",
        "special-characters-group-khmer": "Кхмерські",
+       "special-characters-group-canadianaboriginal": "Письмо канадських аборигенів",
        "special-characters-title-endash": "коротке тире",
        "special-characters-title-emdash": "довге тире",
        "special-characters-title-minus": "мінус",
        "restrictionsfield-help": "Одна IP-адреса або CIDR-діапазон на рядок. Щоб увімкнути все, використайте:<pre>0.0.0.0/0\n::/0</pre>",
        "revid": "версія $1",
        "pageid": "ID сторінки $1",
-       "rawhtml-notallowed": "Теги &lt;html&gt; не можна використовувати за межами звичайних сторінок."
+       "rawhtml-notallowed": "Теги &lt;html&gt; не можна використовувати за межами звичайних сторінок.",
+       "gotointerwiki": "Ви покидаєте сайт {{SITENAME}}",
+       "gotointerwiki-invalid": "Вказана назва була неприпустимою.",
+       "gotointerwiki-external": "Ви збираєтесь покинути сайт {{SITENAME}}, щоб відвідати проект [[$2]], який є окремим веб-сайтом.\n\n[$1 Клацніть тут, щоб продовжити, перейшовши до $1].",
+       "undelete-cantedit": "Ви не можете відновити цю сторінку, оскільки Ви не маєте прав на редагування цієї сторінки.",
+       "undelete-cantcreate": "Ви не можете відновити цю сторінку, оскільки сторінка з такою назвою не існує, і Ви не маєте прав на створення цієї сторінки."
 }
index 031e9d5..52545a1 100644 (file)
        "right-editsemiprotected": "改保護等級係「{{int:protect-level-autoconfirmed}}」嘅版面",
        "right-editcontentmodel": "改版面嘅內容模型",
        "right-editinterface": "編輯用戶界面",
-       "right-editusercssjs": "編輯其他用戶嘅CSS同埋JavaScript檔",
        "right-editusercss": "編輯其他用戶嘅CSS檔",
        "right-edituserjs": "編輯其他用戶嘅JavaScript檔",
        "right-editmyusercss": "編輯戶口嘅CSS文件",
index 05f1a62..7305da5 100644 (file)
        "right-editsemiprotected": "编辑保护级别为“{{int:protect-level-autoconfirmed}}”的页面",
        "right-editcontentmodel": "编辑页面的内容模型",
        "right-editinterface": "编辑用户界面",
-       "right-editusercssjs": "编辑其他用户的CSS和JavaScript文件",
        "right-editusercss": "编辑其他用户的CSS文件",
        "right-edituserjs": "编辑其他用户的JavaScript文件",
        "right-editmyusercss": "编辑您的用户CSS文件",
        "unblocked-id": "封禁$1已被解除",
        "unblocked-ip": "[[Special:Contributions/$1|$1]]已解封。",
        "blocklist": "被封禁用户",
+       "autoblocklist": "自动封禁",
+       "autoblocklist-submit": "搜索",
+       "autoblocklist-legend": "列举自动封禁",
+       "autoblocklist-localblocks": "本地{{PLURAL:$1|自动封禁}}",
+       "autoblocklist-empty": "自动封禁列表为空。",
+       "autoblocklist-otherblocks": "其他{{PLURAL:$1|自动封禁}}",
        "ipblocklist": "被封禁用户",
        "ipblocklist-legend": "查找被封禁用户",
        "blocklist-userblocks": "隐藏账户封禁",
index fc3ad95..75227c4 100644 (file)
        "right-editsemiprotected": "編輯保護層級為 \"{{int:protect-level-autoconfirmed}}\" 的頁面",
        "right-editcontentmodel": "編輯頁面的內容模型",
        "right-editinterface": "編輯使用者介面",
-       "right-editusercssjs": "編輯其他使用者的 CSS 與 JavaScript 檔",
        "right-editusercss": "編輯其他使用者的 CSS 檔",
        "right-edituserjs": "編輯其他使用者的 JavaScript 檔",
        "right-editmyusercss": "編輯自己的使用者 CSS 檔",
index 4dedc47..7adf9c0 100644 (file)
@@ -8,4 +8,23 @@
  *
  */
 
+$namespaceNames = [
+       NS_MEDIA            => 'मिडिया',
+       NS_SPECIAL          => 'बिशेष',
+       NS_TALK             => 'कुरणि',
+       NS_USER             => 'प्रयोगकर्ता',
+       NS_USER_TALK        => 'प्रयोगकर्ता_कुरणि',
+       NS_PROJECT_TALK     => '$1_वार्ता',
+       NS_FILE             => 'चित्र',
+       NS_FILE_TALK        => 'चित्र_कुरणि',
+       NS_MEDIAWIKI        => 'मिडियाविकि',
+       NS_MEDIAWIKI_TALK   => 'मिडियाविकि_कुरणि',
+       NS_TEMPLATE         => 'ढाँचा',
+       NS_TEMPLATE_TALK    => 'ढाँचा_कुरणि',
+       NS_HELP             => 'मद्दत',
+       NS_HELP_TALK        => 'मद्दत_कुरणि',
+       NS_CATEGORY         => 'श्रेणी',
+       NS_CATEGORY_TALK    => 'श्रेणी_कुरणि',
+];
+
 $fallback = 'ne';
index e4bb60e..faa4d96 100644 (file)
@@ -28,6 +28,7 @@
 require_once __DIR__ . '/Maintenance.php';
 
 use Wikimedia\Rdbms\IMaintainableDatabase;
+use Wikimedia\Rdbms\DatabaseSqlite;
 
 /**
  * Maintenance script that rebuilds search index table from scratch.
index 33ca0ff..cbb0c79 100644 (file)
@@ -21,6 +21,8 @@
  * @ingroup Maintenance
  */
 
+use Wikimedia\Rdbms\DatabaseSqlite;
+
 /**
  * This class contains code common to different SQLite-related maintenance scripts
  *
index 64ef3bc..71a5f61 100644 (file)
@@ -132,9 +132,14 @@ return [
        /* jQuery */
 
        'jquery' => [
-               'scripts' => [
-                       'resources/lib/jquery/jquery.js',
-               ],
+               'scripts' => ( $GLOBALS['wgUsejQueryThree'] ?
+                       [
+                               'resources/lib/jquery/jquery3.js',
+                               'resources/lib/jquery/jquery.migrate.js',
+                       ] : [
+                               'resources/lib/jquery/jquery.js',
+                       ]
+               ),
                'raw' => true,
                'targets' => [ 'desktop', 'mobile' ],
        ],
diff --git a/resources/lib/jquery/jquery.migrate.js b/resources/lib/jquery/jquery.migrate.js
new file mode 100644 (file)
index 0000000..05b1a80
--- /dev/null
@@ -0,0 +1,540 @@
+/*!
+ * jQuery Migrate - v3.0.0 - 2016-06-09
+ * Copyright jQuery Foundation and other contributors
+ */
+(function( jQuery, window ) {
+"use strict";
+
+
+jQuery.migrateVersion = "3.0.0";
+
+
+( function() {
+
+       // Support: IE9 only
+       // IE9 only creates console object when dev tools are first opened
+       // Also, avoid Function#bind here to simplify PhantomJS usage
+       var log = window.console && window.console.log &&
+                       function() { window.console.log.apply( window.console, arguments ); },
+               rbadVersions = /^[12]\./;
+
+       if ( !log ) {
+               return;
+       }
+
+       // Need jQuery 3.0.0+ and no older Migrate loaded
+       if ( !jQuery || rbadVersions.test( jQuery.fn.jquery ) ) {
+               log( "JQMIGRATE: jQuery 3.0.0+ REQUIRED" );
+       }
+       if ( jQuery.migrateWarnings ) {
+               log( "JQMIGRATE: Migrate plugin loaded multiple times" );
+       }
+
+       // Show a message on the console so devs know we're active
+       log( "JQMIGRATE: Migrate is installed" +
+               ( jQuery.migrateMute ? "" : " with logging active" ) +
+               ", version " + jQuery.migrateVersion );
+
+} )();
+
+var warnedAbout = {};
+
+// List of warnings already given; public read only
+jQuery.migrateWarnings = [];
+
+// Set to false to disable traces that appear with warnings
+if ( jQuery.migrateTrace === undefined ) {
+       jQuery.migrateTrace = true;
+}
+
+// Forget any warnings we've already given; public
+jQuery.migrateReset = function() {
+       warnedAbout = {};
+       jQuery.migrateWarnings.length = 0;
+};
+
+function migrateWarn( msg ) {
+       var console = window.console;
+       if ( !warnedAbout[ msg ] ) {
+               warnedAbout[ msg ] = true;
+               jQuery.migrateWarnings.push( msg );
+               if ( console && console.warn && !jQuery.migrateMute ) {
+                       console.warn( "JQMIGRATE: " + msg );
+                       if ( jQuery.migrateTrace && console.trace ) {
+                               console.trace();
+                       }
+               }
+       }
+}
+
+function migrateWarnProp( obj, prop, value, msg ) {
+       Object.defineProperty( obj, prop, {
+               configurable: true,
+               enumerable: true,
+               get: function() {
+                       migrateWarn( msg );
+                       return value;
+               }
+       } );
+}
+
+if ( document.compatMode === "BackCompat" ) {
+
+       // JQuery has never supported or tested Quirks Mode
+       migrateWarn( "jQuery is not compatible with Quirks Mode" );
+}
+
+
+var oldInit = jQuery.fn.init,
+       oldIsNumeric = jQuery.isNumeric,
+       oldFind = jQuery.find,
+       rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,
+       rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g;
+
+jQuery.fn.init = function( arg1 ) {
+       var args = Array.prototype.slice.call( arguments );
+
+       if ( typeof arg1 === "string" && arg1 === "#" ) {
+
+               // JQuery( "#" ) is a bogus ID selector, but it returned an empty set before jQuery 3.0
+               migrateWarn( "jQuery( '#' ) is not a valid selector" );
+               args[ 0 ] = [];
+       }
+
+       return oldInit.apply( this, args );
+};
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.find = function( selector ) {
+       var args = Array.prototype.slice.call( arguments );
+
+       // Support: PhantomJS 1.x
+       // String#match fails to match when used with a //g RegExp, only on some strings
+       if ( typeof selector === "string" && rattrHashTest.test( selector ) ) {
+
+               // The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0
+               // First see if qS thinks it's a valid selector, if so avoid a false positive
+               try {
+                       document.querySelector( selector );
+               } catch ( err1 ) {
+
+                       // Didn't *look* valid to qSA, warn and try quoting what we think is the value
+                       selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) {
+                               return "[" + attr + op + "\"" + value + "\"]";
+                       } );
+
+                       // If the regexp *may* have created an invalid selector, don't update it
+                       // Note that there may be false alarms if selector uses jQuery extensions
+                       try {
+                               document.querySelector( selector );
+                               migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] );
+                               args[ 0 ] = selector;
+                       } catch ( err2 ) {
+                               migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] );
+                       }
+               }
+       }
+
+       return oldFind.apply( this, args );
+};
+
+// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML)
+var findProp;
+for ( findProp in oldFind ) {
+       if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) {
+               jQuery.find[ findProp ] = oldFind[ findProp ];
+       }
+}
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+       migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" );
+       return this.length;
+};
+
+jQuery.parseJSON = function() {
+       migrateWarn( "jQuery.parseJSON is deprecated; use JSON.parse" );
+       return JSON.parse.apply( null, arguments );
+};
+
+jQuery.isNumeric = function( val ) {
+
+       // The jQuery 2.2.3 implementation of isNumeric
+       function isNumeric2( obj ) {
+               var realStringObj = obj && obj.toString();
+               return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
+       }
+
+       var newValue = oldIsNumeric( val ),
+               oldValue = isNumeric2( val );
+
+       if ( newValue !== oldValue ) {
+               migrateWarn( "jQuery.isNumeric() should not be called on constructed objects" );
+       }
+
+       return oldValue;
+};
+
+migrateWarnProp( jQuery, "unique", jQuery.uniqueSort,
+       "jQuery.unique is deprecated, use jQuery.uniqueSort" );
+
+// Now jQuery.expr.pseudos is the standard incantation
+migrateWarnProp( jQuery.expr, "filters", jQuery.expr.pseudos,
+       "jQuery.expr.filters is now jQuery.expr.pseudos" );
+migrateWarnProp( jQuery.expr, ":", jQuery.expr.pseudos,
+       "jQuery.expr[\":\"] is now jQuery.expr.pseudos" );
+
+
+var oldAjax = jQuery.ajax;
+
+jQuery.ajax = function( ) {
+       var jQXHR = oldAjax.apply( this, arguments );
+
+       // Be sure we got a jQXHR (e.g., not sync)
+       if ( jQXHR.promise ) {
+               migrateWarnProp( jQXHR, "success", jQXHR.done,
+                       "jQXHR.success is deprecated and removed" );
+               migrateWarnProp( jQXHR, "error", jQXHR.fail,
+                       "jQXHR.error is deprecated and removed" );
+               migrateWarnProp( jQXHR, "complete", jQXHR.always,
+                       "jQXHR.complete is deprecated and removed" );
+       }
+
+       return jQXHR;
+};
+
+
+var oldRemoveAttr = jQuery.fn.removeAttr,
+       oldToggleClass = jQuery.fn.toggleClass,
+       rmatchNonSpace = /\S+/g;
+
+jQuery.fn.removeAttr = function( name ) {
+       var self = this;
+
+       jQuery.each( name.match( rmatchNonSpace ), function( i, attr ) {
+               if ( jQuery.expr.match.bool.test( attr ) ) {
+                       migrateWarn( "jQuery.fn.removeAttr no longer sets boolean properties: " + attr );
+                       self.prop( attr, false );
+               }
+       } );
+
+       return oldRemoveAttr.apply( this, arguments );
+};
+
+jQuery.fn.toggleClass = function( state ) {
+
+       // Only deprecating no-args or single boolean arg
+       if ( state !== undefined && typeof state !== "boolean" ) {
+               return oldToggleClass.apply( this, arguments );
+       }
+
+       migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" );
+
+       // Toggle entire class name of each element
+       return this.each( function() {
+               var className = this.getAttribute && this.getAttribute( "class" ) || "";
+
+               if ( className ) {
+                       jQuery.data( 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 || state === false ?
+                               "" :
+                               jQuery.data( this, "__className__" ) || ""
+                       );
+               }
+       } );
+};
+
+
+var internalSwapCall = false;
+
+// If this version of jQuery has .swap(), don't false-alarm on internal uses
+if ( jQuery.swap ) {
+       jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) {
+               var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get;
+
+               if ( oldHook ) {
+                       jQuery.cssHooks[ name ].get = function() {
+                               var ret;
+
+                               internalSwapCall = true;
+                               ret = oldHook.apply( this, arguments );
+                               internalSwapCall = false;
+                               return ret;
+                       };
+               }
+       } );
+}
+
+jQuery.swap = function( elem, options, callback, args ) {
+       var ret, name,
+               old = {};
+
+       if ( !internalSwapCall ) {
+               migrateWarn( "jQuery.swap() is undocumented and deprecated" );
+       }
+
+       // 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 oldData = jQuery.data;
+
+jQuery.data = function( elem, name, value ) {
+       var curData;
+
+       // If the name is transformed, look for the un-transformed name in the data object
+       if ( name && name !== jQuery.camelCase( name ) ) {
+               curData = jQuery.hasData( elem ) && oldData.call( this, elem );
+               if ( curData && name in curData ) {
+                       migrateWarn( "jQuery.data() always sets/gets camelCased names: " + name );
+                       if ( arguments.length > 2 ) {
+                               curData[ name ] = value;
+                       }
+                       return curData[ name ];
+               }
+       }
+
+       return oldData.apply( this, arguments );
+};
+
+var oldTweenRun = jQuery.Tween.prototype.run;
+
+jQuery.Tween.prototype.run = function( percent ) {
+       if ( jQuery.easing[ this.easing ].length > 1 ) {
+               migrateWarn(
+                       "easing function " +
+                       "\"jQuery.easing." + this.easing.toString() +
+                       "\" should use only first argument"
+               );
+
+               jQuery.easing[ this.easing ] = jQuery.easing[ this.easing ].bind(
+                       jQuery.easing,
+                       percent, this.options.duration * percent, 0, 1, this.options.duration
+               );
+       }
+
+       oldTweenRun.apply( this, arguments );
+};
+
+var oldLoad = jQuery.fn.load,
+       originalFix = jQuery.event.fix;
+
+jQuery.event.props = [];
+jQuery.event.fixHooks = {};
+
+jQuery.event.fix = function( originalEvent ) {
+       var event,
+               type = originalEvent.type,
+               fixHook = this.fixHooks[ type ],
+               props = jQuery.event.props;
+
+       if ( props.length ) {
+               migrateWarn( "jQuery.event.props are deprecated and removed: " + props.join() );
+               while ( props.length ) {
+                       jQuery.event.addProp( props.pop() );
+               }
+       }
+
+       if ( fixHook && !fixHook._migrated_ ) {
+               fixHook._migrated_ = true;
+               migrateWarn( "jQuery.event.fixHooks are deprecated and removed: " + type );
+               if ( ( props = fixHook.props ) && props.length ) {
+                       while ( props.length ) {
+                          jQuery.event.addProp( props.pop() );
+                       }
+               }
+       }
+
+       event = originalFix.call( this, originalEvent );
+
+       return fixHook && fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+};
+
+jQuery.each( [ "load", "unload", "error" ], function( _, name ) {
+
+       jQuery.fn[ name ] = function() {
+               var args = Array.prototype.slice.call( arguments, 0 );
+
+               // If this is an ajax load() the first arg should be the string URL;
+               // technically this could also be the "Anything" arg of the event .load()
+               // which just goes to show why this dumb signature has been deprecated!
+               // jQuery custom builds that exclude the Ajax module justifiably die here.
+               if ( name === "load" && typeof args[ 0 ] === "string" ) {
+                       return oldLoad.apply( this, args );
+               }
+
+               migrateWarn( "jQuery.fn." + name + "() is deprecated" );
+
+               args.splice( 0, 0, name );
+               if ( arguments.length ) {
+                       return this.on.apply( this, args );
+               }
+
+               // Use .triggerHandler here because:
+               // - load and unload events don't need to bubble, only applied to window or image
+               // - error event should not bubble to window, although it does pre-1.7
+               // See http://bugs.jquery.com/ticket/11820
+               this.triggerHandler.apply( this, args );
+               return this;
+       };
+
+} );
+
+// Trigger "ready" event only once, on document ready
+jQuery( function() {
+       jQuery( document ).triggerHandler( "ready" );
+} );
+
+jQuery.event.special.ready = {
+       setup: function() {
+               if ( this === document ) {
+                       migrateWarn( "'ready' event is deprecated" );
+               }
+       }
+};
+
+jQuery.fn.extend( {
+
+       bind: function( types, data, fn ) {
+               migrateWarn( "jQuery.fn.bind() is deprecated" );
+               return this.on( types, null, data, fn );
+       },
+       unbind: function( types, fn ) {
+               migrateWarn( "jQuery.fn.unbind() is deprecated" );
+               return this.off( types, null, fn );
+       },
+       delegate: function( selector, types, data, fn ) {
+               migrateWarn( "jQuery.fn.delegate() is deprecated" );
+               return this.on( types, selector, data, fn );
+       },
+       undelegate: function( selector, types, fn ) {
+               migrateWarn( "jQuery.fn.undelegate() is deprecated" );
+               return arguments.length === 1 ?
+                       this.off( selector, "**" ) :
+                       this.off( types, selector || "**", fn );
+       }
+} );
+
+
+var oldOffset = jQuery.fn.offset;
+
+jQuery.fn.offset = function() {
+       var docElem,
+               elem = this[ 0 ],
+               origin = { top: 0, left: 0 };
+
+       if ( !elem || !elem.nodeType ) {
+               migrateWarn( "jQuery.fn.offset() requires a valid DOM element" );
+               return origin;
+       }
+
+       docElem = ( elem.ownerDocument || document ).documentElement;
+       if ( !jQuery.contains( docElem, elem ) ) {
+               migrateWarn( "jQuery.fn.offset() requires an element connected to a document" );
+               return origin;
+       }
+
+       return oldOffset.apply( this, arguments );
+};
+
+
+var oldParam = jQuery.param;
+
+jQuery.param = function( data, traditional ) {
+       var ajaxTraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+
+       if ( traditional === undefined && ajaxTraditional ) {
+
+               migrateWarn( "jQuery.param() no longer uses jQuery.ajaxSettings.traditional" );
+               traditional = ajaxTraditional;
+       }
+
+       return oldParam.call( this, data, traditional );
+};
+
+var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
+
+jQuery.fn.andSelf = function() {
+       migrateWarn( "jQuery.fn.andSelf() replaced by jQuery.fn.addBack()" );
+       return oldSelf.apply( this, arguments );
+};
+
+
+var oldDeferred = jQuery.Deferred,
+       tuples = [
+
+               // Action, add listener, callbacks, .then handlers, final state
+               [ "resolve", "done", jQuery.Callbacks( "once memory" ),
+                       jQuery.Callbacks( "once memory" ), "resolved" ],
+               [ "reject", "fail", jQuery.Callbacks( "once memory" ),
+                       jQuery.Callbacks( "once memory" ), "rejected" ],
+               [ "notify", "progress", jQuery.Callbacks( "memory" ),
+                       jQuery.Callbacks( "memory" ) ]
+       ];
+
+jQuery.Deferred = function( func ) {
+       var deferred = oldDeferred(),
+               promise = deferred.promise();
+
+       deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) {
+               var fns = arguments;
+
+               migrateWarn( "deferred.pipe() is deprecated" );
+
+               return jQuery.Deferred( function( newDefer ) {
+                       jQuery.each( tuples, function( i, tuple ) {
+                               var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+
+                               // Deferred.done(function() { bind to newDefer or newDefer.resolve })
+                               // deferred.fail(function() { bind to newDefer or newDefer.reject })
+                               // deferred.progress(function() { bind to newDefer or newDefer.notify })
+                               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();
+
+       };
+
+       if ( func ) {
+               func.call( deferred, deferred );
+       }
+
+       return deferred;
+};
+
+
+
+})( jQuery, window );
diff --git a/resources/lib/jquery/jquery3.js b/resources/lib/jquery/jquery3.js
new file mode 100644 (file)
index 0000000..d2d8ca4
--- /dev/null
@@ -0,0 +1,10253 @@
+/*!
+ * jQuery JavaScript Library v3.2.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: 2017-03-20T18:59Z
+ */
+( 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 = {};
+
+
+
+       function DOMEval( code, doc ) {
+               doc = doc || document;
+
+               var script = doc.createElement( "script" );
+
+               script.text = code;
+               doc.head.appendChild( script ).parentNode.removeChild( script );
+       }
+/* 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.2.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,
+
+       // Matches dashed string for camelizing
+       rmsPrefix = /^-ms-/,
+       rdashAlpha = /-([a-z])/g,
+
+       // 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,
+
+       // 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" && !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 = 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() {},
+
+       isFunction: function( obj ) {
+               return jQuery.type( obj ) === "function";
+       },
+
+       isWindow: function( obj ) {
+               return obj != null && obj === obj.window;
+       },
+
+       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 ) );
+       },
+
+       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;
+       },
+
+       type: function( 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;
+       },
+
+       // Evaluates a script in a global context
+       globalEval: function( code ) {
+               DOMEval( code );
+       },
+
+       // Convert dashed to camelCase; used by the css and data modules
+       // Support: IE <=9 - 11, Edge 12 - 13
+       // Microsoft forgot to hump their vendor prefix (#9572)
+       camelCase: function( string ) {
+               return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+       },
+
+       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,
+
+       // Bind a function to a context, optionally partially applying any
+       // arguments.
+       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 ( !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: Date.now,
+
+       // 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 = jQuery.type( obj );
+
+       if ( type === "function" || jQuery.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 );
+
+
+
+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 ) {
+                       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;
+               } );
+       }
+
+       // Simple selector that can be filtered directly, removing non-Elements
+       if ( risSimple.test( qualifier ) ) {
+               return jQuery.filter( qualifier, elements, not );
+       }
+
+       // Complex selector, compare the two sets, removing non-Elements
+       qualifier = jQuery.filter( qualifier, elements );
+       return jQuery.grep( elements, function( elem ) {
+               return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
+       } );
+}
+
+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 ( 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 ] );
+
+                                       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 ( jQuery.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 ( jQuery.isFunction( arg ) ) {
+                                                               if ( !options.unique || !self.has( arg ) ) {
+                                                                       list.push( arg );
+                                                               }
+                                                       } else if ( arg && arg.length && jQuery.type( 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 && jQuery.isFunction( ( method = value.promise ) ) ) {
+                       method.call( value ).done( resolve ).fail( reject );
+
+               // Other thenables
+               } else if ( value && jQuery.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 = jQuery.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 && jQuery.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 ( jQuery.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,
+                                                               jQuery.isFunction( onProgress ) ?
+                                                                       onProgress :
+                                                                       Identity,
+                                                               newDefer.notifyWith
+                                                       )
+                                               );
+
+                                               // fulfilled_handlers.add( ... )
+                                               tuples[ 1 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.isFunction( onFulfilled ) ?
+                                                                       onFulfilled :
+                                                                       Identity
+                                                       )
+                                               );
+
+                                               // rejected_handlers.add( ... )
+                                               tuples[ 2 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.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,
+
+                                       // progress_callbacks.lock
+                                       tuples[ 0 ][ 2 ].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" ||
+                               jQuery.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 ( jQuery.type( 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 ( !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 < 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;
+};
+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[ jQuery.camelCase( data ) ] = value;
+
+               // Handle: [ owner, { properties } ] args
+               } else {
+
+                       // Copy the properties one-by-one to the cache object
+                       for ( prop in data ) {
+                               cache[ jQuery.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 ][ jQuery.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( jQuery.camelCase );
+                       } else {
+                               key = jQuery.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 = jQuery.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 = 1,
+               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 ) {
+
+               // Trust units reported by jQuery.css
+               unit = unit || initialInUnit[ 3 ];
+
+               // Make sure we update the tween properties later on
+               valueParts = valueParts || [];
+
+               // Iteratively approximate from a nonzero starting point
+               initialInUnit = +initial || 1;
+
+               do {
+
+                       // If previous iteration zeroed out, double until we get *something*.
+                       // Use string for doubling so we don't accidentally see scale as unchanged below
+                       scale = scale || ".5";
+
+                       // Adjust and apply
+                       initialInUnit = initialInUnit / scale;
+                       jQuery.style( elem, prop, initialInUnit + unit );
+
+               // Update scale, tolerating zero or NaN from tween.cur()
+               // Break the loop if scale is unchanged or perfect, or if we've just had enough.
+               } while (
+                       scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
+               );
+       }
+
+       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 = ( /^$|\/(?: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 ( jQuery.type( 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: jQuery.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 || jQuery.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
+       // 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,
+       rscriptTypeMasked = /^true\/(.*)/,
+       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( ">tbody", elem )[ 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 ) {
+       var match = rscriptTypeMasked.exec( elem.type );
+
+       if ( match ) {
+               elem.type = match[ 1 ];
+       } 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 ],
+               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 collection.each( function( index ) {
+                       var self = collection.eq( index );
+                       if ( isFunction ) {
+                               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 ) {
+
+                                                       // 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 );
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       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 rmargin = ( /^margin/ );
+
+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 );
+       };
+
+
+
+( 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;
+               }
+
+               div.style.cssText =
+                       "box-sizing:border-box;" +
+                       "position:relative;display:block;" +
+                       "margin:auto;border:1px;padding:1px;" +
+                       "top:1%;width:50%";
+               div.innerHTML = "";
+               documentElement.appendChild( container );
+
+               var divStyle = window.getComputedStyle( div );
+               pixelPositionVal = divStyle.top !== "1%";
+
+               // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
+               reliableMarginLeftVal = divStyle.marginLeft === "2px";
+               boxSizingReliableVal = divStyle.width === "4px";
+
+               // Support: Android 4.0 - 4.3 only
+               // Some styles come back with percentage values, even though they shouldn't
+               div.style.marginRight = "50%";
+               pixelMarginRightVal = divStyle.marginRight === "4px";
+
+               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;
+       }
+
+       var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, 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";
+
+       container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
+               "padding:0;margin-top:1px;position:absolute";
+       container.appendChild( div );
+
+       jQuery.extend( support, {
+               pixelPosition: function() {
+                       computeStyleTests();
+                       return pixelPositionVal;
+               },
+               boxSizingReliable: function() {
+                       computeStyleTests();
+                       return boxSizingReliableVal;
+               },
+               pixelMarginRight: function() {
+                       computeStyleTests();
+                       return pixelMarginRightVal;
+               },
+               reliableMarginLeft: function() {
+                       computeStyleTests();
+                       return reliableMarginLeftVal;
+               }
+       } );
+} )();
+
+
+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.pixelMarginRight() && 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;
+               }
+       }
+
+       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 augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+       var i,
+               val = 0;
+
+       // If we already have the right measurement, avoid augmentation
+       if ( extra === ( isBorderBox ? "border" : "content" ) ) {
+               i = 4;
+
+       // Otherwise initialize for horizontal or vertical properties
+       } else {
+               i = name === "width" ? 1 : 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 computed style
+       var valueIsBorderBox,
+               styles = getStyles( elem ),
+               val = curCSS( elem, name, styles ),
+               isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+       // Computed unit is not pixels. Stop here and return.
+       if ( rnumnonpx.test( val ) ) {
+               return val;
+       }
+
+       // 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 ] );
+
+       // Fall back to offsetWidth/Height when value is "auto"
+       // This happens for inline elements with no explicit setting (gh-3571)
+       if ( val === "auto" ) {
+               val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
+       }
+
+       // 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: {
+               "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: {
+               "float": "cssFloat"
+       },
+
+       // 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 ),
+                       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 = jQuery.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, name ) {
+       jQuery.cssHooks[ name ] = {
+               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, name, extra );
+                                               } ) :
+                                               getWidthOrHeight( elem, name, extra );
+                       }
+               },
+
+               set: function( elem, value, extra ) {
+                       var matches,
+                               styles = extra && getStyles( elem ),
+                               subtract = extra && augmentWidthOrHeight(
+                                       elem,
+                                       name,
+                                       extra,
+                                       jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+                                       styles
+                               );
+
+                       // Convert to pixels if value adjustment is needed
+                       if ( subtract && ( matches = rcssNum.exec( value ) ) &&
+                               ( matches[ 3 ] || "px" ) !== "px" ) {
+
+                               elem.style[ name ] = value;
+                               value = jQuery.css( elem, name );
+                       }
+
+                       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 ( !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 ( 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 = jQuery.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 - 13
+               // Record all 3 overflow attributes because IE does not infer the shorthand
+               // from identically-valued overflowX and overflowY
+               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 = jQuery.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 ( jQuery.isFunction( result.stop ) ) {
+                               jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
+                                       jQuery.proxy( result.stop, result );
+                       }
+                       return result;
+               }
+       }
+
+       jQuery.map( props, createTween, animation );
+
+       if ( jQuery.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 ( jQuery.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 ||
+                       jQuery.isFunction( speed ) && speed,
+               duration: speed,
+               easing: fn && easing || easing && !jQuery.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 ( 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( 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 = jQuery.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://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
+       function stripAndCollapse( value ) {
+               var tokens = value.match( rnothtmlwhite ) || [];
+               return tokens.join( " " );
+       }
+
+
+function getClass( elem ) {
+       return elem.getAttribute && elem.getAttribute( "class" ) || "";
+}
+
+jQuery.fn.extend( {
+       addClass: function( value ) {
+               var classes, elem, cur, curValue, clazz, j, finalValue,
+                       i = 0;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each( function( j ) {
+                               jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
+                       } );
+               }
+
+               if ( typeof value === "string" && value ) {
+                       classes = value.match( rnothtmlwhite ) || [];
+
+                       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 ( jQuery.isFunction( value ) ) {
+                       return this.each( function( j ) {
+                               jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
+                       } );
+               }
+
+               if ( !arguments.length ) {
+                       return this.attr( "class", "" );
+               }
+
+               if ( typeof value === "string" && value ) {
+                       classes = value.match( rnothtmlwhite ) || [];
+
+                       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;
+
+               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, getClass( this ), stateVal ),
+                                       stateVal
+                               );
+                       } );
+               }
+
+               return this.each( function() {
+                       var className, i, self, classNames;
+
+                       if ( type === "string" ) {
+
+                               // Toggle individual class names
+                               i = 0;
+                               self = jQuery( this );
+                               classNames = value.match( rnothtmlwhite ) || [];
+
+                               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, 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;
+
+                               // 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;
+               }
+
+               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 ( 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
+
+
+var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
+
+jQuery.extend( jQuery.event, {
+
+       trigger: function( event, data, elem, onlyHandlers ) {
+
+               var i, cur, tmp, bubbleType, ontype, handle, special,
+                       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( "." ) > -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 && !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 = ( 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 && jQuery.isFunction( 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;
+                                       elem[ type ]();
+                                       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 );
+               }
+       }
+} );
+
+
+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 );
+       }
+} );
+
+
+
+
+support.focusin = "onfocusin" in window;
+
+
+// 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 = jQuery.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 && 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, valueOrFunction ) {
+
+                       // If value is a function, invoke it and use its return value
+                       var value = jQuery.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 ( jQuery.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 - 13
+                       // 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, append data to url
+                       if ( s.data ) {
+                               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 ( jQuery.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 ( jQuery.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 ( 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( 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.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 = 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 = 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() {
+
+                       // 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 && jQuery.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 ( 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.
+                       // 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 ( jQuery.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: function( options ) {
+
+               // Preserve chaining for setter
+               if ( arguments.length ) {
+                       return options === undefined ?
+                               this :
+                               this.each( function( i ) {
+                                       jQuery.offset.setOffset( this, options, i );
+                               } );
+               }
+
+               var doc, docElem, 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 };
+               }
+
+               rect = elem.getBoundingClientRect();
+
+               doc = elem.ownerDocument;
+               docElem = doc.documentElement;
+               win = doc.defaultView;
+
+               return {
+                       top: rect.top + win.pageYOffset - docElem.clientTop,
+                       left: rect.left + win.pageXOffset - docElem.clientLeft
+               };
+       },
+
+       position: function() {
+               if ( !this[ 0 ] ) {
+                       return;
+               }
+
+               var offsetParent, offset,
+                       elem = this[ 0 ],
+                       parentOffset = { top: 0, left: 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" ) {
+
+                       // Assume getBoundingClientRect is there when computed position is fixed
+                       offset = elem.getBoundingClientRect();
+
+               } else {
+
+                       // Get *real* offsetParent
+                       offsetParent = this.offsetParent();
+
+                       // Get correct offsets
+                       offset = this.offset();
+                       if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
+                               parentOffset = offsetParent.offset();
+                       }
+
+                       // Add offsetParent borders
+                       parentOffset = {
+                               top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ),
+                               left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "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 ( jQuery.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 ( jQuery.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.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 );
+       }
+} );
+
+jQuery.holdReady = function( hold ) {
+       if ( hold ) {
+               jQuery.readyWait++;
+       } else {
+               jQuery.ready( true );
+       }
+};
+jQuery.isArray = Array.isArray;
+jQuery.parseJSON = JSON.parse;
+jQuery.nodeName = nodeName;
+
+
+
+
+// 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 c9834f0..f6a9c54 100644 (file)
@@ -20,7 +20,9 @@
                var editBox, scrollTop, $editForm;
 
                // Make sure edit summary does not exceed byte limit
-               $( '#wpSummary' ).byteLimit( 255 );
+               // TODO: Replace with this when $wgOOUIEditPage is removed:
+               // OO.ui.infuse( 'wpSummary' ).$input.byteLimit( 255 );
+               $( 'input#wpSummary, #wpSummary > input' ).byteLimit( 255 );
 
                // Restore the edit box scroll state following a preview operation,
                // and set up a form submission handler to remember this state.
index d228236..8287264 100644 (file)
        min-height: 5em;
 }
 
+/*
+ * Add a bit of margin space between the preview and the toolbar.
+ * This replaces the ugly <p><br /></p> we used to insert into the page source
+ */
+#wikiPreview.ontop {
+       margin-bottom: 1em;
+}
+
 /* Adjustments to edit form elements */
-.editCheckboxes {
+#editpage-copywarn {
+       font-size: 0.9em;
+}
+
+#wpSummary {
+       display: block;
+       width: 80%;
        margin-bottom: 1em;
 }
 
-.editCheckboxes input:first-child {
-       margin-left: 0;
+/* Adjustments to edit form elements (only when $wgOOUIEditPage is false) */
+.mw-editform-legacy .editCheckboxes {
+       margin-bottom: 1em;
 }
 
-.cancelLink {
-       margin-left: 0.5em;
+.mw-editform-legacy .editCheckboxes input:first-child {
+       margin-left: 0;
 }
 
-#editpage-copywarn {
-       font-size: 0.9em;
+.mw-editform-legacy .cancelLink {
+       margin-left: 0.5em;
 }
 
-input#wpSummary {
-       display: block;
+.mw-editform-legacy input#wpSummary {
        background-color: #fff;
        color: #000;
-       width: 80%;
        margin-top: 0;
-       margin-bottom: 1em;
        padding: 0.625em 0.546875em 0.546875em;
        border: 1px solid #a2a9b1;
        border-radius: 2px;
@@ -47,21 +59,43 @@ input#wpSummary {
        transition: border-color 200ms cubic-bezier( 0.39, 0.575, 0.565, 1 ), box-shadow 200ms cubic-bezier( 0.39, 0.575, 0.565, 1 );
 }
 
-input#wpSummary:focus,
-input#wpSummary:active {
+.mw-editform-legacy input#wpSummary:focus,
+.mw-editform-legacy input#wpSummary:active {
        outline: 0;
        border-color: #36c;
        box-shadow: inset 0 0 0 1px #36c;
 }
 
-.editButtons input:first-child {
+.mw-editform-legacy .editButtons input:first-child {
        margin-left: 0.1em;
 }
 
-/*
- * Add a bit of margin space between the preview and the toolbar.
- * This replaces the ugly <p><br /></p> we used to insert into the page source
- */
-#wikiPreview.ontop {
-       margin-bottom: 1em;
+/* Adjustments to edit form elements (only when $wgOOUIEditPage is true) */
+.mw-editform-ooui #editpage-copywarn {
+       line-height: 1.26;
+}
+
+.mw-editform-ooui #wpSummary {
+       max-width: none;
+}
+
+.mw-editform-ooui #wpSummaryLabel {
+       margin: 0;
+}
+
+.mw-editform-ooui .editCheckboxes .oo-ui-fieldLayout {
+       margin-right: 1em;
+}
+
+.mw-editform-ooui .editHelp {
+       margin-left: 0.5em;
+       vertical-align: middle;
+}
+
+.mw-editform-ooui .editHelp a {
+       font-weight: bold;
+}
+
+.mw-editform-ooui .editOptions {
+       border-radius: 0 0 2px 2px;
 }
index 2be3bb2..c6d5082 100644 (file)
@@ -21,7 +21,7 @@ textarea {
 }
 
 .editOptions {
-       background-color: #f8f9fa;
+       background-color: #eaecf0;
        border: 1px solid #c8ccd1;
        border-top: 0;
        padding: 1em 1em 1.5em 1em;
index b0c9f91..9edd0bd 100644 (file)
         */
        mw.widgets.ComplexNamespaceInputWidget.prototype.setDisabled = function ( disabled ) {
                mw.widgets.ComplexNamespaceInputWidget.parent.prototype.setDisabled.call( this, disabled );
-               this.namespace.setDisabled( disabled );
-
+               if ( this.namespace ) {
+                       this.namespace.setDisabled( disabled );
+               }
                if ( this.invert ) {
                        this.invert.setDisabled( disabled );
                }
                if ( this.associated ) {
                        this.associated.setDisabled( disabled );
                }
+               return this;
        };
 
 }( jQuery, mediaWiki ) );
index 030fbb0..a01fbde 100644 (file)
         */
        mw.widgets.ComplexTitleInputWidget.prototype.setDisabled = function ( disabled ) {
                mw.widgets.ComplexTitleInputWidget.parent.prototype.setDisabled.call( this, disabled );
-               this.namespace.setDisabled( disabled );
-               this.title.setDisabled( disabled );
+               if ( this.namespace ) {
+                       this.namespace.setDisabled( disabled );
+               }
+
+               if ( this.title ) {
+                       this.title.setDisabled( disabled );
+               }
+               return this;
        };
 
 }( jQuery, mediaWiki ) );
index 08807fb..d172a39 100644 (file)
                                registry[ module ].state = 'executing';
 
                                runScript = function () {
-                                       var script, markModuleReady, nestedAddScript, legacyWait, implicitDependencies,
-                                               // Expand to include dependencies since we have to exclude both legacy modules
-                                               // and their dependencies from the legacyWait (to prevent a circular dependency).
-                                               legacyModules = resolve( mw.config.get( 'wgResourceLoaderLegacyModules', [] ) );
+                                       var script, markModuleReady, nestedAddScript, implicitDependencies, implicitWait;
 
                                        script = registry[ module ].script;
                                        markModuleReady = function () {
                                                } );
                                        };
 
-                                       implicitDependencies = ( $.inArray( module, legacyModules ) !== -1 ) ?
-                                               [] :
-                                               legacyModules;
+                                       implicitDependencies = [];
 
                                        if ( module === 'user' ) {
                                                // Implicit dependency on the site module. Not real dependency because
                                                implicitDependencies.push( 'site' );
                                        }
 
-                                       legacyWait = implicitDependencies.length ?
+                                       implicitWait = implicitDependencies.length ?
                                                mw.loader.using( implicitDependencies ) :
                                                $.Deferred().resolve();
 
-                                       legacyWait.always( function () {
+                                       implicitWait.always( function () {
                                                try {
                                                        if ( Array.isArray( script ) ) {
                                                                nestedAddScript( script, markModuleReady, 0 );
index 7571e26..9893f8c 100644 (file)
@@ -507,8 +507,12 @@ class OutputPageTest extends MediaWikiTestCase {
        /**
         * @dataProvider providePreloadLinkHeaders
         * @covers OutputPage::addLogoPreloadLinkHeaders
+        * @covers ResourceLoaderSkinModule::getLogo
         */
-       public function testPreloadLinkHeaders( $config, $result ) {
+       public function testPreloadLinkHeaders( $config, $result, $baseDir = null ) {
+               if ( $baseDir ) {
+                       $this->setMwGlobals( 'IP', $baseDir );
+               }
                $out = TestingAccessWrapper::newFromObject( $this->newInstance( $config ) );
                $out->addLogoPreloadLinkHeaders();
 
@@ -519,6 +523,7 @@ class OutputPageTest extends MediaWikiTestCase {
                return [
                        [
                                [
+                                       'ResourceBasePath' => '/w',
                                        'Logo' => '/img/default.png',
                                        'LogoHD' => [
                                                '1.5x' => '/img/one-point-five.png',
@@ -533,6 +538,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        ],
                        [
                                [
+                                       'ResourceBasePath' => '/w',
                                        'Logo' => '/img/default.png',
                                        'LogoHD' => false,
                                ],
@@ -540,6 +546,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        ],
                        [
                                [
+                                       'ResourceBasePath' => '/w',
                                        'Logo' => '/img/default.png',
                                        'LogoHD' => [
                                                '2x' => '/img/two-x.png',
@@ -549,6 +556,16 @@ class OutputPageTest extends MediaWikiTestCase {
                                'not all and (min-resolution: 2dppx),' .
                                '</img/two-x.png>;rel=preload;as=image;media=(min-resolution: 2dppx)'
                        ],
+                       [
+                               [
+                                       'ResourceBasePath' => '/w',
+                                       'Logo' => '/w/test.jpg',
+                                       'LogoHD' => false,
+                                       'UploadPath' => '/w/images',
+                               ],
+                               'Link: </w/test.jpg?edcf2>;rel=preload;as=image',
+                               'baseDir' => dirname( __DIR__ ) . '/data/media',
+                       ],
                ];
        }
 
index b95462a..97e9b26 100644 (file)
@@ -28,6 +28,7 @@
 use Wikimedia\Rdbms\TransactionProfiler;
 use Wikimedia\Rdbms\DatabaseDomain;
 use Wikimedia\Rdbms\MySQLMasterPos;
+use Wikimedia\Rdbms\DatabaseMysqlBase;
 
 /**
  * Fake class around abstract class so we can call concrete methods.
index 10bf028..b90b1ad 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 
 use Wikimedia\Rdbms\Blob;
+use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\DatabaseSqlite;
 
 class DatabaseSqliteMock extends DatabaseSqlite {
        private $lastQuery;