Merge "Use a less confusing column alias in findMissingFiles.php"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 24 Sep 2014 22:46:13 +0000 (22:46 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 24 Sep 2014 22:46:13 +0000 (22:46 +0000)
144 files changed:
RELEASE-NOTES-1.24
RELEASE-NOTES-1.25
composer.json
includes/AutoLoader.php
includes/GlobalFunctions.php
includes/Message.php
includes/MovePage.php
includes/OutputPage.php
includes/Sanitizer.php
includes/Setup.php
includes/Title.php
includes/User.php
includes/api/ApiBase.php
includes/api/ApiFormatBase.php
includes/cache/bloom/BloomCacheRedis.php
includes/context/RequestContext.php
includes/db/LoadBalancer.php
includes/db/LoadMonitor.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLMultiSelectField.php
includes/installer/i18n/ia.json
includes/installer/i18n/ksh.json
includes/installer/i18n/nb.json
includes/jobqueue/Job.php
includes/jobqueue/JobQueueDB.php
includes/jobqueue/JobQueueGroup.php
includes/jobqueue/JobRunner.php
includes/libs/CSSJanus.php
includes/libs/CSSMin.php
includes/libs/XmlTypeCheck.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/skins/BaseTemplate.php [new file with mode: 0644]
includes/skins/MediaWikiI18N.php [new file with mode: 0644]
includes/skins/QuickTemplate.php [new file with mode: 0644]
includes/skins/SkinApi.php [new file with mode: 0644]
includes/skins/SkinApiTemplate.php [new file with mode: 0644]
includes/skins/SkinTemplate.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialBlockList.php
includes/specials/SpecialBooksources.php
includes/specials/SpecialEditWatchlist.php
includes/specials/SpecialLinkSearch.php
includes/specials/SpecialListfiles.php
includes/specials/SpecialListgrouprights.php
includes/specials/SpecialUserlogin.php
includes/upload/UploadBase.php
languages/Language.php
languages/i18n/af.json
languages/i18n/an.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/de.json
languages/i18n/diq.json
languages/i18n/egl.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/ga.json
languages/i18n/gd.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/ka.json
languages/i18n/ksh.json
languages/i18n/ku-latn.json
languages/i18n/ky.json
languages/i18n/lb.json
languages/i18n/lrc.json
languages/i18n/lv.json
languages/i18n/mg.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/ms.json
languages/i18n/mt.json
languages/i18n/nap.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/pl.json
languages/i18n/pms.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/ru.json
languages/i18n/sc.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/ug-arab.json
languages/i18n/uk.json
languages/i18n/vi.json
languages/i18n/wa.json
languages/i18n/yi.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
maintenance/dictionary/mediawiki.dic
maintenance/mwdoc-filter.php
resources/lib/oojs-ui/i18n/sr-el.json
resources/lib/oojs-ui/i18n/zh-hant.json
resources/lib/oojs-ui/oojs-ui-apex.css
resources/lib/oojs-ui/oojs-ui-minerva.css
resources/lib/oojs-ui/oojs-ui.js
resources/lib/oojs-ui/oojs-ui.svg.css
resources/src/mediawiki.api/mediawiki.api.js
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.ui/components/checkbox.less
tests/parser/preprocess/All_system_messages.expected
tests/parser/preprocess/All_system_messages.txt
tests/parserTests.php
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/data/less/module/styles.css
tests/phpunit/includes/HttpTest.php
tests/phpunit/includes/MessageTest.php
tests/phpunit/includes/MovePageTest.php [new file with mode: 0644]
tests/phpunit/includes/jobqueue/JobTest.php [new file with mode: 0644]
tests/phpunit/includes/libs/CSSJanusTest.php
tests/phpunit/includes/libs/CSSMinTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderTest.php
tests/phpunit/includes/search/SearchEngineTest.php
tests/phpunit/includes/upload/UploadBaseTest.php
tests/qunit/suites/resources/mediawiki.api/mediawiki.api.test.js
thumb.php

index 8733f94..43e0ae5 100644 (file)
@@ -350,6 +350,12 @@ production.
   * ApiFormatWddx
   * ApiFormatYaml
   * ApiTokens
+* The following class constants have been deprecated and may be removed in a
+  future release:
+  * ApiBase::PROP_ROOT
+  * ApiBase::PROP_LIST
+  * ApiBase::PROP_TYPE
+  * ApiBase::PROP_NULLABLE
 
 === Languages updated in 1.24 ===
 
index c8bea32..9dbf896 100644 (file)
@@ -14,7 +14,11 @@ production.
 
 === Bug fixes in 1.25 ===
 
-=== Web API changes in 1.25 ===
+=== Action API changes in 1.25 ===
+* (bug 65403) XML tag highlighting is now only performed for formats
+  "xmlfm" and "wddxfm".
+
+=== Action API internal changes in 1.25 ===
 
 === Languages updated in 1.25 ===
 
@@ -25,7 +29,7 @@ changes to languages because of Bugzilla reports.
 === Other changes in 1.25 ===
 * The skin autodiscovery mechanism, deprecated in MediaWiki 1.23, has been
   removed. See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for
-  migration guide for creators and users of custom skins that relied on it. 
+  migration guide for creators and users of custom skins that relied on it.
 * Javascript variable 'wgFileCanRotate' now only available on Special:Upload.
 * (bug 56257) Set site logo url in ResourceLoaderSiteModule instead of inline
   styles in the HTML output.
index 8389f00..3b18933 100644 (file)
                "ext-wikidiff2": "*",
                "ext-apc": "*",
                "monolog/monolog": "*"
+       },
+       "autoload": {
+               "psr-0": {
+                       "ComposerHookHandler": "includes/composer"
+               }
+       },
+       "scripts": {
+               "pre-update-cmd": "ComposerHookHandler::onPreUpdate",
+               "pre-install-cmd": "ComposerHookHandler::onPreInstall"
        }
 }
index 6b0daa1..3e36712 100644 (file)
@@ -945,10 +945,12 @@ $wgAutoloadLocalClasses = array(
        'SiteStore' => 'includes/site/SiteStore.php',
 
        # includes/skins
-       'BaseTemplate' => 'includes/skins/SkinTemplate.php',
-       'MediaWikiI18N' => 'includes/skins/SkinTemplate.php',
-       'QuickTemplate' => 'includes/skins/SkinTemplate.php',
+       'BaseTemplate' => 'includes/skins/BaseTemplate.php',
+       'MediaWikiI18N' => 'includes/skins/MediaWikiI18N.php',
+       'QuickTemplate' => 'includes/skins/QuickTemplate.php',
        'Skin' => 'includes/skins/Skin.php',
+       'SkinApi' => 'includes/skins/SkinApi.php',
+       'SkinApiTemplate' => 'includes/skins/SkinApiTemplate.php',
        'SkinException' => 'includes/skins/SkinException.php',
        'SkinFactory' => 'includes/skins/SkinFactory.php',
        'SkinFallback' => 'includes/skins/SkinFallback.php',
index 490df24..3306acd 100644 (file)
@@ -3761,11 +3761,18 @@ function wfGetNull() {
  * @param float|null $ifWritesSince Only wait if writes were done since this UNIX timestamp
  * @param string|bool $wiki Wiki identifier accepted by wfGetLB
  * @param string|bool $cluster Cluster name accepted by LBFactory. Default: false.
+ * @param int|null $timeout Max wait time. Default: 1 day (cli), ~10 seconds (web)
  * @return bool Success (able to connect and no timeouts reached)
  */
-function wfWaitForSlaves( $ifWritesSince = false, $wiki = false, $cluster = false ) {
+function wfWaitForSlaves(
+       $ifWritesSince = null, $wiki = false, $cluster = false, $timeout = null
+) {
        // B/C: first argument used to be "max seconds of lag"; ignore such values
-       $ifWritesSince = ( $ifWritesSince > 1e9 ) ? $ifWritesSince : false;
+       $ifWritesSince = ( $ifWritesSince > 1e9 ) ? $ifWritesSince : null;
+
+       if ( $timeout === null ) {
+               $timeout = ( PHP_SAPI === 'cli' ) ? 86400 : 10;
+       }
 
        if ( $cluster !== false ) {
                $lb = wfGetLBFactory()->getExternalLB( $cluster );
@@ -3787,7 +3794,7 @@ function wfWaitForSlaves( $ifWritesSince = false, $wiki = false, $cluster = fals
                // The DBMS may not support getMasterPos() or the whole
                // load balancer might be fake (e.g. $wgAllDBsAreLocalhost).
                if ( $pos !== false ) {
-                       return $lb->waitForAll( $pos, PHP_SAPI === 'cli' ? 86400 : null );
+                       return $lb->waitForAll( $pos, $timeout );
                }
        }
 
index 4df0d80..59c5120 100644 (file)
@@ -674,11 +674,10 @@ class Message {
                $string = $this->fetchMessage();
 
                if ( $string === false ) {
-                       $key = htmlspecialchars( $this->key );
-                       if ( $this->format === 'plain' ) {
-                               return '<' . $key . '>';
+                       if ( $this->format === 'plain' || $this->format === 'text' ) {
+                               return '<' . $this->key . '>';
                        }
-                       return '&lt;' . $key . '&gt;';
+                       return '&lt;' . htmlspecialchars( $this->key ) . '&gt;';
                }
 
                # Replace $* with a list of parameters for &uselang=qqx.
@@ -735,10 +734,10 @@ class Message {
                                // Doh! Cause a fatal error after all?
                        }
 
-                       if ( $this->format === 'plain' ) {
+                       if ( $this->format === 'plain' || $this->format === 'text' ) {
                                return '<' . $this->key . '>';
                        }
-                       return '&lt;' . $this->key . '&gt;';
+                       return '&lt;' . htmlspecialchars( $this->key ) . '&gt;';
                }
        }
 
index fdece8d..cea91d2 100644 (file)
@@ -42,6 +42,90 @@ class MovePage {
                $this->newTitle = $newTitle;
        }
 
+       /**
+        * Does various sanity checks that the move is
+        * valid. Only things based on the two titles
+        * should be checked here.
+        *
+        * @return Status
+        */
+       public function isValidMove() {
+               global $wgContentHandlerUseDB;
+               $status = new Status();
+
+               if ( $this->oldTitle->equals( $this->newTitle ) ) {
+                       $status->fatal( 'selfmove' );
+               }
+               if ( !$this->oldTitle->isMovable() ) {
+                       $status->fatal( 'immobile-source-namespace', $this->oldTitle->getNsText() );
+               }
+               if ( $this->newTitle->isExternal() ) {
+                       $status->fatal( 'immobile-target-namespace-iw' );
+               }
+               if ( !$this->newTitle->isMovable() ) {
+                       $status->fatal( 'immobile-target-namespace', $this->newTitle->getNsText() );
+               }
+
+               $oldid = $this->oldTitle->getArticleID();
+
+               if ( strlen( $this->newTitle->getDBkey() ) < 1 ) {
+                       $errors[] = array( 'articleexists' );
+               }
+               if (
+                       ( $this->oldTitle->getDBkey() == '' ) ||
+                       ( !$oldid ) ||
+                       ( $this->newTitle->getDBkey() == '' )
+               ) {
+                       $errors[] = array( 'badarticleerror' );
+               }
+
+               // Content model checks
+               if ( !$wgContentHandlerUseDB &&
+                       $this->oldTitle->getContentModel() !== $this->newTitle->getContentModel() ) {
+                       // can't move a page if that would change the page's content model
+                       $status->fatal(
+                               'bad-target-model',
+                               ContentHandler::getLocalizedName( $this->oldTitle->getContentModel() ),
+                               ContentHandler::getLocalizedName( $this->newTitle->getContentModel() )
+                       );
+               }
+
+               // Image-specific checks
+               if ( $this->oldTitle->inNamespace( NS_FILE ) ) {
+                       $status->merge( $this->isValidFileMove() );
+               }
+
+               if ( $this->newTitle->inNamespace( NS_FILE ) && !$this->oldTitle->inNamespace( NS_FILE ) ) {
+                       $status->fatal( 'nonfile-cannot-move-to-file' );
+               }
+
+               return $status;
+       }
+
+       /**
+        * Sanity checks for when a file is being moved
+        *
+        * @return Status
+        */
+       protected function isValidFileMove() {
+               $status = new Status();
+               $file = wfLocalFile( $this->oldTitle );
+               if ( $file->exists() ) {
+                       if ( $this->newTitle->getText() != wfStripIllegalFilenameChars( $this->newTitle->getText() ) ) {
+                               $status->fatal( 'imageinvalidfilename' );
+                       }
+                       if ( !File::checkExtensionCompatibility( $file, $this->newTitle->getDBkey() ) ) {
+                               $status->fatal( 'imagetypemismatch' );
+                       }
+               }
+
+               if ( !$this->newTitle->inNamespace( NS_FILE ) ) {
+                       $status->fatal( 'imagenocrossnamespace' );
+               }
+
+               return $status;
+       }
+
        /**
         * @param User $user
         * @param string $reason
index 22a6012..3321747 100644 (file)
@@ -3520,8 +3520,6 @@ $templates
                if ( $flip === 'flip' && $this->getLanguage()->isRTL() ) {
                        # If wanted, and the interface is right-to-left, flip the CSS
                        $style_css = CSSJanus::transform( $style_css, true, false );
-               } else {
-                       $style_css = CSSJanus::nullTransform( $style_css );
                }
                $this->mInlineStyles .= Html::inlineStyle( $style_css ) . "\n";
        }
@@ -3572,8 +3570,6 @@ $templates
                        $previewedCSS = $this->getRequest()->getText( 'wpTextbox1' );
                        if ( $this->getLanguage()->getDir() !== $wgContLang->getDir() ) {
                                $previewedCSS = CSSJanus::transform( $previewedCSS, true, false );
-                       } else {
-                               $previewedCSS = CSSJanus::nullTransform( $previewedCSS );
                        }
                        $otherTags .= Html::inlineStyle( $previewedCSS ) . "\n";
                } else {
index ce70047..bca2f67 100644 (file)
@@ -832,24 +832,16 @@ class Sanitizer {
        }
 
        /**
-        * Pick apart some CSS and check it for forbidden or unsafe structures.
-        * Returns a sanitized string. This sanitized string will have
-        * character references and escape sequences decoded and comments
-        * stripped (unless it is itself one valid comment, in which case the value
-        * will be passed through). If the input is just too evil, only a comment
-        * complaining about evilness will be returned.
-        *
-        * Currently URL references, 'expression', 'tps' are forbidden.
-        *
-        * NOTE: Despite the fact that character references are decoded, the
-        * returned string may contain character references given certain
-        * clever input strings. These character references must
-        * be escaped before the return value is embedded in HTML.
-        *
-        * @param string $value
-        * @return string
+        * Normalize CSS into a format we can easily search for hostile input
+        *  - decode character references
+        *  - decode escape sequences
+        *  - convert characters that IE6 interprets into ascii
+        *  - remove comments, unless the entire value is one single comment
+        * @param string $value the css string
+        * @return string normalized css
         */
-       static function checkCss( $value ) {
+       public static function normalizeCss( $value ) {
+
                // Decode character references like &#123;
                $value = Sanitizer::decodeCharReferences( $value );
 
@@ -935,6 +927,31 @@ class Sanitizer {
                        $value
                );
 
+               return $value;
+       }
+
+
+       /**
+        * Pick apart some CSS and check it for forbidden or unsafe structures.
+        * Returns a sanitized string. This sanitized string will have
+        * character references and escape sequences decoded and comments
+        * stripped (unless it is itself one valid comment, in which case the value
+        * will be passed through). If the input is just too evil, only a comment
+        * complaining about evilness will be returned.
+        *
+        * Currently URL references, 'expression', 'tps' are forbidden.
+        *
+        * NOTE: Despite the fact that character references are decoded, the
+        * returned string may contain character references given certain
+        * clever input strings. These character references must
+        * be escaped before the return value is embedded in HTML.
+        *
+        * @param string $value
+        * @return string
+        */
+       static function checkCss( $value ) {
+               $value = self::normalizeCss( $value );
+
                // Reject problematic keywords and control characters
                if ( preg_match( '/[\000-\010\013\016-\037\177]/', $value ) ) {
                        return '/* invalid control char */';
index 7a89c7a..743936e 100644 (file)
@@ -289,8 +289,13 @@ call_user_func( function () use ( $wgValidSkinNames ) {
        $factory->register( 'fallback', 'Fallback', function () {
                return new SkinFallback;
        } );
+       // Register a hidden skin for api output
+       $factory->register( 'apioutput', 'ApiOutput', function () {
+               return new SkinApi;
+       } );
 } );
 $wgSkipSkins[] = 'fallback';
+$wgSkipSkins[] = 'apioutput';
 
 if ( $wgLocalInterwiki ) {
        array_unshift( $wgLocalInterwikis, $wgLocalInterwiki );
index 74d78ba..e8cda85 100644 (file)
@@ -3589,7 +3589,7 @@ class Title {
         * Check whether a given move operation would be valid.
         * Returns true if ok, or a getUserPermissionsErrors()-like array otherwise
         *
-        * @todo move this into MovePage
+        * @todo finish moving this into MovePage
         * @param Title $nt The new title
         * @param bool $auth Indicates whether $wgUser's permissions
         *  should be checked
@@ -3597,60 +3597,18 @@ class Title {
         * @return array|bool True on success, getUserPermissionsErrors()-like array on failure
         */
        public function isValidMoveOperation( &$nt, $auth = true, $reason = '' ) {
-               global $wgUser, $wgContentHandlerUseDB;
+               global $wgUser;
 
-               $errors = array();
-               if ( !$nt ) {
+               if ( !( $nt instanceof Title ) ) {
                        // Normally we'd add this to $errors, but we'll get
                        // lots of syntax errors if $nt is not an object
                        return array( array( 'badtitletext' ) );
                }
-               if ( $this->equals( $nt ) ) {
-                       $errors[] = array( 'selfmove' );
-               }
-               if ( !$this->isMovable() ) {
-                       $errors[] = array( 'immobile-source-namespace', $this->getNsText() );
-               }
-               if ( $nt->isExternal() ) {
-                       $errors[] = array( 'immobile-target-namespace-iw' );
-               }
-               if ( !$nt->isMovable() ) {
-                       $errors[] = array( 'immobile-target-namespace', $nt->getNsText() );
-               }
-
-               $oldid = $this->getArticleID();
-               $newid = $nt->getArticleID();
-
-               if ( strlen( $nt->getDBkey() ) < 1 ) {
-                       $errors[] = array( 'articleexists' );
-               }
-               if (
-                       ( $this->getDBkey() == '' ) ||
-                       ( !$oldid ) ||
-                       ( $nt->getDBkey() == '' )
-               ) {
-                       $errors[] = array( 'badarticleerror' );
-               }
-
-               // Content model checks
-               if ( !$wgContentHandlerUseDB &&
-                               $this->getContentModel() !== $nt->getContentModel() ) {
-                       // can't move a page if that would change the page's content model
-                       $errors[] = array(
-                               'bad-target-model',
-                               ContentHandler::getLocalizedName( $this->getContentModel() ),
-                               ContentHandler::getLocalizedName( $nt->getContentModel() )
-                       );
-               }
 
-               // Image-specific checks
-               if ( $this->getNamespace() == NS_FILE ) {
-                       $errors = array_merge( $errors, $this->validateFileMoveOperation( $nt ) );
-               }
+               $mp = new MovePage( $this, $nt );
+               $errors = $mp->isValidMove()->getErrorsArray();
 
-               if ( $nt->getNamespace() == NS_FILE && $this->getNamespace() != NS_FILE ) {
-                       $errors[] = array( 'nonfile-cannot-move-to-file' );
-               }
+               $newid = $nt->getArticleID();
 
                if ( $auth ) {
                        $errors = wfMergeErrorArrays( $errors,
@@ -3700,6 +3658,7 @@ class Title {
 
        /**
         * Check if the requested move target is a valid file move target
+        * @todo move this to MovePage
         * @param Title $nt Target title
         * @return array List of errors
         */
@@ -3708,27 +3667,6 @@ class Title {
 
                $errors = array();
 
-               // wfFindFile( $nt ) / wfLocalFile( $nt ) is not allowed until below
-
-               $file = wfLocalFile( $this );
-               if ( $file->exists() ) {
-                       if ( $nt->getText() != wfStripIllegalFilenameChars( $nt->getText() ) ) {
-                               $errors[] = array( 'imageinvalidfilename' );
-                       }
-                       if ( !File::checkExtensionCompatibility( $file, $nt->getDBkey() ) ) {
-                               $errors[] = array( 'imagetypemismatch' );
-                       }
-               }
-
-               if ( $nt->getNamespace() != NS_FILE ) {
-                       $errors[] = array( 'imagenocrossnamespace' );
-                       // From here we want to do checks on a file object, so if we can't
-                       // create one, we must return.
-                       return $errors;
-               }
-
-               // wfFindFile( $nt ) / wfLocalFile( $nt ) is allowed below here
-
                $destFile = wfLocalFile( $nt );
                if ( !$wgUser->isAllowed( 'reupload-shared' ) && !$destFile->exists() && wfFindFile( $nt ) ) {
                        $errors[] = array( 'file-exists-sharedrepo' );
@@ -3899,6 +3837,7 @@ class Title {
         * Checks if $this can be moved to a given Title
         * - Selects for update, so don't call it unless you mean business
         *
+        * @todo move to MovePage
         * @param Title $nt The new title to check
         * @return bool
         */
index 635b1e9..9897013 100644 (file)
@@ -357,21 +357,14 @@ class User implements IDBAccessObject {
         * @return bool False if the ID does not exist, true otherwise
         */
        public function loadFromId() {
-               global $wgMemc;
                if ( $this->mId == 0 ) {
                        $this->loadDefaults();
                        return false;
                }
 
                // Try cache
-               $key = wfMemcKey( 'user', 'id', $this->mId );
-               $data = $wgMemc->get( $key );
-               if ( !is_array( $data ) || $data['mVersion'] != self::VERSION ) {
-                       // Object is expired, load from DB
-                       $data = false;
-               }
-
-               if ( !$data ) {
+               $cache = $this->loadFromCache();
+               if ( !$cache ) {
                        wfDebug( "User: cache miss for user {$this->mId}\n" );
                        // Load from DB
                        if ( !$this->loadFromDatabase() ) {
@@ -379,12 +372,6 @@ class User implements IDBAccessObject {
                                return false;
                        }
                        $this->saveToCache();
-               } else {
-                       wfDebug( "User: got user {$this->mId} from cache\n" );
-                       // Restore from cache
-                       foreach ( self::$mCacheVars as $name ) {
-                               $this->$name = $data[$name];
-                       }
                }
 
                $this->mLoadedItems = true;
@@ -392,6 +379,37 @@ class User implements IDBAccessObject {
                return true;
        }
 
+       /**
+        * Load user data from shared cache, given mId has already been set.
+        *
+        * @return bool false if the ID does not exist or data is invalid, true otherwise
+        * @since 1.25
+        */
+       public function loadFromCache() {
+               global $wgMemc;
+
+               if ( $this->mId == 0 ) {
+                       $this->loadDefaults();
+                       return false;
+               }
+
+               $key = wfMemcKey( 'user', 'id', $this->mId );
+               $data = $wgMemc->get( $key );
+               if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) {
+                       // Object is expired
+                       return false;
+               }
+
+               wfDebug( "User: got user {$this->mId} from cache\n" );
+
+               // Restore from cache
+               foreach ( self::$mCacheVars as $name ) {
+                       $this->$name = $data[$name];
+               }
+
+               return true;
+       }
+
        /**
         * Save user data to the shared cache
         */
index eafa9cc..7bc3f71 100644 (file)
@@ -65,16 +65,6 @@ abstract class ApiBase extends ContextSource {
        // Only applies if TYPE='integer' Use with extreme caution
        const PARAM_RANGE_ENFORCE = 9;
 
-       // Name of property group that is on the root element of the result,
-       // i.e. not part of a list
-       const PROP_ROOT = 'ROOT';
-       // Boolean, is the result multiple items? Defaults to true for query modules,
-       // to false for other modules
-       const PROP_LIST = 'LIST';
-       const PROP_TYPE = 0; // Type of the property, uses same format as PARAM_TYPE
-       // Boolean, can the property be not included in the result? Defaults to false
-       const PROP_NULLABLE = 1;
-
        const LIMIT_BIG1 = 500; // Fast query, std user limit
        const LIMIT_BIG2 = 5000; // Fast query, bot/sysop limit
        const LIMIT_SML1 = 50; // Slow query, std user limit
@@ -2245,6 +2235,15 @@ abstract class ApiBase extends ContextSource {
         * @{
         */
 
+       /// @deprecated since 1.24
+       const PROP_ROOT = 'ROOT';
+       /// @deprecated since 1.24
+       const PROP_LIST = 'LIST';
+       /// @deprecated since 1.24
+       const PROP_TYPE = 0;
+       /// @deprecated since 1.24
+       const PROP_NULLABLE = 1;
+
        /**
         * Formerly returned a string that identifies the version of the extending
         * class. Typically included the class name, the svn revision, timestamp,
index 9165ce8..2a57688 100644 (file)
@@ -278,9 +278,12 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
        protected function formatHTML( $text ) {
                // Escape everything first for full coverage
                $text = htmlspecialchars( $text );
-               // encode all comments or tags as safe blue strings
-               $text = str_replace( '&lt;', '<span style="color:blue;">&lt;', $text );
-               $text = str_replace( '&gt;', '&gt;</span>', $text );
+
+               if ( $this->mFormat === 'XML' || $this->mFormat === 'WDDX' ) {
+                       // encode all comments or tags as safe blue strings
+                       $text = str_replace( '&lt;', '<span style="color:blue;">&lt;', $text );
+                       $text = str_replace( '&gt;', '&gt;</span>', $text );
+               }
 
                // identify requests to api.php
                $text = preg_replace( '#^(\s*)(api\.php\?[^ <\n\t]+)$#m', '\1<a href="\2">\2</a>', $text );
index 212e5e8..583556f 100644 (file)
@@ -328,7 +328,7 @@ LUA;
        }
 
        /**
-        * $param string $to (master/slave)
+        * @param string $to (master/slave)
         * @return RedisConnRef|bool Returns false on failure
         */
        protected function getConnection( $to ) {
@@ -354,6 +354,7 @@ LUA;
                                        return $conn;
                                }
                                unset( $servers[$index] ); // skip next time
+                               $servers = array_values( $servers ); // reindex
                        }
                }
 
index db57371..952af8c 100644 (file)
@@ -140,7 +140,7 @@ class RequestContext implements IContextSource {
                if ( $this->title === null ) {
                        global $wgTitle; # fallback to $wg till we can improve this
                        $this->title = $wgTitle;
-                       wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetCaller() . 'with no title set.' );
+                       wfDebugLog( 'GlobalTitleFail', __METHOD__ . ' called by ' . wfGetCaller() . ' with no title set.' );
                }
 
                return $this->title;
index e517a02..8aa3bdb 100644 (file)
@@ -1128,7 +1128,7 @@ class LoadBalancer {
         * Results are cached for a short time in memcached, and indefinitely in the process cache
         *
         * @param string|bool $wiki
-        * @return array
+        * @return array Map of (server index => seconds)
         */
        function getLagTimes( $wiki = false ) {
                # Try process cache
@@ -1178,7 +1178,7 @@ class LoadBalancer {
 }
 
 /**
- * Helper class to handle automatically marking connectons as reusable (via RAII pattern)
+ * Helper class to handle automatically marking connections as reusable (via RAII pattern)
  * as well handling deferring the actual network connection until the handle is used
  *
  * @ingroup Database
index 7281485..b694a6f 100644 (file)
@@ -48,7 +48,7 @@ interface LoadMonitor {
         * @param array $serverIndexes
         * @param string $wiki
         *
-        * @return array
+        * @return array Map of (server index => seconds)
         */
        public function getLagTimes( $serverIndexes, $wiki );
 }
index d582da3..6589b2a 100644 (file)
@@ -1045,12 +1045,20 @@ class HTMLForm extends ContextSource {
 
        /**
         * Identify that the submit button in the form has a destructive action
-        *
+        * @since 1.24
         */
        public function setSubmitDestructive() {
                $this->mSubmitModifierClass = 'mw-ui-destructive';
        }
 
+       /**
+        * Identify that the submit button in the form has a progressive action
+        * @since 1.25
+        */
+       public function setSubmitProgressive() {
+               $this->mSubmitModifierClass = 'mw-ui-progressive';
+       }
+
        /**
         * Set the text for the submit button to a message
         * @since 1.19
index 1b71ab9..8d28b59 100644 (file)
@@ -59,6 +59,14 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                                        $label
                                );
 
+                               if ( $this->mParent->getConfig()->get( 'UseMediaWikiUIEverywhere' ) ) {
+                                       $checkbox = Html::rawElement(
+                                               'div',
+                                               array( 'class' => 'mw-ui-checkbox' ),
+                                               $checkbox
+                                       );
+                               }
+
                                $html .= ' ' . Html::rawElement(
                                        'div',
                                        array( 'class' => 'mw-htmlform-flatlist-item' ),
index 62afb44..0e8f597 100644 (file)
@@ -47,6 +47,7 @@
        "config-env-good": "Le ambiente ha essite verificate.\nTu pote installar MediaWiki.",
        "config-env-bad": "Le ambiente ha essite verificate.\nTu non pote installar MediaWiki.",
        "config-env-php": "PHP $1 es installate.",
+       "config-env-hhvm": "HHVM $1 es installate.",
        "config-unicode-using-utf8": "utf8_normalize.so per Brion Vibber es usate pro le normalisation Unicode.",
        "config-unicode-using-intl": "Le [http://pecl.php.net/intl extension PECL intl] es usate pro le normalisation Unicode.",
        "config-unicode-pure-php-warning": "'''Aviso''': Le [http://pecl.php.net/intl extension PECL intl] non es disponibile pro exequer le normalisation Unicode; le systema recurre al implementation lente in PHP pur.\nSi tu sito ha un alte volumine de traffico, tu deberea informar te un poco super le [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations normalisation Unicode].",
@@ -55,6 +56,7 @@
        "config-outdated-sqlite": "'''Attention''': tu ha SQLite $1, que es inferior al version minimal requirite, $2. SQLite essera indisponibile.",
        "config-no-fts3": "'''Attention''': SQLite es compilate sin [//sqlite.org/fts3.html modulo FTS3]; functionalitate de recerca non essera disponibile in iste back-end.",
        "config-register-globals-error": "<strong>Error: Le option <code>[http://php.net/register_globals register_globals]</code> de PHP es active.\nIllo debe esser disactivate pro continuar le installation.</strong>\nVide [https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals] pro obtener adjuta sur como facer lo.",
+       "config-magic-quotes-gpc": "<strong>Fatal: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc magic_quotes_gpc] es active!</strong>\nIste option corrumpe le datos entrate de maniera imprevisibile.\nTu non pote installar o usar MediaWiki si iste option non es disactivate.",
        "config-magic-quotes-runtime": "'''Fatal: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime] es active!'''\nIste option corrumpe le entrata de datos imprevisibilemente.\nTu non pote installar o usar MediaWiki si iste option non es disactivate.",
        "config-magic-quotes-sybase": "'''Fatal: [http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-sybase magic_quotes_sybase] es active!'''\nIste option corrumpe le entrata de datos imprevisibilemente.\nTu non pote installar o usar MediaWiki si iste option non es disactivate.",
        "config-mbstring": "'''Fatal: [http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload] es active!'''\nIste option causa errores e pote corrumper datos imprevisibilemente.\nTu non pote installar o usar MediaWiki si iste option non es disactivate.",
@@ -65,6 +67,7 @@
        "config-memory-raised": "Le <code>memory_limit</code> de PHP es $1, elevate a $2.",
        "config-memory-bad": "'''Aviso:''' Le <code>memory_limit</code> de PHP es $1.\nIsto es probabilemente troppo basse.\nLe installation pote faller!",
        "config-ctype": "'''Fatal''': PHP debe esser compilate con supporto pro le [http://www.php.net/manual/en/ctype.installation.php extension Ctype].",
+       "config-iconv": "<strong>Fatal:</strong> PHP debe esser compilate con supporto pro le [http://www.php.net/manual/en/iconv.installation.php extension iconv].",
        "config-json": "'''Fatal:''' PHP ha essite compilate sin supporto de JSON.\nTu debe installar le extension JSON de PHP o le extension [http://pecl.php.net/package/jsonc PECL jsonc] extension ante de installar MediaWiki.\n* Le extension de PHP es includite in Red Hat Enterprise Linux (CentOS) 5 e 6, ma debe esser activate in <code>/etc/php.ini</code> o <code>/etc/php.d/json.ini</code>.\n* Alcun distributiones de Linux liberate post maio 2013 omitte iste extension de PHP, forniente in su loco le extension PECL como <code>php5-json</code> o <code>php-pecl-jsonc</code>.",
        "config-xcache": "[http://xcache.lighttpd.net/ XCache] es installate",
        "config-apc": "[http://www.php.net/apc APC] es installate",
        "config-license-gfdl": "Licentia GNU pro Documentation Libere 1.3 o plus recente",
        "config-license-pd": "Dominio public",
        "config-license-cc-choose": "Seliger un licentia Creative Commons personalisate",
-       "config-license-help": "Multe wikis public pone tote le contributiones sub un [http://freedomdefined.org/Definition/Ia?uselang=ia licentia libere].\nIsto adjuta a crear un senso de proprietate communitari e incoragia le contribution in longe termino.\nIsto non es generalmente necessari pro un wiki private o de interprisa.\n\nSi tu vole poter usar texto de Wikipedia, e si tu vole que Wikipedia pote acceptar texto copiate de tu wiki, tu debe seliger '''Creative Commons Attribution Share Alike'''.\n\nWikipedia usava anteriormente le Licentia GNU pro Documentation Libere (GFDL).\nIste es un licentia valide, ma es difficile a comprender.\nIl es anque difficile reusar le contento licentiate sub GFDL.",
+       "config-license-help": "Multe wikis public pone tote le contributiones sub un [http://freedomdefined.org/Definition/Ia?uselang=ia licentia libere].\nIsto adjuta a crear un senso de proprietate communitari e incoragia le contribution in longe termino.\nIsto non es generalmente necessari pro un wiki private o de interprisa.\n\nSi tu vole poter usar texto de Wikipedia, e si tu vole que Wikipedia pote acceptar texto copiate de tu wiki, tu debe seliger <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia usava anteriormente le Licentia GNU pro Documentation Libere (GFDL).\nIste es un licentia valide, ma es difficile a comprender.\nIl es anque difficile reusar le contento licentiate sub GFDL.",
        "config-email-settings": "Configuration de e-mail",
        "config-enable-email": "Activar le e-mail sortiente",
        "config-enable-email-help": "Si tu vole que e-mail functiona, [http://www.php.net/manual/en/mail.configuration.php le optiones de e-mail de PHP] debe esser configurate correctemente.\nSi tu non vole functiones de e-mail, tu pote disactivar los hic.",
        "config-memcache-badport": "Le numeros de porto de Memcached debe esser inter $1 e $2",
        "config-extensions": "Extensiones",
        "config-extensions-help": "Le extensiones listate hic supra esseva detegite in tu directorio <code>./extensions</code>.\n\nIstes pote requirer additional configuration, ma tu pote activar los ora.",
+       "config-skins": "Apparentias",
+       "config-skins-help": "Hic supra es le lista de apparentias detegite in tu directorio <code>./skins</code>. Tu debe activar al minus un de illos e seliger le predefinite.",
+       "config-skins-use-as-default": "Usar iste apparentia como predefinite",
+       "config-skins-missing": "Nulle apparentia ha essite trovate; MediaWiki usara un apparentia de reserva usque tu installa alcun apparentia complete.",
+       "config-skins-must-enable-some": "Tu debe seliger al minus un apparentia a activar.",
+       "config-skins-must-enable-default": "Le apparentia seligite como predefinite debe esser activate.",
        "config-install-alreadydone": "'''Aviso:''' Il pare que tu ha jam installate MediaWiki e tenta installar lo de novo.\nPer favor continua al proxime pagina.",
        "config-install-begin": "Un clic sur \"{{int:config-continue}}\" comencia le installation de MediaWiki.\nPro facer alterationes, clicca sur \"{{int:config-back}}\".",
        "config-install-step-done": "finite",
        "config-install-stats": "Initialisation del statisticas",
        "config-install-keys": "Generation de claves secrete",
        "config-insecure-keys": "'''Attention:''' {{PLURAL:$2|Un clave|Alcun claves}} secur ($1) generate durante le installation non es completemente secur. Considera cambiar {{PLURAL:$2|lo|los}} manualmente.",
+       "config-install-updates": "Impedir le execution de actualisationes innecessari",
+       "config-install-updates-failed": "<strong>Error:</strong> Le insertion de claves de actualisation in le tabellas ha fallite con le error sequente: $1",
        "config-install-sysop": "Crea conto de usator pro administrator",
        "config-install-subscribe-fail": "Impossibile subscriber a mediawiki-announce: $1",
        "config-install-subscribe-notpossible": "cURL non es installate e <code>allow_url_fopen</code> non es disponibile.",
index 785b2b5..f87389d 100644 (file)
@@ -21,7 +21,7 @@
        "config-no-session": "De Daate för Ding Setzung sinn verschött jejange.\nDonn en dä Dattei <code>php.ini</code> nohloore, ov dä <code lang=\"en\">session.save_path</code> op e zopaß Verzeijschneß zeisch.",
        "config-your-language": "Ding Schprooch:",
        "config-your-language-help": "Donn heh di Shprooch ußsöhke, di dat Enshtallzjuhnsprojramm kalle sull.",
-       "config-wiki-language": "Dem Wiki sing Shprooch:",
+       "config-wiki-language": "Dem Wiki sing Schprohch:",
        "config-wiki-language-help": "Donn heh di Shprooch ußsöhke, di et Wiki shtandattmääßesch kalle sull.",
        "config-back": "← Retuur",
        "config-continue": "Wigger →",
@@ -48,7 +48,7 @@
        "config-env-good": "De Ömjävung es jeprööf.\nDo kanns MediaWiki opsäze.",
        "config-env-bad": "De Ömjävung es jeprööf.\nDo kanns MediaWiki nit opsäze.",
        "config-env-php": "PHP $1 es doh.",
-       "config-env-php-toolow": "PHP $1 es enshtalleert.\nÄvver MediaWiki bruch PHP $2 udder hühter.",
+       "config-env-hhvm": "HHVM $1 es enschtalleerd.",
        "config-unicode-using-utf8": "För et <i lang=\"en\">Unicode</i>-Nommaliseere dom_mer däm <i lang=\"en\">Brion Vibber</i> sing Projramm <code lang=\"en\">utf8_normalize.so</code> nämme.",
        "config-unicode-using-intl": "För et <i lang=\"en\">Unicode</i>-Nommaliseere dom_mer dä [http://pecl.php.net/intl Zohsaz <code lang=\"en\">intl</code> uss em <code lang=\"en\">PECL</code>] nämme.",
        "config-unicode-pure-php-warning": "'''Opjepaß:''' Mer kunnte dä [http://pecl.php.net/intl Zohsaz <code lang=\"en\">intl</code> uss em <code lang=\"en\">PECL</code>] för et <i lang=\"en\">Unicode</i>-Nommaliseere nit fenge. Dröm nämme mer dat eijfache, ävver ärsh lahme, <i lang=\"en\">PHP</i>-Projrammshtöck doför.\nFör jruuße Wikis met vill Metmaachere doht Üsch die Sigg övver et [//www.mediawiki.org/wiki/Special:MyLanguage/Unicode_normalization_considerations <i lang=\"en\">Unicode</i>-Nommaliseere] (es op Änglesch) aanloore.",
@@ -56,7 +56,8 @@
        "config-no-db": "Mer kunnte kei zopaß Daatebangk-Driiverprojamm fenge.\nMer bruche e Daatebangk-Driiverprojamm för PHP. Dat moß enjeresht wääde.\nMer künne met heh dä Daatebangke ömjonn: $1.\n\nWann De nit om eijene Rääshner bes, moß De Dinge <i lang=\"en\">provider</i> bedde, dat hä Der ene zopaß Driiver enresht.\nWann de PHP sellver övversaz häs, donn e Zohjangsprojramm för en Daatebangk enbenge, för e Beishpell met: <code  lang=\"en\">./configure --with-mysql</code>.\nWann De PHP uss enem <i lang=\"en\">Debian</i> udder <i lang=\"en\">Ubuntu</i> Pakätt enjeresht häs, moß De dann och noch et <code lang=\"en\">php5-mysql</code> op Dinge Räschner bränge.",
        "config-outdated-sqlite": "'''Opjepaß:''' <i lang=\"en\">SQLite</i> $1 es enschtaleert. Avver MediaWiki bruch <i lang=\"en\">SQLite</i> $2 udder hühter. <i lang=\"en\">SQLite</i> kann dröm nit enjesaz wääde.",
        "config-no-fts3": "'''Opjepaß:''' De Projramme vum <i lang=\"en\">SQLite</i> sin der ohne et [//sqlite.org/fts3.html FTS3-Modul] övversaz, dröm wääde de Funxjohne för et Söhke fähle.",
-       "config-register-globals": "'''Opjepaß:''' dem PHP singe Schallder <code lang=\"en\">[http://php.net/register_globals register_globals]</code> es enjeschalldt.\n'''Donn dä ußmaache, wann De kann.'''\nMediaWiki löp och esu, dä künnt ävver Sesherheitslöcke opmaache, di mer noch nit jefonge un eruß jemaat hät.",
+       "config-register-globals-error": "<strong>Fähler: dem PHP sing Enschtällong <code>[http://php.net/register_globals register_globals]</code> es aanjeschalldt.\nSe moß ußjeschalldt sin, domet mer heh wigger maache kann.</strong>\nLoor op dä Sigg [https://www.mediawiki.org/wiki/register_globals https://www.mediawiki.org/wiki/register_globals] wi mer se ußschallde kann.",
+       "config-magic-quotes-gpc": "'''Dä!''' Dem PHP singe Schallder <code lang=\"en\">[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-gpc magic_quotes_gpc]</code> es enjeschalldt.\nDä määt enjejovve Daate kapott, un doh draan kam_mer dann nix mieh repareere.\nDomet kam_mer MediaWiki nit ennreeshte un och nit loufe lohße.\nDat heiß, mer moß en affschallde, söns jeiht nix.",
        "config-magic-quotes-runtime": "'''Dä!''' Dem PHP singe Schallder <code lang=\"en\">[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-runtime magic_quotes_runtime]</code> es enjeschalldt.\nDä määt enjejovve Daate kapott, un doh draan kam_mer dann nix mieh repareere.\nDomet kam_mer MediaWiki nit ennreeshte un och nit loufe lohße.\nDat heiß, mer moß en affschallde, söns jeiht nix.",
        "config-magic-quotes-sybase": "'''Dä!''' Dem PHP singe Schallder <code lang=\"en\">[http://www.php.net/manual/en/ref.info.php#ini.magic-quotes-sybase magic_quotes_sybase]</code> es enjeschalldt.\nDä määt enjejovve Daate kapott, un doh draan kam_mer dann nix mieh repareere.\nDomet kam_mer MediaWiki nit ennreeshte un och nit loufe lohße.\nDat heiß, mer moß en affschallde, söns jeiht nix.",
        "config-mbstring": "'''Dä!''' Dem PHP singe Schallder <code lang=\"en\">[http://www.php.net/manual/en/ref.mbstring.php#mbstring.overload mbstring.func_overload]</code> es enjeschalldt.\nDat sorresch för Fähler un kann enjejovve Daate esu kapott maach, dat doh draan nix mieh ze repareere es.\nDomet kam_mer MediaWiki nit ennreeshte un och nit loufe lohße.\nDat heiß, mer moß en affschallde, söns jeiht nix.",
@@ -67,6 +68,7 @@
        "config-memory-raised": "Der jrühzte zohjelasse Shpeisherbedarf vum PHP, et <code lang=\"en\">memory_limit</code>, shtund op $1 un es op $2 erop jesaz woode.",
        "config-memory-bad": "'''Opjepaß:''' Dem PHP singe Parameeter <code lang=\"en\">memory_limit</code> es $1.\nDat es wall ze winnisch.\nEt Enreeschte kunnt doh draan kappott jon!",
        "config-ctype": "'''Fähler:''' <i lang=\"en\">PHP</i> moß met dä Ongerschtözong för der [http://www.php.net/manual/en/ctype.installation.php <code lang=\"en\">Ctype</code> Zohsaz] övversaz woode sin.",
+       "config-iconv": "'''Fähler:''' <i lang=\"en\">PHP</i> moß met dä Ongerschtözong för der [http://www.php.net/manual/en/iconv.installation.php <code lang=\"en\">iconv</code> Zohsaz] övversaz woode sin.",
        "config-json": "'''Dä!:''' PHP wood der ohne <i lang=\"en\" xml:lang=\"en\">JSON</i> övversaz.\nJäz moß de äntweeder dä PHP-<i lang=\"en\" xml:lang=\"en\">JSON</i>-Zohsaz enschtallere udder der <i lang=\"en\" xml:lang=\"en\">[http://pecl.php.net/package/jsonc PECL jsonc]</i>-Zohsaz, ih dat de MedijaWikki enschtallere kanns.\n* Dä PHP-Zohsaz es em <i lang=\"en\" xml:lang=\"en\">Red Hat Enterprise Linux (CentOS)</i> 5 un 6 änthallde, moß ävver en de <code lang=\"en\" xml:lang=\"en\">/etc/php.ini</code> udder <code lang=\"en\" xml:lang=\"en\">/etc/php.d/json.ini</code> enjeschalldt wääde.\n* E paa Linux Destrebuzjohne lohß zigg_em Mai 2013 dä PHP-Zohsaz fott un packe doför der PECL-Zohsaz als <code lang=\"en\" xml:lang=\"en\">php5-json</code> udder <code lang=\"en\" xml:lang=\"en\">php-pecl-jsonc</code> med ein.",
        "config-xcache": "Dä <code lang=\"en\">[http://xcache.lighttpd.net/ XCache]</code> es ennjeresht.",
        "config-apc": "Dä <code lang=\"en\">[http://www.php.net/apc APC]</code> es ennjeresht.",
        "config-license-gfdl": "De <i lang=\"en\">GNU</i>-Lizänz för frei Dokemäntazjuhne, Version 1.3 udder en späädere",
        "config-license-pd": "Allmende (jemeinfrei, <i lang=\"en\">public domain</i>)",
        "config-license-cc-choose": "En <i lang=\"en\">Creative Commons</i> Lizänz, sellver ußjesöhk:",
-       "config-license-help": "Ättlijje öffentleje Wikis donn iehr Beidrääsh onger en [http://freedomdefined.org/Definition frei Lizänz] shtelle.\nDat hellef, e Jeföhl vun Jemeinsamkeid opzeboue, un op lange Seesh emmer wider Beidrääsch ze krijje.\nDat es nit onbedengk nüüdesh för e Jeschäffs- udder Privaat_Wiki.\n\nWä Stöcke uß de Wikipedia bruche well, un han well, dat de Wikipedia uss_em eije Wiki jät övvernämme kann, sullt „'''<i lang=\"en\">Creative Commons</i>, dem Schriever singe Name moß jenannt wääde, un Wiggerjävve zoh dersellve Bedengunge es zohjelohße'''“ ußwähle.\n\nDe su jenannte '''<i lang=\"en\">GNU Free Documentation License</i>''' (de freije Lizänz för Dokemäntazjuhne vun dä GNU) sen de ahle Lizänzbedenonge vun de Wikipedia. Se es emmer noch in Odenong un jöltesch, ävver se es schwer ze vershtonn un et Wiggerjävve un widder Verwände es manshmool schwieeresch domet.",
+       "config-license-help": "Ättlijje öffentleje Wikis donn iehr Beidrääsch onger en [http://freedomdefined.org/Definition freije Lizänz] schtelle.\nDat hellef, e Jeföhl vun Jemeinsamkeid opzeboue, un op lange Seesch emmer wider Beidrääsch ze krijje.\nDat es nit onbedengk nüüdesh för e Jeschäffs- udder Privaat_Wiki.\n\nWä Stöcke uß de Wikipedia bruche well, un dröm han well, dat mer för Wikipedia uss_em eije Wiki jät övvernämme kann, sullt „'''<i lang=\"en\">Creative Commons</i>, dem Schriever singe Name moß jenannt wääde, un Wiggerjävve zoh dersellve Bedengunge es zohjelohße'''“ ußwähle.\n\nDe su jenannte '''<i lang=\"en\">GNU Free Documentation License</i>''' (de freije Lizänz för Dokemäntazjuhne vun dä GNU) sen de ahle Lizänzbedenonge vun de Wikipedia. Se es emmer noch in Odenong un jöltesch, ävver se es schwer ze verschtonn un et Wiggerjävve un widder Bruche es ens schwieerejer domet.",
        "config-email-settings": "Enschtellunge för de <i lang=\"en\">e-mail</i>",
        "config-enable-email": "De <i lang=\"en\">e-mail</i> noh druße zohlohße",
        "config-enable-email-help": "Sulle <i lang=\"en\">e-mails</i> zohjelohße sin, moß mer, domet et noher flupp, de [http://www.php.net/manual/en/mail.configuration.php Enschtellunge em PHP för de <i lang=\"en\">e-mails</i>] zopaß jemaat han.\nWann kein <i lang=\"en\">e-mails</i> nüüdesch sin, kam_mer se heh afschallde.",
        "config-memcache-badport": "Dem <code lang=\"en\">memcached</code> ẞööver singe Pooz (<code lang=\"en\">port</code>) Nommere sullte zwesche $1 un $2 sin.",
        "config-extensions": "Projramm-Zohsäz (<i lang=\"en\">Extensions</i>)",
        "config-extensions-help": "Di bovve opjeleß Zohsazprojramme för et MediaWiki sin em Verzeischneß <code lang=\"en\">./extensions</code> ald ze fenge.\n\nDo kann se heh un jez aanschallde, ävver se künnte noch zohsäzlesch Enshtellunge bruche.",
+       "config-skins": "Bedeenbovverfläsche",
+       "config-skins-help": "De opjeleß Beddenbovverfläsche sin en Dingem Verzeischnesß <code>./skins</code> dre. Do moß winneschßdens eine enschallde, un eine för der Schtandatt ußsöhke.",
+       "config-skins-use-as-default": "Donn heh di Bovverfläsch als der Schtandatt nämme.",
+       "config-skins-missing": "Mer han kein bedeebovverfläsche jevonge un nämme dröm der Schtandatt, bes De wälsche enjeresch häß.",
+       "config-skins-must-enable-some": "Do moß winneschßtens ein Beddenbovverfläsch ußsöhke zum aanschallde.",
+       "config-skins-must-enable-default": "De Schtadatt-Beddenbovverfläsch moß och enjeschalldt sin.",
        "config-install-alreadydone": "'''Opjepaß:'''\nEt sühd esu uß, wi wann De MediaWiki ald enshtalleet hätß, un wöhrs aam Versöhke, dat norr_ens ze donn.\nJang wigger op de näähßte Sigg.",
        "config-install-begin": "Wann De op „{{int:config-continue}}“ klecks, jeiht de Enshtallazjuhn vum MediaWiki loßß.\nWann De noch Änderonge maache wells, dann kleck op „{{int:config-back}}“.",
        "config-install-step-done": "jedonn",
        "config-install-stats": "De Shtatestek-Zahle wääde op Aanfang jeshtallt.",
        "config-install-keys": "Jeheime Schlößel wääde opjebout.",
        "config-insecure-keys": "'''Opjepaß:''' {{PLURAL:$2|Ene jeheime Schlößel|Jeheim Schlößele|Keine jeheime Schlößel}} ($1) {{PLURAL:$2|es|sin|es}} automattesch aanjelaat woode. {{PLURAL:$2|Dä es|Di sin|Hä es}} ävver nit onbedengk janz sescher. Övverlääsch Der, {{PLURAL:$2|dä|di|en}} norr_ens vun Hand ze ändere.",
+       "config-install-updates": "Donn kein onnühdeje Änderonge maache.",
+       "config-install-updates-failed": "<strong>Dä:</strong> Schlößßelle för et Ändere en Tabälle  bränge es donävve jajange. Jemäldt wood: $1",
        "config-install-sysop": "Dä Zohjang för der Wiki-Köbes weed aanjelaat.",
        "config-install-subscribe-fail": "Mer künne de <i lang=\"en\">e-mail</i>-Leß <code lang=\"en\">mediawiki-announce</code> nit abonneere: $1",
        "config-install-subscribe-notpossible": "<code lang=\"en\">cURL</code> es nit enstalleed un <code lang=\"en\">allow_url_fopen</code>es nit doh.",
        "config-install-done": "'''Jlöckwonsch!'''\nMediaWiki es jetz enstalleet.\n\nEt Projramm zom Enreeschte hät en Dattei <code lang=\"en\">LocalSettings.php</code> aanjelaat.\nDoh sin de Enstellunge vum Wiki dren.\n\nDo weeß se eronge laade möße un dann en dem Wiki sing Aanfangsverzeishnes donn möße, et sellve Verzeisneß, woh di Dattei <code lang=\"en\">index.php</code> dren litt. Dat Erongerlaade sullt automattesch aanjefange han.\n\nWann domet jet nit jeflupp hät, udder De di Dattei norr_ens han wells, donn op dä Lengk heh dronger klecke:\n\n$3\n\n'''Opjepaß''': Wann De dat jez nit deihß, es alles verschött, wat De bes jöz enjejovve häs, weil di Dattei fott es en däm Momang, woh heh dat Projamm aam Engk es.\n\nWann De mem Ronger- un widder Huhlaade fäädesh bes, kanns De '''[$2 en Ding Wiki jonn]'''.",
        "config-download-localsettings": "Donn di Dattei <code lang=\"en\">LocalSettings.php</code> eronger laade",
        "config-help": "Hölp",
+       "config-help-tooltip": "Donn Hölp heh aan däm Plaaz enblände.",
        "config-nofile": "De Dattei „$1“ ham_mer nit jefonge. Es di fottjeschmeße?",
        "config-extension-link": "Häs De jewoß, dat et Wiki [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions Zohsazprojramme] hann kann?\n\nDo kanns [//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category Zohsazprojramme noh Saachjroppe] söhke udder en de [//www.mediawiki.org/wiki/Extension_Matrix Tabäll met de Zohsazprojramme] kike, öm de kumplätte Leß met de Zohsazprojramme ze krijje.",
        "mainpagetext": "'''MediaWiki es jäz enschtalleht.'''",
index f3cf645..c1bc294 100644 (file)
        "config-subscribe": "Abonner på [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce e-postlisten for utgivelsesannonseringer].",
        "config-subscribe-help": "Dette er en lav-volums e-postliste brukt til utgivelsesannonseringer, herunder viktige sikkerhetsannonseringer.\nDu bør abonnere på den og oppdatere MediaWikiinstallasjonen din når nye versjoner kommer ut.",
        "config-subscribe-noemail": "Du prøvde å abonnere på epost-meldinger om nye versjoner uten å oppgi en epost-adresse. Vær vennlig å oppgi en epost-adresse om du ønsker dette abonnementet.",
-       "config-almost-done": "Du er nesten ferdig!\nDu kan hoppe over de resterende konfigurasjonene og installere wikien nå.",
-       "config-optional-continue": "Spør meg flere spørsmål.",
+       "config-almost-done": "Du er nesten ferdig!\nDu kan velge å hoppe over de siste konfigurasjonstrinnene og installere wikien med en gang.",
+       "config-optional-continue": "Still meg flere spørsmål.",
        "config-optional-skip": "Jeg er lei, bare installer wikien.",
        "config-profile": "Brukerrettighetsprofil:",
        "config-profile-wiki": "Åpen wiki",
        "config-profile-help": "Wikier fungerer best om du lar så mange mennesker som mulig redigere den.\nI MediaWiki er det enkelt å se på de siste endringene og tilbakestille eventuell skade som er gjort av naive eller ondsinnede brukere.\n\nImidlertid har mange funnet at MediaWiki er nyttig for mange formål, og av og til er det ikke lett å overbevise alle om fordelene med wiki-funksjonaliteten.\nSå du har valget.\n\nEn '''{{int:config-profile-wiki}}''' tillater enhver å redigere, selv uten å logge inn.\nEn wiki med '''{{int:config-profile-no-anon}}''' tilbyr ekstra ansvarlighet, men kan avskrekke tilfeldige bidragsytere.\n\n'''{{int:config-profile-fishbowl}}'''-scenariet tillater godkjente brukere å redigere, mens publikum kan se sider, og også historikken.\nEn '''{{int:config-profile-private}}''' tillater kun godkjente brukere å se sider, der den samme gruppen også får lov til å redigere dem.\n\nMer komplekse konfigurasjoner av brukerrettigheter er tilgjengelige etter installasjonen, se [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights relevant avsnitt i brukerbeskrivelsen].",
        "config-license": "Opphavsrett og lisens:",
        "config-license-none": "Ingen lisensbunntekst",
-       "config-license-cc-by-sa": "Creative Commons Navngivelse Del på samme vilkår",
-       "config-license-cc-by": "Creative Commons Attribution",
-       "config-license-cc-by-nc-sa": "Creative Commons Navngivelse Ikke-kommersiell Del på samme vilkår",
-       "config-license-cc-0": "Creative Commons Zero (tilgjengelig for alle)",
+       "config-license-cc-by-sa": "Creative Commons Navngivelse-DelPåSammeVilkår",
+       "config-license-cc-by": "Creative Commons Navngivelse",
+       "config-license-cc-by-nc-sa": "Creative Commons Navngivelse-IkkeKommersiell-DelPåSammeVilkår",
+       "config-license-cc-0": "Creative Commons Zero (Fristatus-erklæring)",
        "config-license-gfdl": "GNU Free Documentation License 1.3 eller senere",
-       "config-license-pd": "Offentlig rom",
+       "config-license-pd": "Offentlig eiendom",
        "config-license-cc-choose": "Velg en egendefinert Creative Commons-lisens",
        "config-license-help": "Mange åpne wikier legger alle bidrag under en [http://freedomdefined.org/Definition gratislisens].\nDette gir en følelse av felleseie og stimulerer til langvarige bidrag.\nDette er normalt unødvendig for en privat eller virksomhetsbegrenset wiki.\n\nHvis du ønsker å kunne bruke tekst fra Wikipedia, og at Wikipedia skal kunne ta i mot tekst kopiert fra din wiki, bør du velge '''Creative Commons Attribution Share Alike'''.\n\nWikipedia brukte tidligere GNU Free Documentation License.\nGFDL er en grei lisens, med vanskelig å forstå.\nDet er også vanskelig å gjenbruke innhold lisensiert under GFDL.",
        "config-email-settings": "E-postinnstillinger",
index ee3f2c2..d89c5d2 100644 (file)
@@ -87,7 +87,7 @@ abstract class Job implements IJobSpecification {
         * This may add duplicate at insert time, but they will be
         * removed later on, when the first one is popped.
         *
-        * @param array $jobs Array of Job objects
+        * @param Job[] $jobs Array of Job objects
         * @return bool
         * @deprecated since 1.21
         */
@@ -103,7 +103,7 @@ abstract class Job implements IJobSpecification {
         * be rolled-back as part of a larger transaction. However,
         * large batches of jobs can cause slave lag.
         *
-        * @param array $jobs Array of Job objects
+        * @param Job[] $jobs Array of Job objects
         * @return bool
         * @deprecated since 1.21
         */
@@ -143,7 +143,7 @@ abstract class Job implements IJobSpecification {
        /**
         * @param string $command
         * @param Title $title
-        * @param array|bool $params
+        * @param array|bool $params Can not be === true
         */
        public function __construct( $command, $title, $params = false ) {
                $this->command = $command;
index 08873cc..056e5a8 100644 (file)
@@ -556,7 +556,7 @@ class JobQueueDB extends JobQueue {
         * @return void
         */
        protected function doWaitForBackups() {
-               wfWaitForSlaves();
+               wfWaitForSlaves( false, $this->wiki, $this->cluster ?: false );
        }
 
        /**
index 98a78c5..b0b35e9 100644 (file)
@@ -104,7 +104,7 @@ class JobQueueGroup {
         * This inserts the jobs into the queue specified by $wgJobTypeConf
         * and updates the aggregate job queue information cache as needed.
         *
-        * @param Job|array $jobs A single Job or a list of Jobs
+        * @param Job|Job[] $jobs A single Job or a list of Jobs
         * @throws MWException
         * @return void
         */
index 8ccceda..e38aa5f 100644 (file)
@@ -76,6 +76,14 @@ class JobRunner {
                        $this->runJobsLog( "Executed $count periodic queue task(s)." );
                }
 
+               // Bail out if there is too much DB lag
+               // @note: getLagTimes() has better caching than getMaxLag()
+               $maxLag = max( wfGetLBFactory()->getMainLB( wfWikiID() )->getLagTimes() );
+               if ( $maxLag >= 5 ) {
+                       $response['reached'] = 'slave-lag-limit';
+                       return $response;
+               }
+
                // Flush any pending DB writes for sanity
                wfGetLBFactory()->commitMasterChanges();
 
@@ -87,8 +95,10 @@ class JobRunner {
                $jobsRun = 0;
                $timeMsTotal = 0;
                $flags = JobQueueGroup::USE_CACHE;
+               $checkPeriod = 5.0; // seconds
+               $checkPhase = mt_rand( 0, 1000 * $checkPeriod ) / 1000; // avoid stampedes
                $startTime = microtime( true ); // time since jobs started running
-               $lastTime = microtime( true ); // time since last slave check
+               $lastTime = microtime( true ) - $checkPhase; // time since last slave check
                do {
                        // Sync the persistent backoffs with concurrent runners
                        $backoffs = $this->syncBackoffDeltas( $backoffs, $backoffDeltas, $wait );
@@ -172,10 +182,15 @@ class JobRunner {
                                        break;
                                }
 
-                               // Don't let any of the main DB slaves get backed up
+                               // Don't let any of the main DB slaves get backed up.
+                               // This only waits for so long before exiting and letting
+                               // other wikis in the farm (on different masters) get a chance.
                                $timePassed = microtime( true ) - $lastTime;
                                if ( $timePassed >= 5 || $timePassed < 0 ) {
-                                       wfWaitForSlaves( $lastTime );
+                                       if ( !wfWaitForSlaves( $lastTime, wfWikiID(), false, 5 ) ) {
+                                               $response['reached'] = 'slave-lag-limit';
+                                               break;
+                                       }
                                        $lastTime = microtime( true );
                                }
                                // Don't let any queue slaves/backups fall behind
index 7b7b407..4cfc9b7 100644 (file)
@@ -174,22 +174,6 @@ class CSSJanus {
                $css = $noFlipClass->detokenize( $css );
                $css = $noFlipSingle->detokenize( $css );
 
-               // Remove remaining /* @noflip */ annotations, they won't be needed anymore
-               // and can interfere with other code (bug 69698).
-               $css = self::nullTransform( $css );
-
-               return $css;
-       }
-
-       /**
-        * Remove @noflip annotations, but don't do any other transforms.
-        * @param string $css stylesheet to transform
-        * @return string Transformed stylesheet
-        */
-       public static function nullTransform( $css ) {
-               $patt = self::$patterns['noflip_annotation'];
-               $css = preg_replace( "/($patt)\\s*/i", '', $css );
-
                return $css;
        }
 
index dcaa685..c69e79f 100644 (file)
@@ -200,10 +200,9 @@ class CSSMin {
                        $remote = substr( $remote, 0, -1 );
                }
 
-               // Replace all comments by a placeholder so they will not interfere
-               // with the remapping
-               // Warning: This will also catch on anything looking like the start of
-               // a comment between quotation marks (e.g. "foo /* bar").
+               // Replace all comments by a placeholder so they will not interfere with the remapping.
+               // Warning: This will also catch on anything looking like the start of a comment between
+               // quotation marks (e.g. "foo /* bar").
                $comments = array();
                $placeholder = uniqid( '', true );
 
@@ -226,12 +225,13 @@ class CSSMin {
 
                $source = preg_replace_callback(
                        $pattern,
-                       function ( $matchOuter ) use ( $local, $remote, $embedData ) {
+                       function ( $matchOuter ) use ( $local, $remote, $embedData, $placeholder ) {
                                $rule = $matchOuter[0];
 
-                               // Check for global @embed comment and remove it
+                               // Check for global @embed comment and remove it. Allow other comments to be present
+                               // before @embed (they have been replaced with placeholders at this point).
                                $embedAll = false;
-                               $rule = preg_replace( '/^(\s*)' . CSSMin::EMBED_REGEX . '\s*/', '$1', $rule, 1, $embedAll );
+                               $rule = preg_replace( '/^((?:\s+|' . $placeholder . '(\d+)x)*)' . CSSMin::EMBED_REGEX . '\s*/', '$1', $rule, 1, $embedAll );
 
                                // Build two versions of current rule: with remapped URLs
                                // and with embedded data: URIs (where possible).
index eb98a4a..aca857e 100644 (file)
@@ -39,6 +39,23 @@ class XmlTypeCheck {
         */
        public $rootElement = '';
 
+       /**
+        * A stack of strings containing the data of each xml element as it's processed. Append
+        * data to the top string of the stack, then pop off the string and process it when the
+        * element is closed.
+        */
+       protected $elementData = array();
+
+       /**
+        * A stack of element names and attributes, as we process them.
+        */
+       protected $elementDataContext = array();
+
+       /**
+        * Current depth of the data stack.
+        */
+       protected $stackDepth = 0;
+
        /**
         * Additional parsing options
         */
@@ -51,7 +68,7 @@ class XmlTypeCheck {
         * @param callable $filterCallback (optional)
         *        Function to call to do additional custom validity checks from the
         *        SAX element handler event. This gives you access to the element
-        *        namespace, name, and attributes, but not to text contents.
+        *        namespace, name, attributes, and text contents.
         *        Filter should return 'true' to toggle on $this->filterMatch
         * @param boolean $isFile (optional) indicates if the first parameter is a
         *        filename (default, true) or if it is a string (false)
@@ -179,7 +196,12 @@ class XmlTypeCheck {
                $this->rootElement = $name;
 
                if ( is_callable( $this->filterCallback ) ) {
-                       xml_set_element_handler( $parser, array( $this, 'elementOpen' ), false );
+                       xml_set_element_handler(
+                               $parser,
+                               array( $this, 'elementOpen' ),
+                               array( $this, 'elementClose' )
+                       );
+                       xml_set_character_data_handler( $parser, array( $this, 'elementData' ) );
                        $this->elementOpen( $parser, $name, $attribs );
                } else {
                        // We only need the first open element
@@ -193,12 +215,41 @@ class XmlTypeCheck {
         * @param $attribs
         */
        private function elementOpen( $parser, $name, $attribs ) {
-               if ( call_user_func( $this->filterCallback, $name, $attribs ) ) {
+               $this->elementDataContext[] = array( $name, $attribs );
+               $this->elementData[] = '';
+               $this->stackDepth++;
+       }
+
+       /**
+        * @param $parser
+        * @param $name
+        */
+       private function elementClose( $parser, $name ) {
+               list( $name, $attribs ) = array_pop( $this->elementDataContext );
+               $data = array_pop( $this->elementData );
+               $this->stackDepth--;
+
+               if ( call_user_func(
+                       $this->filterCallback,
+                       $name,
+                       $attribs,
+                       $data
+               ) ) {
                        // Filter hit!
                        $this->filterMatch = true;
                }
        }
 
+       /**
+        * @param $parser
+        * @param $data
+        */
+       private function elementData( $parser, $data ) {
+               // xml_set_character_data_handler breaks the data on & characters, so
+               // we collect any data here, and we'll run the callback in elementClose
+               $this->elementData[ $this->stackDepth - 1 ] .= trim( $data );
+       }
+
        /**
         * @param $parser
         * @param $target
index 4f1414b..57deb00 100644 (file)
@@ -35,22 +35,32 @@ class ResourceLoader {
        /** @var bool */
        protected static $debugMode = null;
 
-       /** @var array Module name/ResourceLoaderModule object pairs */
+       /**
+        * Module name/ResourceLoaderModule object pairs
+        * @var array
+        */
        protected $modules = array();
 
-       /** @var array Associative array mapping module name to info associative array */
+       /**
+        * Associative array mapping module name to info associative array
+        * @var array
+        */
        protected $moduleInfos = array();
 
        /** @var Config $config */
        private $config;
 
        /**
-        * @var array Associative array mapping framework ids to a list of names of test suite modules
-        *      like array( 'qunit' => array( 'mediawiki.tests.qunit.suites', 'ext.foo.tests', .. ), .. )
+        * Associative array mapping framework ids to a list of names of test suite modules
+        * like array( 'qunit' => array( 'mediawiki.tests.qunit.suites', 'ext.foo.tests', .. ), .. )
+        * @var array
         */
        protected $testModuleNames = array();
 
-       /** @var array E.g. array( 'source-id' => 'http://.../load.php' ) */
+       /**
+        * E.g. array( 'source-id' => 'http://.../load.php' )
+        * @var array
+        */
        protected $sources = array();
 
        /** @var bool */
index 137ff62..dc8b14a 100644 (file)
@@ -870,8 +870,6 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
 
                if ( $flip ) {
                        $style = CSSJanus::transform( $style, true, false );
-               } else {
-                       $style = CSSJanus::nullTransform( $style );
                }
                $localDir = dirname( $localPath );
                $remoteDir = dirname( $remotePath );
index 7abecc7..40274c6 100644 (file)
@@ -83,8 +83,6 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
                $style = implode( "\n", $rules );
                if ( $this->getFlip( $context ) ) {
                        $style = CSSJanus::transform( $style, true, false );
-               } else {
-                       $style = CSSJanus::nullTransform( $style );
                }
                return array( 'all' => $style );
        }
index 2eaca67..99a8739 100644 (file)
@@ -81,9 +81,15 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
         * @return null|string
         */
        protected function getContent( $title ) {
-               if ( !$title->isCssJsSubpage() && !$title->isCssOrJsPage() ) {
+               $handler = ContentHandler::getForTitle( $title );
+               if ( $handler->isSupportedFormat( CONTENT_FORMAT_CSS ) ) {
+                       $format = CONTENT_FORMAT_CSS;
+               } elseif ( $handler->isSupportedFormat( CONTENT_FORMAT_JAVASCRIPT ) ) {
+                       $format = CONTENT_FORMAT_JAVASCRIPT;
+               } else {
                        return null;
                }
+
                $revision = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
                if ( !$revision ) {
                        return null;
@@ -96,14 +102,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        return null;
                }
 
-               if ( $content->isSupportedFormat( CONTENT_FORMAT_JAVASCRIPT ) ) {
-                       return $content->serialize( CONTENT_FORMAT_JAVASCRIPT );
-               } elseif ( $content->isSupportedFormat( CONTENT_FORMAT_CSS ) ) {
-                       return $content->serialize( CONTENT_FORMAT_CSS );
-               } else {
-                       wfDebugLog( 'resourceloader', __METHOD__ . ": bad content model {$content->getModel()} for JS/CSS page!" );
-                       return null;
-               }
+               return $content->serialize( $format );
        }
 
        /* Methods */
@@ -152,8 +151,6 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        }
                        if ( $this->getFlip( $context ) ) {
                                $style = CSSJanus::transform( $style, true, false );
-                       } else {
-                               $style = CSSJanus::nullTransform( $style );
                        }
                        $style = CSSMin::remap( $style, false, $this->getConfig()->get( 'ScriptPath' ), true );
                        if ( !isset( $styles[$media] ) ) {
diff --git a/includes/skins/BaseTemplate.php b/includes/skins/BaseTemplate.php
new file mode 100644 (file)
index 0000000..6dc33ac
--- /dev/null
@@ -0,0 +1,614 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * New base template for a skin's template extended from QuickTemplate
+ * this class features helper methods that provide common ways of interacting
+ * with the data stored in the QuickTemplate
+ */
+abstract class BaseTemplate extends QuickTemplate {
+
+       /**
+        * Get a Message object with its context set
+        *
+        * @param string $name Message name
+        * @return Message
+        */
+       public function getMsg( $name ) {
+               return $this->getSkin()->msg( $name );
+       }
+
+       function msg( $str ) {
+               echo $this->getMsg( $str )->escaped();
+       }
+
+       function msgHtml( $str ) {
+               echo $this->getMsg( $str )->text();
+       }
+
+       function msgWiki( $str ) {
+               echo $this->getMsg( $str )->parseAsBlock();
+       }
+
+       /**
+        * Create an array of common toolbox items from the data in the quicktemplate
+        * stored by SkinTemplate.
+        * The resulting array is built according to a format intended to be passed
+        * through makeListItem to generate the html.
+        * @return array
+        */
+       function getToolbox() {
+               wfProfileIn( __METHOD__ );
+
+               $toolbox = array();
+               if ( isset( $this->data['nav_urls']['whatlinkshere'] )
+                       && $this->data['nav_urls']['whatlinkshere']
+               ) {
+                       $toolbox['whatlinkshere'] = $this->data['nav_urls']['whatlinkshere'];
+                       $toolbox['whatlinkshere']['id'] = 't-whatlinkshere';
+               }
+               if ( isset( $this->data['nav_urls']['recentchangeslinked'] )
+                       && $this->data['nav_urls']['recentchangeslinked']
+               ) {
+                       $toolbox['recentchangeslinked'] = $this->data['nav_urls']['recentchangeslinked'];
+                       $toolbox['recentchangeslinked']['msg'] = 'recentchangeslinked-toolbox';
+                       $toolbox['recentchangeslinked']['id'] = 't-recentchangeslinked';
+               }
+               if ( isset( $this->data['feeds'] ) && $this->data['feeds'] ) {
+                       $toolbox['feeds']['id'] = 'feedlinks';
+                       $toolbox['feeds']['links'] = array();
+                       foreach ( $this->data['feeds'] as $key => $feed ) {
+                               $toolbox['feeds']['links'][$key] = $feed;
+                               $toolbox['feeds']['links'][$key]['id'] = "feed-$key";
+                               $toolbox['feeds']['links'][$key]['rel'] = 'alternate';
+                               $toolbox['feeds']['links'][$key]['type'] = "application/{$key}+xml";
+                               $toolbox['feeds']['links'][$key]['class'] = 'feedlink';
+                       }
+               }
+               foreach ( array( 'contributions', 'log', 'blockip', 'emailuser',
+                       'userrights', 'upload', 'specialpages' ) as $special
+               ) {
+                       if ( isset( $this->data['nav_urls'][$special] ) && $this->data['nav_urls'][$special] ) {
+                               $toolbox[$special] = $this->data['nav_urls'][$special];
+                               $toolbox[$special]['id'] = "t-$special";
+                       }
+               }
+               if ( isset( $this->data['nav_urls']['print'] ) && $this->data['nav_urls']['print'] ) {
+                       $toolbox['print'] = $this->data['nav_urls']['print'];
+                       $toolbox['print']['id'] = 't-print';
+                       $toolbox['print']['rel'] = 'alternate';
+                       $toolbox['print']['msg'] = 'printableversion';
+               }
+               if ( isset( $this->data['nav_urls']['permalink'] ) && $this->data['nav_urls']['permalink'] ) {
+                       $toolbox['permalink'] = $this->data['nav_urls']['permalink'];
+                       if ( $toolbox['permalink']['href'] === '' ) {
+                               unset( $toolbox['permalink']['href'] );
+                               $toolbox['ispermalink']['tooltiponly'] = true;
+                               $toolbox['ispermalink']['id'] = 't-ispermalink';
+                               $toolbox['ispermalink']['msg'] = 'permalink';
+                       } else {
+                               $toolbox['permalink']['id'] = 't-permalink';
+                       }
+               }
+               if ( isset( $this->data['nav_urls']['info'] ) && $this->data['nav_urls']['info'] ) {
+                       $toolbox['info'] = $this->data['nav_urls']['info'];
+                       $toolbox['info']['id'] = 't-info';
+               }
+
+               wfRunHooks( 'BaseTemplateToolbox', array( &$this, &$toolbox ) );
+               wfProfileOut( __METHOD__ );
+               return $toolbox;
+       }
+
+       /**
+        * Create an array of personal tools items from the data in the quicktemplate
+        * stored by SkinTemplate.
+        * The resulting array is built according to a format intended to be passed
+        * through makeListItem to generate the html.
+        * This is in reality the same list as already stored in personal_urls
+        * however it is reformatted so that you can just pass the individual items
+        * to makeListItem instead of hardcoding the element creation boilerplate.
+        * @return array
+        */
+       function getPersonalTools() {
+               $personal_tools = array();
+               foreach ( $this->get( 'personal_urls' ) as $key => $plink ) {
+                       # The class on a personal_urls item is meant to go on the <a> instead
+                       # of the <li> so we have to use a single item "links" array instead
+                       # of using most of the personal_url's keys directly.
+                       $ptool = array(
+                               'links' => array(
+                                       array( 'single-id' => "pt-$key" ),
+                               ),
+                               'id' => "pt-$key",
+                       );
+                       if ( isset( $plink['active'] ) ) {
+                               $ptool['active'] = $plink['active'];
+                       }
+                       foreach ( array( 'href', 'class', 'text', 'dir' ) as $k ) {
+                               if ( isset( $plink[$k] ) ) {
+                                       $ptool['links'][0][$k] = $plink[$k];
+                               }
+                       }
+                       $personal_tools[$key] = $ptool;
+               }
+               return $personal_tools;
+       }
+
+       function getSidebar( $options = array() ) {
+               // Force the rendering of the following portals
+               $sidebar = $this->data['sidebar'];
+               if ( !isset( $sidebar['SEARCH'] ) ) {
+                       $sidebar['SEARCH'] = true;
+               }
+               if ( !isset( $sidebar['TOOLBOX'] ) ) {
+                       $sidebar['TOOLBOX'] = true;
+               }
+               if ( !isset( $sidebar['LANGUAGES'] ) ) {
+                       $sidebar['LANGUAGES'] = true;
+               }
+
+               if ( !isset( $options['search'] ) || $options['search'] !== true ) {
+                       unset( $sidebar['SEARCH'] );
+               }
+               if ( isset( $options['toolbox'] ) && $options['toolbox'] === false ) {
+                       unset( $sidebar['TOOLBOX'] );
+               }
+               if ( isset( $options['languages'] ) && $options['languages'] === false ) {
+                       unset( $sidebar['LANGUAGES'] );
+               }
+
+               $boxes = array();
+               foreach ( $sidebar as $boxName => $content ) {
+                       if ( $content === false ) {
+                               continue;
+                       }
+                       switch ( $boxName ) {
+                       case 'SEARCH':
+                               // Search is a special case, skins should custom implement this
+                               $boxes[$boxName] = array(
+                                       'id' => 'p-search',
+                                       'header' => $this->getMsg( 'search' )->text(),
+                                       'generated' => false,
+                                       'content' => true,
+                               );
+                               break;
+                       case 'TOOLBOX':
+                               $msgObj = $this->getMsg( 'toolbox' );
+                               $boxes[$boxName] = array(
+                                       'id' => 'p-tb',
+                                       'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox',
+                                       'generated' => false,
+                                       'content' => $this->getToolbox(),
+                               );
+                               break;
+                       case 'LANGUAGES':
+                               if ( $this->data['language_urls'] ) {
+                                       $msgObj = $this->getMsg( 'otherlanguages' );
+                                       $boxes[$boxName] = array(
+                                               'id' => 'p-lang',
+                                               'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages',
+                                               'generated' => false,
+                                               'content' => $this->data['language_urls'],
+                                       );
+                               }
+                               break;
+                       default:
+                               $msgObj = $this->getMsg( $boxName );
+                               $boxes[$boxName] = array(
+                                       'id' => "p-$boxName",
+                                       'header' => $msgObj->exists() ? $msgObj->text() : $boxName,
+                                       'generated' => true,
+                                       'content' => $content,
+                               );
+                               break;
+                       }
+               }
+
+               // HACK: Compatibility with extensions still using SkinTemplateToolboxEnd
+               $hookContents = null;
+               if ( isset( $boxes['TOOLBOX'] ) ) {
+                       ob_start();
+                       // We pass an extra 'true' at the end so extensions using BaseTemplateToolbox
+                       // can abort and avoid outputting double toolbox links
+                       wfRunHooks( 'SkinTemplateToolboxEnd', array( &$this, true ) );
+                       $hookContents = ob_get_contents();
+                       ob_end_clean();
+                       if ( !trim( $hookContents ) ) {
+                               $hookContents = null;
+                       }
+               }
+               // END hack
+
+               if ( isset( $options['htmlOnly'] ) && $options['htmlOnly'] === true ) {
+                       foreach ( $boxes as $boxName => $box ) {
+                               if ( is_array( $box['content'] ) ) {
+                                       $content = '<ul>';
+                                       foreach ( $box['content'] as $key => $val ) {
+                                               $content .= "\n " . $this->makeListItem( $key, $val );
+                                       }
+                                       // HACK, shove the toolbox end onto the toolbox if we're rendering itself
+                                       if ( $hookContents ) {
+                                               $content .= "\n $hookContents";
+                                       }
+                                       // END hack
+                                       $content .= "\n</ul>\n";
+                                       $boxes[$boxName]['content'] = $content;
+                               }
+                       }
+               } else {
+                       if ( $hookContents ) {
+                               $boxes['TOOLBOXEND'] = array(
+                                       'id' => 'p-toolboxend',
+                                       'header' => $boxes['TOOLBOX']['header'],
+                                       'generated' => false,
+                                       'content' => "<ul>{$hookContents}</ul>",
+                               );
+                               // HACK: Make sure that TOOLBOXEND is sorted next to TOOLBOX
+                               $boxes2 = array();
+                               foreach ( $boxes as $key => $box ) {
+                                       if ( $key === 'TOOLBOXEND' ) {
+                                               continue;
+                                       }
+                                       $boxes2[$key] = $box;
+                                       if ( $key === 'TOOLBOX' ) {
+                                               $boxes2['TOOLBOXEND'] = $boxes['TOOLBOXEND'];
+                                       }
+                               }
+                               $boxes = $boxes2;
+                               // END hack
+                       }
+               }
+
+               return $boxes;
+       }
+
+       /**
+        * @param string $name
+        */
+       protected function renderAfterPortlet( $name ) {
+               $content = '';
+               wfRunHooks( 'BaseTemplateAfterPortlet', array( $this, $name, &$content ) );
+
+               if ( $content !== '' ) {
+                       echo "<div class='after-portlet after-portlet-$name'>$content</div>";
+               }
+
+       }
+
+       /**
+        * Makes a link, usually used by makeListItem to generate a link for an item
+        * in a list used in navigation lists, portlets, portals, sidebars, etc...
+        *
+        * @param string $key Usually a key from the list you are generating this
+        * link from.
+        * @param array $item Contains some of a specific set of keys.
+        *
+        * The text of the link will be generated either from the contents of the
+        * "text" key in the $item array, if a "msg" key is present a message by
+        * that name will be used, and if neither of those are set the $key will be
+        * used as a message name.
+        *
+        * If a "href" key is not present makeLink will just output htmlescaped text.
+        * The "href", "id", "class", "rel", and "type" keys are used as attributes
+        * for the link if present.
+        *
+        * If an "id" or "single-id" (if you don't want the actual id to be output
+        * on the link) is present it will be used to generate a tooltip and
+        * accesskey for the link.
+        *
+        * The keys "context" and "primary" are ignored; these keys are used
+        * internally by skins and are not supposed to be included in the HTML
+        * output.
+        *
+        * If you don't want an accesskey, set $item['tooltiponly'] = true;
+        *
+        * @param array $options Can be used to affect the output of a link.
+        * Possible options are:
+        *   - 'text-wrapper' key to specify a list of elements to wrap the text of
+        *   a link in. This should be an array of arrays containing a 'tag' and
+        *   optionally an 'attributes' key. If you only have one element you don't
+        *   need to wrap it in another array. eg: To use <a><span>...</span></a>
+        *   in all links use array( 'text-wrapper' => array( 'tag' => 'span' ) )
+        *   for your options.
+        *   - 'link-class' key can be used to specify additional classes to apply
+        *   to all links.
+        *   - 'link-fallback' can be used to specify a tag to use instead of "<a>"
+        *   if there is no link. eg: If you specify 'link-fallback' => 'span' than
+        *   any non-link will output a "<span>" instead of just text.
+        *
+        * @return string
+        */
+       function makeLink( $key, $item, $options = array() ) {
+               if ( isset( $item['text'] ) ) {
+                       $text = $item['text'];
+               } else {
+                       $text = $this->translator->translate( isset( $item['msg'] ) ? $item['msg'] : $key );
+               }
+
+               $html = htmlspecialchars( $text );
+
+               if ( isset( $options['text-wrapper'] ) ) {
+                       $wrapper = $options['text-wrapper'];
+                       if ( isset( $wrapper['tag'] ) ) {
+                               $wrapper = array( $wrapper );
+                       }
+                       while ( count( $wrapper ) > 0 ) {
+                               $element = array_pop( $wrapper );
+                               $html = Html::rawElement( $element['tag'], isset( $element['attributes'] )
+                                       ? $element['attributes']
+                                       : null, $html );
+                       }
+               }
+
+               if ( isset( $item['href'] ) || isset( $options['link-fallback'] ) ) {
+                       $attrs = $item;
+                       foreach ( array( 'single-id', 'text', 'msg', 'tooltiponly', 'context', 'primary' ) as $k ) {
+                               unset( $attrs[$k] );
+                       }
+
+                       if ( isset( $item['id'] ) && !isset( $item['single-id'] ) ) {
+                               $item['single-id'] = $item['id'];
+                       }
+                       if ( isset( $item['single-id'] ) ) {
+                               if ( isset( $item['tooltiponly'] ) && $item['tooltiponly'] ) {
+                                       $title = Linker::titleAttrib( $item['single-id'] );
+                                       if ( $title !== false ) {
+                                               $attrs['title'] = $title;
+                                       }
+                               } else {
+                                       $tip = Linker::tooltipAndAccesskeyAttribs( $item['single-id'] );
+                                       if ( isset( $tip['title'] ) && $tip['title'] !== false ) {
+                                               $attrs['title'] = $tip['title'];
+                                       }
+                                       if ( isset( $tip['accesskey'] ) && $tip['accesskey'] !== false ) {
+                                               $attrs['accesskey'] = $tip['accesskey'];
+                                       }
+                               }
+                       }
+                       if ( isset( $options['link-class'] ) ) {
+                               if ( isset( $attrs['class'] ) ) {
+                                       $attrs['class'] .= " {$options['link-class']}";
+                               } else {
+                                       $attrs['class'] = $options['link-class'];
+                               }
+                       }
+                       $html = Html::rawElement( isset( $attrs['href'] )
+                               ? 'a'
+                               : $options['link-fallback'], $attrs, $html );
+               }
+
+               return $html;
+       }
+
+       /**
+        * Generates a list item for a navigation, portlet, portal, sidebar... list
+        *
+        * @param string $key Usually a key from the list you are generating this link from.
+        * @param array $item Array of list item data containing some of a specific set of keys.
+        * The "id", "class" and "itemtitle" keys will be used as attributes for the list item,
+        * if "active" contains a value of true a "active" class will also be appended to class.
+        *
+        * @param array $options
+        *
+        * If you want something other than a "<li>" you can pass a tag name such as
+        * "tag" => "span" in the $options array to change the tag used.
+        * link/content data for the list item may come in one of two forms
+        * A "links" key may be used, in which case it should contain an array with
+        * a list of links to include inside the list item, see makeLink for the
+        * format of individual links array items.
+        *
+        * Otherwise the relevant keys from the list item $item array will be passed
+        * to makeLink instead. Note however that "id" and "class" are used by the
+        * list item directly so they will not be passed to makeLink
+        * (however the link will still support a tooltip and accesskey from it)
+        * If you need an id or class on a single link you should include a "links"
+        * array with just one link item inside of it. If you want to add a title
+        * to the list item itself, you can set "itemtitle" to the value.
+        * $options is also passed on to makeLink calls
+        *
+        * @return string
+        */
+       function makeListItem( $key, $item, $options = array() ) {
+               if ( isset( $item['links'] ) ) {
+                       $links = array();
+                       foreach ( $item['links'] as $linkKey => $link ) {
+                               $links[] = $this->makeLink( $linkKey, $link, $options );
+                       }
+                       $html = implode( ' ', $links );
+               } else {
+                       $link = $item;
+                       // These keys are used by makeListItem and shouldn't be passed on to the link
+                       foreach ( array( 'id', 'class', 'active', 'tag', 'itemtitle' ) as $k ) {
+                               unset( $link[$k] );
+                       }
+                       if ( isset( $item['id'] ) && !isset( $item['single-id'] ) ) {
+                               // The id goes on the <li> not on the <a> for single links
+                               // but makeSidebarLink still needs to know what id to use when
+                               // generating tooltips and accesskeys.
+                               $link['single-id'] = $item['id'];
+                       }
+                       $html = $this->makeLink( $key, $link, $options );
+               }
+
+               $attrs = array();
+               foreach ( array( 'id', 'class' ) as $attr ) {
+                       if ( isset( $item[$attr] ) ) {
+                               $attrs[$attr] = $item[$attr];
+                       }
+               }
+               if ( isset( $item['active'] ) && $item['active'] ) {
+                       if ( !isset( $attrs['class'] ) ) {
+                               $attrs['class'] = '';
+                       }
+                       $attrs['class'] .= ' active';
+                       $attrs['class'] = trim( $attrs['class'] );
+               }
+               if ( isset( $item['itemtitle'] ) ) {
+                       $attrs['title'] = $item['itemtitle'];
+               }
+               return Html::rawElement( isset( $options['tag'] ) ? $options['tag'] : 'li', $attrs, $html );
+       }
+
+       function makeSearchInput( $attrs = array() ) {
+               $realAttrs = array(
+                       'type' => 'search',
+                       'name' => 'search',
+                       'placeholder' => wfMessage( 'searchsuggest-search' )->text(),
+                       'value' => $this->get( 'search', '' ),
+               );
+               $realAttrs = array_merge( $realAttrs, Linker::tooltipAndAccesskeyAttribs( 'search' ), $attrs );
+               return Html::element( 'input', $realAttrs );
+       }
+
+       function makeSearchButton( $mode, $attrs = array() ) {
+               switch ( $mode ) {
+                       case 'go':
+                       case 'fulltext':
+                               $realAttrs = array(
+                                       'type' => 'submit',
+                                       'name' => $mode,
+                                       'value' => $this->translator->translate(
+                                               $mode == 'go' ? 'searcharticle' : 'searchbutton' ),
+                               );
+                               $realAttrs = array_merge(
+                                       $realAttrs,
+                                       Linker::tooltipAndAccesskeyAttribs( "search-$mode" ),
+                                       $attrs
+                               );
+                               return Html::element( 'input', $realAttrs );
+                       case 'image':
+                               $buttonAttrs = array(
+                                       'type' => 'submit',
+                                       'name' => 'button',
+                               );
+                               $buttonAttrs = array_merge(
+                                       $buttonAttrs,
+                                       Linker::tooltipAndAccesskeyAttribs( 'search-fulltext' ),
+                                       $attrs
+                               );
+                               unset( $buttonAttrs['src'] );
+                               unset( $buttonAttrs['alt'] );
+                               unset( $buttonAttrs['width'] );
+                               unset( $buttonAttrs['height'] );
+                               $imgAttrs = array(
+                                       'src' => $attrs['src'],
+                                       'alt' => isset( $attrs['alt'] )
+                                               ? $attrs['alt']
+                                               : $this->translator->translate( 'searchbutton' ),
+                                       'width' => isset( $attrs['width'] ) ? $attrs['width'] : null,
+                                       'height' => isset( $attrs['height'] ) ? $attrs['height'] : null,
+                               );
+                               return Html::rawElement( 'button', $buttonAttrs, Html::element( 'img', $imgAttrs ) );
+                       default:
+                               throw new MWException( 'Unknown mode passed to BaseTemplate::makeSearchButton' );
+               }
+       }
+
+       /**
+        * Returns an array of footerlinks trimmed down to only those footer links that
+        * are valid.
+        * If you pass "flat" as an option then the returned array will be a flat array
+        * of footer icons instead of a key/value array of footerlinks arrays broken
+        * up into categories.
+        * @param string $option
+        * @return array|mixed
+        */
+       function getFooterLinks( $option = null ) {
+               $footerlinks = $this->get( 'footerlinks' );
+
+               // Reduce footer links down to only those which are being used
+               $validFooterLinks = array();
+               foreach ( $footerlinks as $category => $links ) {
+                       $validFooterLinks[$category] = array();
+                       foreach ( $links as $link ) {
+                               if ( isset( $this->data[$link] ) && $this->data[$link] ) {
+                                       $validFooterLinks[$category][] = $link;
+                               }
+                       }
+                       if ( count( $validFooterLinks[$category] ) <= 0 ) {
+                               unset( $validFooterLinks[$category] );
+                       }
+               }
+
+               if ( $option == 'flat' ) {
+                       // fold footerlinks into a single array using a bit of trickery
+                       $validFooterLinks = call_user_func_array(
+                               'array_merge',
+                               array_values( $validFooterLinks )
+                       );
+               }
+
+               return $validFooterLinks;
+       }
+
+       /**
+        * Returns an array of footer icons filtered down by options relevant to how
+        * the skin wishes to display them.
+        * If you pass "icononly" as the option all footer icons which do not have an
+        * image icon set will be filtered out.
+        * If you pass "nocopyright" then MediaWiki's copyright icon will not be included
+        * in the list of footer icons. This is mostly useful for skins which only
+        * display the text from footericons instead of the images and don't want a
+        * duplicate copyright statement because footerlinks already rendered one.
+        * @param string $option
+        * @return string
+        */
+       function getFooterIcons( $option = null ) {
+               // Generate additional footer icons
+               $footericons = $this->get( 'footericons' );
+
+               if ( $option == 'icononly' ) {
+                       // Unset any icons which don't have an image
+                       foreach ( $footericons as &$footerIconsBlock ) {
+                               foreach ( $footerIconsBlock as $footerIconKey => $footerIcon ) {
+                                       if ( !is_string( $footerIcon ) && !isset( $footerIcon['src'] ) ) {
+                                               unset( $footerIconsBlock[$footerIconKey] );
+                                       }
+                               }
+                       }
+                       // Redo removal of any empty blocks
+                       foreach ( $footericons as $footerIconsKey => &$footerIconsBlock ) {
+                               if ( count( $footerIconsBlock ) <= 0 ) {
+                                       unset( $footericons[$footerIconsKey] );
+                               }
+                       }
+               } elseif ( $option == 'nocopyright' ) {
+                       unset( $footericons['copyright']['copyright'] );
+                       if ( count( $footericons['copyright'] ) <= 0 ) {
+                               unset( $footericons['copyright'] );
+                       }
+               }
+
+               return $footericons;
+       }
+
+       /**
+        * Output the basic end-page trail including bottomscripts, reporttime, and
+        * debug stuff. This should be called right before outputting the closing
+        * body and html tags.
+        */
+       function printTrail() { ?>
+<?php echo MWDebug::getDebugHTML( $this->getSkin()->getContext() ); ?>
+<?php $this->html( 'bottomscripts' ); /* JS call to runBodyOnloadHook */ ?>
+<?php $this->html( 'reporttime' ) ?>
+<?php
+       }
+}
diff --git a/includes/skins/MediaWikiI18N.php b/includes/skins/MediaWikiI18N.php
new file mode 100644 (file)
index 0000000..8bd77cc
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Wrapper object for MediaWiki's localization functions,
+ * to be passed to the template engine.
+ *
+ * @private
+ * @ingroup Skins
+ */
+class MediaWikiI18N {
+       private $context = array();
+
+       function set( $varName, $value ) {
+               $this->context[$varName] = $value;
+       }
+
+       function translate( $value ) {
+               wfProfileIn( __METHOD__ );
+
+               // Hack for i18n:attributes in PHPTAL 1.0.0 dev version as of 2004-10-23
+               $value = preg_replace( '/^string:/', '', $value );
+
+               $value = wfMessage( $value )->text();
+               // interpolate variables
+               $m = array();
+               while ( preg_match( '/\$([0-9]*?)/sm', $value, $m ) ) {
+                       list( $src, $var ) = $m;
+                       wfSuppressWarnings();
+                       $varValue = $this->context[$var];
+                       wfRestoreWarnings();
+                       $value = str_replace( $src, $varValue, $value );
+               }
+               wfProfileOut( __METHOD__ );
+               return $value;
+       }
+}
diff --git a/includes/skins/QuickTemplate.php b/includes/skins/QuickTemplate.php
new file mode 100644 (file)
index 0000000..b28dc51
--- /dev/null
@@ -0,0 +1,180 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * Generic wrapper for template functions, with interface
+ * compatible with what we use of PHPTAL 0.7.
+ * @ingroup Skins
+ */
+abstract class QuickTemplate {
+
+       /** @var Config $config */
+       protected $config;
+
+       /**
+        * @param Config $config
+        */
+       function __construct( Config $config = null ) {
+               $this->data = array();
+               $this->translator = new MediaWikiI18N();
+               if ( $config === null ) {
+                       wfDebug( __METHOD__ . ' was called with no Config instance passed to it' );
+                       $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+               }
+               $this->config = $config;
+       }
+
+       /**
+        * Sets the value $value to $name
+        * @param string $name
+        * @param mixed $value
+        */
+       public function set( $name, $value ) {
+               $this->data[$name] = $value;
+       }
+
+       /**
+        * Gets the template data requested
+        * @since 1.22
+        * @param string $name Key for the data
+        * @param mixed $default Optional default (or null)
+        * @return mixed The value of the data requested or the deafult
+        */
+       public function get( $name, $default = null ) {
+               if ( isset( $this->data[$name] ) ) {
+                       return $this->data[$name];
+               } else {
+                       return $default;
+               }
+       }
+
+       /**
+        * @param string $name
+        * @param mixed $value
+        */
+       public function setRef( $name, &$value ) {
+               $this->data[$name] =& $value;
+       }
+
+       /**
+        * @param MediaWikiI18N $t
+        */
+       public function setTranslator( &$t ) {
+               $this->translator = &$t;
+       }
+
+       /**
+        * Main function, used by classes that subclass QuickTemplate
+        * to show the actual HTML output
+        */
+       abstract public function execute();
+
+       /**
+        * @private
+        * @param string $str
+        * @return string
+        */
+       function text( $str ) {
+               echo htmlspecialchars( $this->data[$str] );
+       }
+
+       /**
+        * @private
+        * @param string $str
+        * @return string
+        */
+       function html( $str ) {
+               echo $this->data[$str];
+       }
+
+       /**
+        * @private
+        * @param string $str
+        * @return string
+        */
+       function msg( $str ) {
+               echo htmlspecialchars( $this->translator->translate( $str ) );
+       }
+
+       /**
+        * @private
+        * @param string $str
+        * @return string
+        */
+       function msgHtml( $str ) {
+               echo $this->translator->translate( $str );
+       }
+
+       /**
+        * An ugly, ugly hack.
+        * @private
+        * @param string $str
+        * @return string
+        */
+       function msgWiki( $str ) {
+               global $wgOut;
+
+               $text = $this->translator->translate( $str );
+               echo $wgOut->parse( $text );
+       }
+
+       /**
+        * @private
+        * @param string $str
+        * @return bool
+        */
+       function haveData( $str ) {
+               return isset( $this->data[$str] );
+       }
+
+       /**
+        * @private
+        *
+        * @param string $str
+        * @return bool
+        */
+       function haveMsg( $str ) {
+               $msg = $this->translator->translate( $str );
+               return ( $msg != '-' ) && ( $msg != '' ); # ????
+       }
+
+       /**
+        * Get the Skin object related to this object
+        *
+        * @return Skin
+        */
+       public function getSkin() {
+               return $this->data['skin'];
+       }
+
+       /**
+        * Fetch the output of a QuickTemplate and return it
+        *
+        * @since 1.23
+        * @return string
+        */
+       public function getHTML() {
+               ob_start();
+               $this->execute();
+               $html = ob_get_contents();
+               ob_end_clean();
+               return $html;
+       }
+}
diff --git a/includes/skins/SkinApi.php b/includes/skins/SkinApi.php
new file mode 100644 (file)
index 0000000..064c076
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Extremely basic "skin" for API output, which needs to output a page without
+ * the usual skin elements but still using CSS, JS, and such via OutputPage and
+ * ResourceLoader.
+ *
+ * Created on Sep 08, 2014
+ *
+ * Copyright © 2014 Brad Jorsch <bjorsch@wikimedia.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * SkinTemplate class for API output
+ * @since 1.25
+ */
+class SkinApi extends SkinTemplate {
+       public $skinname = 'apioutput';
+       public $template = 'SkinApiTemplate';
+
+       public function setupSkinUserCss( OutputPage $out ) {
+               parent::setupSkinUserCss( $out );
+               $out->addModuleStyles( 'mediawiki.skinning.interface' );
+       }
+}
diff --git a/includes/skins/SkinApiTemplate.php b/includes/skins/SkinApiTemplate.php
new file mode 100644 (file)
index 0000000..be77c61
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Extremely basic "skin" for API output, which needs to output a page without
+ * the usual skin elements but still using CSS, JS, and such via OutputPage and
+ * ResourceLoader.
+ *
+ * Created on Sep 08, 2014
+ *
+ * Copyright © 2014 Brad Jorsch <bjorsch@wikimedia.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+/**
+ * BaseTemplate class for the 'apioutput' skin
+ * @since 1.25
+ */
+class SkinApiTemplate extends BaseTemplate {
+
+       public function execute() {
+               $this->html( 'headelement' ) ?>
+
+               <div class="mw-body" role="main">
+                       <h1 class="firstHeading">
+                               <span dir="auto"><?php $this->html( 'title' ) ?></span>
+                       </h1>
+                       <div class="mw-body-content">
+                               <?php $this->html( 'bodytext' ) ?>
+                       </div>
+               </div>
+
+               <?php $this->printTrail() ?>
+               </body></html>
+
+       <?php
+       }
+}
index b66862b..64ad816 100644 (file)
@@ -1,7 +1,5 @@
 <?php
 /**
- * Base class for template-based skins.
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  */
 
 /**
- * Wrapper object for MediaWiki's localization functions,
- * to be passed to the template engine.
+ * Base class for template-based skins.
  *
- * @private
- * @ingroup Skins
- */
-class MediaWikiI18N {
-       private $context = array();
-
-       function set( $varName, $value ) {
-               $this->context[$varName] = $value;
-       }
-
-       function translate( $value ) {
-               wfProfileIn( __METHOD__ );
-
-               // Hack for i18n:attributes in PHPTAL 1.0.0 dev version as of 2004-10-23
-               $value = preg_replace( '/^string:/', '', $value );
-
-               $value = wfMessage( $value )->text();
-               // interpolate variables
-               $m = array();
-               while ( preg_match( '/\$([0-9]*?)/sm', $value, $m ) ) {
-                       list( $src, $var ) = $m;
-                       wfSuppressWarnings();
-                       $varValue = $this->context[$var];
-                       wfRestoreWarnings();
-                       $value = str_replace( $src, $varValue, $value );
-               }
-               wfProfileOut( __METHOD__ );
-               return $value;
-       }
-}
-
-/**
  * Template-filler skin base class
  * Formerly generic PHPTal (http://phptal.sourceforge.net/) skin
  * Based on Brion's smarty skin
@@ -1365,759 +1330,3 @@ class SkinTemplate extends Skin {
                return $this->getTitle()->getNamespaceKey();
        }
 }
-
-/**
- * Generic wrapper for template functions, with interface
- * compatible with what we use of PHPTAL 0.7.
- * @ingroup Skins
- */
-abstract class QuickTemplate {
-
-       /** @var Config $config */
-       protected $config;
-
-       /**
-        * @param Config $config
-        */
-       function __construct( Config $config = null ) {
-               $this->data = array();
-               $this->translator = new MediaWikiI18N();
-               if ( $config === null ) {
-                       wfDebug( __METHOD__ . ' was called with no Config instance passed to it' );
-                       $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
-               }
-               $this->config = $config;
-       }
-
-       /**
-        * Sets the value $value to $name
-        * @param string $name
-        * @param mixed $value
-        */
-       public function set( $name, $value ) {
-               $this->data[$name] = $value;
-       }
-
-       /**
-        * Gets the template data requested
-        * @since 1.22
-        * @param string $name Key for the data
-        * @param mixed $default Optional default (or null)
-        * @return mixed The value of the data requested or the deafult
-        */
-       public function get( $name, $default = null ) {
-               if ( isset( $this->data[$name] ) ) {
-                       return $this->data[$name];
-               } else {
-                       return $default;
-               }
-       }
-
-       /**
-        * @param string $name
-        * @param mixed $value
-        */
-       public function setRef( $name, &$value ) {
-               $this->data[$name] =& $value;
-       }
-
-       /**
-        * @param MediaWikiI18N $t
-        */
-       public function setTranslator( &$t ) {
-               $this->translator = &$t;
-       }
-
-       /**
-        * Main function, used by classes that subclass QuickTemplate
-        * to show the actual HTML output
-        */
-       abstract public function execute();
-
-       /**
-        * @private
-        * @param string $str
-        * @return string
-        */
-       function text( $str ) {
-               echo htmlspecialchars( $this->data[$str] );
-       }
-
-       /**
-        * @private
-        * @param string $str
-        * @return string
-        */
-       function html( $str ) {
-               echo $this->data[$str];
-       }
-
-       /**
-        * @private
-        * @param string $str
-        * @return string
-        */
-       function msg( $str ) {
-               echo htmlspecialchars( $this->translator->translate( $str ) );
-       }
-
-       /**
-        * @private
-        * @param string $str
-        * @return string
-        */
-       function msgHtml( $str ) {
-               echo $this->translator->translate( $str );
-       }
-
-       /**
-        * An ugly, ugly hack.
-        * @private
-        * @param string $str
-        * @return string
-        */
-       function msgWiki( $str ) {
-               global $wgOut;
-
-               $text = $this->translator->translate( $str );
-               echo $wgOut->parse( $text );
-       }
-
-       /**
-        * @private
-        * @param string $str
-        * @return bool
-        */
-       function haveData( $str ) {
-               return isset( $this->data[$str] );
-       }
-
-       /**
-        * @private
-        *
-        * @param string $str
-        * @return bool
-        */
-       function haveMsg( $str ) {
-               $msg = $this->translator->translate( $str );
-               return ( $msg != '-' ) && ( $msg != '' ); # ????
-       }
-
-       /**
-        * Get the Skin object related to this object
-        *
-        * @return Skin
-        */
-       public function getSkin() {
-               return $this->data['skin'];
-       }
-
-       /**
-        * Fetch the output of a QuickTemplate and return it
-        *
-        * @since 1.23
-        * @return string
-        */
-       public function getHTML() {
-               ob_start();
-               $this->execute();
-               $html = ob_get_contents();
-               ob_end_clean();
-               return $html;
-       }
-}
-
-/**
- * New base template for a skin's template extended from QuickTemplate
- * this class features helper methods that provide common ways of interacting
- * with the data stored in the QuickTemplate
- */
-abstract class BaseTemplate extends QuickTemplate {
-
-       /**
-        * Get a Message object with its context set
-        *
-        * @param string $name Message name
-        * @return Message
-        */
-       public function getMsg( $name ) {
-               return $this->getSkin()->msg( $name );
-       }
-
-       function msg( $str ) {
-               echo $this->getMsg( $str )->escaped();
-       }
-
-       function msgHtml( $str ) {
-               echo $this->getMsg( $str )->text();
-       }
-
-       function msgWiki( $str ) {
-               echo $this->getMsg( $str )->parseAsBlock();
-       }
-
-       /**
-        * Create an array of common toolbox items from the data in the quicktemplate
-        * stored by SkinTemplate.
-        * The resulting array is built according to a format intended to be passed
-        * through makeListItem to generate the html.
-        * @return array
-        */
-       function getToolbox() {
-               wfProfileIn( __METHOD__ );
-
-               $toolbox = array();
-               if ( isset( $this->data['nav_urls']['whatlinkshere'] )
-                       && $this->data['nav_urls']['whatlinkshere']
-               ) {
-                       $toolbox['whatlinkshere'] = $this->data['nav_urls']['whatlinkshere'];
-                       $toolbox['whatlinkshere']['id'] = 't-whatlinkshere';
-               }
-               if ( isset( $this->data['nav_urls']['recentchangeslinked'] )
-                       && $this->data['nav_urls']['recentchangeslinked']
-               ) {
-                       $toolbox['recentchangeslinked'] = $this->data['nav_urls']['recentchangeslinked'];
-                       $toolbox['recentchangeslinked']['msg'] = 'recentchangeslinked-toolbox';
-                       $toolbox['recentchangeslinked']['id'] = 't-recentchangeslinked';
-               }
-               if ( isset( $this->data['feeds'] ) && $this->data['feeds'] ) {
-                       $toolbox['feeds']['id'] = 'feedlinks';
-                       $toolbox['feeds']['links'] = array();
-                       foreach ( $this->data['feeds'] as $key => $feed ) {
-                               $toolbox['feeds']['links'][$key] = $feed;
-                               $toolbox['feeds']['links'][$key]['id'] = "feed-$key";
-                               $toolbox['feeds']['links'][$key]['rel'] = 'alternate';
-                               $toolbox['feeds']['links'][$key]['type'] = "application/{$key}+xml";
-                               $toolbox['feeds']['links'][$key]['class'] = 'feedlink';
-                       }
-               }
-               foreach ( array( 'contributions', 'log', 'blockip', 'emailuser',
-                       'userrights', 'upload', 'specialpages' ) as $special
-               ) {
-                       if ( isset( $this->data['nav_urls'][$special] ) && $this->data['nav_urls'][$special] ) {
-                               $toolbox[$special] = $this->data['nav_urls'][$special];
-                               $toolbox[$special]['id'] = "t-$special";
-                       }
-               }
-               if ( isset( $this->data['nav_urls']['print'] ) && $this->data['nav_urls']['print'] ) {
-                       $toolbox['print'] = $this->data['nav_urls']['print'];
-                       $toolbox['print']['id'] = 't-print';
-                       $toolbox['print']['rel'] = 'alternate';
-                       $toolbox['print']['msg'] = 'printableversion';
-               }
-               if ( isset( $this->data['nav_urls']['permalink'] ) && $this->data['nav_urls']['permalink'] ) {
-                       $toolbox['permalink'] = $this->data['nav_urls']['permalink'];
-                       if ( $toolbox['permalink']['href'] === '' ) {
-                               unset( $toolbox['permalink']['href'] );
-                               $toolbox['ispermalink']['tooltiponly'] = true;
-                               $toolbox['ispermalink']['id'] = 't-ispermalink';
-                               $toolbox['ispermalink']['msg'] = 'permalink';
-                       } else {
-                               $toolbox['permalink']['id'] = 't-permalink';
-                       }
-               }
-               if ( isset( $this->data['nav_urls']['info'] ) && $this->data['nav_urls']['info'] ) {
-                       $toolbox['info'] = $this->data['nav_urls']['info'];
-                       $toolbox['info']['id'] = 't-info';
-               }
-
-               wfRunHooks( 'BaseTemplateToolbox', array( &$this, &$toolbox ) );
-               wfProfileOut( __METHOD__ );
-               return $toolbox;
-       }
-
-       /**
-        * Create an array of personal tools items from the data in the quicktemplate
-        * stored by SkinTemplate.
-        * The resulting array is built according to a format intended to be passed
-        * through makeListItem to generate the html.
-        * This is in reality the same list as already stored in personal_urls
-        * however it is reformatted so that you can just pass the individual items
-        * to makeListItem instead of hardcoding the element creation boilerplate.
-        * @return array
-        */
-       function getPersonalTools() {
-               $personal_tools = array();
-               foreach ( $this->get( 'personal_urls' ) as $key => $plink ) {
-                       # The class on a personal_urls item is meant to go on the <a> instead
-                       # of the <li> so we have to use a single item "links" array instead
-                       # of using most of the personal_url's keys directly.
-                       $ptool = array(
-                               'links' => array(
-                                       array( 'single-id' => "pt-$key" ),
-                               ),
-                               'id' => "pt-$key",
-                       );
-                       if ( isset( $plink['active'] ) ) {
-                               $ptool['active'] = $plink['active'];
-                       }
-                       foreach ( array( 'href', 'class', 'text', 'dir' ) as $k ) {
-                               if ( isset( $plink[$k] ) ) {
-                                       $ptool['links'][0][$k] = $plink[$k];
-                               }
-                       }
-                       $personal_tools[$key] = $ptool;
-               }
-               return $personal_tools;
-       }
-
-       function getSidebar( $options = array() ) {
-               // Force the rendering of the following portals
-               $sidebar = $this->data['sidebar'];
-               if ( !isset( $sidebar['SEARCH'] ) ) {
-                       $sidebar['SEARCH'] = true;
-               }
-               if ( !isset( $sidebar['TOOLBOX'] ) ) {
-                       $sidebar['TOOLBOX'] = true;
-               }
-               if ( !isset( $sidebar['LANGUAGES'] ) ) {
-                       $sidebar['LANGUAGES'] = true;
-               }
-
-               if ( !isset( $options['search'] ) || $options['search'] !== true ) {
-                       unset( $sidebar['SEARCH'] );
-               }
-               if ( isset( $options['toolbox'] ) && $options['toolbox'] === false ) {
-                       unset( $sidebar['TOOLBOX'] );
-               }
-               if ( isset( $options['languages'] ) && $options['languages'] === false ) {
-                       unset( $sidebar['LANGUAGES'] );
-               }
-
-               $boxes = array();
-               foreach ( $sidebar as $boxName => $content ) {
-                       if ( $content === false ) {
-                               continue;
-                       }
-                       switch ( $boxName ) {
-                       case 'SEARCH':
-                               // Search is a special case, skins should custom implement this
-                               $boxes[$boxName] = array(
-                                       'id' => 'p-search',
-                                       'header' => $this->getMsg( 'search' )->text(),
-                                       'generated' => false,
-                                       'content' => true,
-                               );
-                               break;
-                       case 'TOOLBOX':
-                               $msgObj = $this->getMsg( 'toolbox' );
-                               $boxes[$boxName] = array(
-                                       'id' => 'p-tb',
-                                       'header' => $msgObj->exists() ? $msgObj->text() : 'toolbox',
-                                       'generated' => false,
-                                       'content' => $this->getToolbox(),
-                               );
-                               break;
-                       case 'LANGUAGES':
-                               if ( $this->data['language_urls'] ) {
-                                       $msgObj = $this->getMsg( 'otherlanguages' );
-                                       $boxes[$boxName] = array(
-                                               'id' => 'p-lang',
-                                               'header' => $msgObj->exists() ? $msgObj->text() : 'otherlanguages',
-                                               'generated' => false,
-                                               'content' => $this->data['language_urls'],
-                                       );
-                               }
-                               break;
-                       default:
-                               $msgObj = $this->getMsg( $boxName );
-                               $boxes[$boxName] = array(
-                                       'id' => "p-$boxName",
-                                       'header' => $msgObj->exists() ? $msgObj->text() : $boxName,
-                                       'generated' => true,
-                                       'content' => $content,
-                               );
-                               break;
-                       }
-               }
-
-               // HACK: Compatibility with extensions still using SkinTemplateToolboxEnd
-               $hookContents = null;
-               if ( isset( $boxes['TOOLBOX'] ) ) {
-                       ob_start();
-                       // We pass an extra 'true' at the end so extensions using BaseTemplateToolbox
-                       // can abort and avoid outputting double toolbox links
-                       wfRunHooks( 'SkinTemplateToolboxEnd', array( &$this, true ) );
-                       $hookContents = ob_get_contents();
-                       ob_end_clean();
-                       if ( !trim( $hookContents ) ) {
-                               $hookContents = null;
-                       }
-               }
-               // END hack
-
-               if ( isset( $options['htmlOnly'] ) && $options['htmlOnly'] === true ) {
-                       foreach ( $boxes as $boxName => $box ) {
-                               if ( is_array( $box['content'] ) ) {
-                                       $content = '<ul>';
-                                       foreach ( $box['content'] as $key => $val ) {
-                                               $content .= "\n " . $this->makeListItem( $key, $val );
-                                       }
-                                       // HACK, shove the toolbox end onto the toolbox if we're rendering itself
-                                       if ( $hookContents ) {
-                                               $content .= "\n $hookContents";
-                                       }
-                                       // END hack
-                                       $content .= "\n</ul>\n";
-                                       $boxes[$boxName]['content'] = $content;
-                               }
-                       }
-               } else {
-                       if ( $hookContents ) {
-                               $boxes['TOOLBOXEND'] = array(
-                                       'id' => 'p-toolboxend',
-                                       'header' => $boxes['TOOLBOX']['header'],
-                                       'generated' => false,
-                                       'content' => "<ul>{$hookContents}</ul>",
-                               );
-                               // HACK: Make sure that TOOLBOXEND is sorted next to TOOLBOX
-                               $boxes2 = array();
-                               foreach ( $boxes as $key => $box ) {
-                                       if ( $key === 'TOOLBOXEND' ) {
-                                               continue;
-                                       }
-                                       $boxes2[$key] = $box;
-                                       if ( $key === 'TOOLBOX' ) {
-                                               $boxes2['TOOLBOXEND'] = $boxes['TOOLBOXEND'];
-                                       }
-                               }
-                               $boxes = $boxes2;
-                               // END hack
-                       }
-               }
-
-               return $boxes;
-       }
-
-       /**
-        * @param string $name
-        */
-       protected function renderAfterPortlet( $name ) {
-               $content = '';
-               wfRunHooks( 'BaseTemplateAfterPortlet', array( $this, $name, &$content ) );
-
-               if ( $content !== '' ) {
-                       echo "<div class='after-portlet after-portlet-$name'>$content</div>";
-               }
-
-       }
-
-       /**
-        * Makes a link, usually used by makeListItem to generate a link for an item
-        * in a list used in navigation lists, portlets, portals, sidebars, etc...
-        *
-        * @param string $key Usually a key from the list you are generating this
-        * link from.
-        * @param array $item Contains some of a specific set of keys.
-        *
-        * The text of the link will be generated either from the contents of the
-        * "text" key in the $item array, if a "msg" key is present a message by
-        * that name will be used, and if neither of those are set the $key will be
-        * used as a message name.
-        *
-        * If a "href" key is not present makeLink will just output htmlescaped text.
-        * The "href", "id", "class", "rel", and "type" keys are used as attributes
-        * for the link if present.
-        *
-        * If an "id" or "single-id" (if you don't want the actual id to be output
-        * on the link) is present it will be used to generate a tooltip and
-        * accesskey for the link.
-        *
-        * The keys "context" and "primary" are ignored; these keys are used
-        * internally by skins and are not supposed to be included in the HTML
-        * output.
-        *
-        * If you don't want an accesskey, set $item['tooltiponly'] = true;
-        *
-        * @param array $options Can be used to affect the output of a link.
-        * Possible options are:
-        *   - 'text-wrapper' key to specify a list of elements to wrap the text of
-        *   a link in. This should be an array of arrays containing a 'tag' and
-        *   optionally an 'attributes' key. If you only have one element you don't
-        *   need to wrap it in another array. eg: To use <a><span>...</span></a>
-        *   in all links use array( 'text-wrapper' => array( 'tag' => 'span' ) )
-        *   for your options.
-        *   - 'link-class' key can be used to specify additional classes to apply
-        *   to all links.
-        *   - 'link-fallback' can be used to specify a tag to use instead of "<a>"
-        *   if there is no link. eg: If you specify 'link-fallback' => 'span' than
-        *   any non-link will output a "<span>" instead of just text.
-        *
-        * @return string
-        */
-       function makeLink( $key, $item, $options = array() ) {
-               if ( isset( $item['text'] ) ) {
-                       $text = $item['text'];
-               } else {
-                       $text = $this->translator->translate( isset( $item['msg'] ) ? $item['msg'] : $key );
-               }
-
-               $html = htmlspecialchars( $text );
-
-               if ( isset( $options['text-wrapper'] ) ) {
-                       $wrapper = $options['text-wrapper'];
-                       if ( isset( $wrapper['tag'] ) ) {
-                               $wrapper = array( $wrapper );
-                       }
-                       while ( count( $wrapper ) > 0 ) {
-                               $element = array_pop( $wrapper );
-                               $html = Html::rawElement( $element['tag'], isset( $element['attributes'] )
-                                       ? $element['attributes']
-                                       : null, $html );
-                       }
-               }
-
-               if ( isset( $item['href'] ) || isset( $options['link-fallback'] ) ) {
-                       $attrs = $item;
-                       foreach ( array( 'single-id', 'text', 'msg', 'tooltiponly', 'context', 'primary' ) as $k ) {
-                               unset( $attrs[$k] );
-                       }
-
-                       if ( isset( $item['id'] ) && !isset( $item['single-id'] ) ) {
-                               $item['single-id'] = $item['id'];
-                       }
-                       if ( isset( $item['single-id'] ) ) {
-                               if ( isset( $item['tooltiponly'] ) && $item['tooltiponly'] ) {
-                                       $title = Linker::titleAttrib( $item['single-id'] );
-                                       if ( $title !== false ) {
-                                               $attrs['title'] = $title;
-                                       }
-                               } else {
-                                       $tip = Linker::tooltipAndAccesskeyAttribs( $item['single-id'] );
-                                       if ( isset( $tip['title'] ) && $tip['title'] !== false ) {
-                                               $attrs['title'] = $tip['title'];
-                                       }
-                                       if ( isset( $tip['accesskey'] ) && $tip['accesskey'] !== false ) {
-                                               $attrs['accesskey'] = $tip['accesskey'];
-                                       }
-                               }
-                       }
-                       if ( isset( $options['link-class'] ) ) {
-                               if ( isset( $attrs['class'] ) ) {
-                                       $attrs['class'] .= " {$options['link-class']}";
-                               } else {
-                                       $attrs['class'] = $options['link-class'];
-                               }
-                       }
-                       $html = Html::rawElement( isset( $attrs['href'] )
-                               ? 'a'
-                               : $options['link-fallback'], $attrs, $html );
-               }
-
-               return $html;
-       }
-
-       /**
-        * Generates a list item for a navigation, portlet, portal, sidebar... list
-        *
-        * @param string $key Usually a key from the list you are generating this link from.
-        * @param array $item Array of list item data containing some of a specific set of keys.
-        * The "id", "class" and "itemtitle" keys will be used as attributes for the list item,
-        * if "active" contains a value of true a "active" class will also be appended to class.
-        *
-        * @param array $options
-        *
-        * If you want something other than a "<li>" you can pass a tag name such as
-        * "tag" => "span" in the $options array to change the tag used.
-        * link/content data for the list item may come in one of two forms
-        * A "links" key may be used, in which case it should contain an array with
-        * a list of links to include inside the list item, see makeLink for the
-        * format of individual links array items.
-        *
-        * Otherwise the relevant keys from the list item $item array will be passed
-        * to makeLink instead. Note however that "id" and "class" are used by the
-        * list item directly so they will not be passed to makeLink
-        * (however the link will still support a tooltip and accesskey from it)
-        * If you need an id or class on a single link you should include a "links"
-        * array with just one link item inside of it. If you want to add a title
-        * to the list item itself, you can set "itemtitle" to the value.
-        * $options is also passed on to makeLink calls
-        *
-        * @return string
-        */
-       function makeListItem( $key, $item, $options = array() ) {
-               if ( isset( $item['links'] ) ) {
-                       $links = array();
-                       foreach ( $item['links'] as $linkKey => $link ) {
-                               $links[] = $this->makeLink( $linkKey, $link, $options );
-                       }
-                       $html = implode( ' ', $links );
-               } else {
-                       $link = $item;
-                       // These keys are used by makeListItem and shouldn't be passed on to the link
-                       foreach ( array( 'id', 'class', 'active', 'tag', 'itemtitle' ) as $k ) {
-                               unset( $link[$k] );
-                       }
-                       if ( isset( $item['id'] ) && !isset( $item['single-id'] ) ) {
-                               // The id goes on the <li> not on the <a> for single links
-                               // but makeSidebarLink still needs to know what id to use when
-                               // generating tooltips and accesskeys.
-                               $link['single-id'] = $item['id'];
-                       }
-                       $html = $this->makeLink( $key, $link, $options );
-               }
-
-               $attrs = array();
-               foreach ( array( 'id', 'class' ) as $attr ) {
-                       if ( isset( $item[$attr] ) ) {
-                               $attrs[$attr] = $item[$attr];
-                       }
-               }
-               if ( isset( $item['active'] ) && $item['active'] ) {
-                       if ( !isset( $attrs['class'] ) ) {
-                               $attrs['class'] = '';
-                       }
-                       $attrs['class'] .= ' active';
-                       $attrs['class'] = trim( $attrs['class'] );
-               }
-               if ( isset( $item['itemtitle'] ) ) {
-                       $attrs['title'] = $item['itemtitle'];
-               }
-               return Html::rawElement( isset( $options['tag'] ) ? $options['tag'] : 'li', $attrs, $html );
-       }
-
-       function makeSearchInput( $attrs = array() ) {
-               $realAttrs = array(
-                       'type' => 'search',
-                       'name' => 'search',
-                       'placeholder' => wfMessage( 'searchsuggest-search' )->text(),
-                       'value' => $this->get( 'search', '' ),
-               );
-               $realAttrs = array_merge( $realAttrs, Linker::tooltipAndAccesskeyAttribs( 'search' ), $attrs );
-               return Html::element( 'input', $realAttrs );
-       }
-
-       function makeSearchButton( $mode, $attrs = array() ) {
-               switch ( $mode ) {
-                       case 'go':
-                       case 'fulltext':
-                               $realAttrs = array(
-                                       'type' => 'submit',
-                                       'name' => $mode,
-                                       'value' => $this->translator->translate(
-                                               $mode == 'go' ? 'searcharticle' : 'searchbutton' ),
-                               );
-                               $realAttrs = array_merge(
-                                       $realAttrs,
-                                       Linker::tooltipAndAccesskeyAttribs( "search-$mode" ),
-                                       $attrs
-                               );
-                               return Html::element( 'input', $realAttrs );
-                       case 'image':
-                               $buttonAttrs = array(
-                                       'type' => 'submit',
-                                       'name' => 'button',
-                               );
-                               $buttonAttrs = array_merge(
-                                       $buttonAttrs,
-                                       Linker::tooltipAndAccesskeyAttribs( 'search-fulltext' ),
-                                       $attrs
-                               );
-                               unset( $buttonAttrs['src'] );
-                               unset( $buttonAttrs['alt'] );
-                               unset( $buttonAttrs['width'] );
-                               unset( $buttonAttrs['height'] );
-                               $imgAttrs = array(
-                                       'src' => $attrs['src'],
-                                       'alt' => isset( $attrs['alt'] )
-                                               ? $attrs['alt']
-                                               : $this->translator->translate( 'searchbutton' ),
-                                       'width' => isset( $attrs['width'] ) ? $attrs['width'] : null,
-                                       'height' => isset( $attrs['height'] ) ? $attrs['height'] : null,
-                               );
-                               return Html::rawElement( 'button', $buttonAttrs, Html::element( 'img', $imgAttrs ) );
-                       default:
-                               throw new MWException( 'Unknown mode passed to BaseTemplate::makeSearchButton' );
-               }
-       }
-
-       /**
-        * Returns an array of footerlinks trimmed down to only those footer links that
-        * are valid.
-        * If you pass "flat" as an option then the returned array will be a flat array
-        * of footer icons instead of a key/value array of footerlinks arrays broken
-        * up into categories.
-        * @param string $option
-        * @return array|mixed
-        */
-       function getFooterLinks( $option = null ) {
-               $footerlinks = $this->get( 'footerlinks' );
-
-               // Reduce footer links down to only those which are being used
-               $validFooterLinks = array();
-               foreach ( $footerlinks as $category => $links ) {
-                       $validFooterLinks[$category] = array();
-                       foreach ( $links as $link ) {
-                               if ( isset( $this->data[$link] ) && $this->data[$link] ) {
-                                       $validFooterLinks[$category][] = $link;
-                               }
-                       }
-                       if ( count( $validFooterLinks[$category] ) <= 0 ) {
-                               unset( $validFooterLinks[$category] );
-                       }
-               }
-
-               if ( $option == 'flat' ) {
-                       // fold footerlinks into a single array using a bit of trickery
-                       $validFooterLinks = call_user_func_array(
-                               'array_merge',
-                               array_values( $validFooterLinks )
-                       );
-               }
-
-               return $validFooterLinks;
-       }
-
-       /**
-        * Returns an array of footer icons filtered down by options relevant to how
-        * the skin wishes to display them.
-        * If you pass "icononly" as the option all footer icons which do not have an
-        * image icon set will be filtered out.
-        * If you pass "nocopyright" then MediaWiki's copyright icon will not be included
-        * in the list of footer icons. This is mostly useful for skins which only
-        * display the text from footericons instead of the images and don't want a
-        * duplicate copyright statement because footerlinks already rendered one.
-        * @param string $option
-        * @return string
-        */
-       function getFooterIcons( $option = null ) {
-               // Generate additional footer icons
-               $footericons = $this->get( 'footericons' );
-
-               if ( $option == 'icononly' ) {
-                       // Unset any icons which don't have an image
-                       foreach ( $footericons as &$footerIconsBlock ) {
-                               foreach ( $footerIconsBlock as $footerIconKey => $footerIcon ) {
-                                       if ( !is_string( $footerIcon ) && !isset( $footerIcon['src'] ) ) {
-                                               unset( $footerIconsBlock[$footerIconKey] );
-                                       }
-                               }
-                       }
-                       // Redo removal of any empty blocks
-                       foreach ( $footericons as $footerIconsKey => &$footerIconsBlock ) {
-                               if ( count( $footerIconsBlock ) <= 0 ) {
-                                       unset( $footericons[$footerIconsKey] );
-                               }
-                       }
-               } elseif ( $option == 'nocopyright' ) {
-                       unset( $footericons['copyright']['copyright'] );
-                       if ( count( $footericons['copyright'] ) <= 0 ) {
-                               unset( $footericons['copyright'] );
-                       }
-               }
-
-               return $footericons;
-       }
-
-       /**
-        * Output the basic end-page trail including bottomscripts, reporttime, and
-        * debug stuff. This should be called right before outputting the closing
-        * body and html tags.
-        */
-       function printTrail() { ?>
-<?php echo MWDebug::getDebugHTML( $this->getSkin()->getContext() ); ?>
-<?php $this->html( 'bottomscripts' ); /* JS call to runBodyOnloadHook */ ?>
-<?php $this->html( 'reporttime' ) ?>
-<?php
-       }
-}
index d17b671..07e1be1 100644 (file)
@@ -332,6 +332,8 @@ class SpecialActiveUsers extends SpecialPage {
         * @return int|bool UNIX timestamp the cache is now up-to-date as of (false on error)
         */
        protected static function doQueryCacheUpdate( DatabaseBase $dbw, $days, $window ) {
+               $dbw->startAtomic( __METHOD__ );
+
                $lockKey = wfWikiID() . '-activeusers';
                if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
                        return false; // exclusive update (avoids duplicate entries)
@@ -343,6 +345,9 @@ class SpecialActiveUsers extends SpecialPage {
                        array( 'qci_type' => 'activeusers' )
                );
                $cTimeUnix = $cTime ? wfTimestamp( TS_UNIX, $cTime ) : 1;
+               // If a transaction was already started, it might have an old
+               // snapshot, so kludge the timestamp range a few seconds back.
+               $cTimeUnix -= 5;
 
                // Pick the date range to fetch from. This is normally from the last
                // update to till the present time, but has a limited window for sanity.
@@ -389,7 +394,10 @@ class SpecialActiveUsers extends SpecialPage {
                                        'qcc_type' => 'activeusers',
                                        'qcc_namespace' => NS_USER,
                                        'qcc_title' => array_keys( $names ) ),
-                               __METHOD__
+                               __METHOD__,
+                               // See the latest data (ignoring trx snapshot) to avoid
+                               // duplicates if this method was called in a transaction
+                               array( 'LOCK IN SHARE MODE' )
                        );
                        foreach ( $res as $row ) {
                                unset( $names[$row->user_name] );
@@ -426,6 +434,7 @@ class SpecialActiveUsers extends SpecialPage {
                );
 
                $dbw->unlock( $lockKey, __METHOD__ );
+               $dbw->endAtomic( __METHOD__ );
 
                return $eTimestamp;
        }
index 456f4ec..aefd99a 100644 (file)
@@ -103,6 +103,7 @@ class SpecialBlockList extends SpecialPage {
                $form->setMethod( 'get' );
                $form->setWrapperLegendMsg( 'ipblocklist-legend' );
                $form->setSubmitTextMsg( 'ipblocklist-submit' );
+               $form->setSubmitProgressive();
                $form->prepareForm();
 
                $form->displayForm( '' );
index 72f4e46..e6750e1 100644 (file)
@@ -131,9 +131,20 @@ class SpecialBookSources extends SpecialPage {
                        'isbn',
                        20,
                        $this->isbn,
-                       array( 'autofocus' => true )
+                       array( 'autofocus' => true, 'class' => 'mw-ui-input-inline' )
                );
-               $form .= '&#160;' . Xml::submitButton( $this->msg( 'booksources-go' )->text() ) . "</p>\n";
+
+               if ( $this->getConfig()->get( 'UseMediaWikiUIEverywhere' ) ) {
+                       $form .= '&#160;' . Xml::submitButton(
+                               $this->msg( 'booksources-search' )->text(),
+                               array( 'class' => 'mw-ui-button mw-ui-progressive' )
+                       ) . "</p>\n";
+               } else {
+                       $form .= '&#160;' . Xml::submitButton(
+                               $this->msg( 'booksources-search' )->text()
+                       ) . "</p>\n";
+               }
+
                $form .= Html::closeElement( 'form' ) . "\n";
                $form .= Html::closeElement( 'fieldset' ) . "\n";
 
index 3656b9c..db83019 100644 (file)
@@ -609,6 +609,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                $context->setTitle( $this->getPageTitle() ); // Remove subpage
                $form = new EditWatchlistNormalHTMLForm( $fields, $context );
                $form->setSubmitTextMsg( 'watchlistedit-normal-submit' );
+               $form->setSubmitDestructive();
                # Used message keys:
                # 'accesskey-watchlistedit-normal-submit', 'tooltip-watchlistedit-normal-submit'
                $form->setSubmitTooltip( 'watchlistedit-normal-submit' );
index 371469b..37edc0f 100644 (file)
@@ -88,7 +88,7 @@ class LinkSearchPage extends QueryPage {
 
                $request = $this->getRequest();
                $target = $request->getVal( 'target', $par );
-               $namespace = $request->getIntorNull( 'namespace', null );
+               $namespace = $request->getIntOrNull( 'namespace', null );
 
                $protocols_list = array();
                foreach ( $this->getConfig()->get( 'UrlProtocols' ) as $prot ) {
index 04a83c8..2a97abc 100644 (file)
@@ -87,7 +87,7 @@ class ImageListPager extends TablePager {
                $this->mIncluding = $including;
                $this->mShowAll = $showAll;
 
-               if ( $userName ) {
+               if ( $userName !== null && $userName !== '' ) {
                        $nt = Title::newFromText( $userName, NS_USER );
                        if ( !is_null( $nt ) ) {
                                $this->mUserName = $nt->getText();
index 5bae28f..8b9a0ee 100644 (file)
@@ -235,20 +235,18 @@ class SpecialListGroupRights extends SpecialPage {
                foreach ( $permissions as $permission => $granted ) {
                        //show as granted only if it isn't revoked to prevent duplicate display of permissions
                        if ( $granted && ( !isset( $revoke[$permission] ) || !$revoke[$permission] ) ) {
-                               $description = $this->msg( 'listgrouprights-right-display',
+                               $r[] = $this->msg( 'listgrouprights-right-display',
                                        User::getRightDescription( $permission ),
                                        '<span class="mw-listgrouprights-right-name">' . $permission . '</span>'
                                )->parse();
-                               $r[] = $description;
                        }
                }
                foreach ( $revoke as $permission => $revoked ) {
                        if ( $revoked ) {
-                               $description = $this->msg( 'listgrouprights-right-revoked',
+                               $r[] = $this->msg( 'listgrouprights-right-revoked',
                                        User::getRightDescription( $permission ),
                                        '<span class="mw-listgrouprights-right-name">' . $permission . '</span>'
                                )->parse();
-                               $r[] = $description;
                        }
                }
 
@@ -257,51 +255,28 @@ class SpecialListGroupRights extends SpecialPage {
                $lang = $this->getLanguage();
                $allGroups = User::getAllGroups();
 
-               if ( $add === true ) {
-                       $r[] = $this->msg( 'listgrouprights-addgroup-all' )->escaped();
-               } elseif ( is_array( $add ) ) {
-                       $add = array_intersect( array_values( array_unique( $add ) ), $allGroups );
-                       if ( count( $add ) ) {
-                               $r[] = $this->msg( 'listgrouprights-addgroup',
-                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $add ) ),
-                                       count( $add )
-                               )->parse();
-                       }
-               }
-
-               if ( $remove === true ) {
-                       $r[] = $this->msg( 'listgrouprights-removegroup-all' )->escaped();
-               } elseif ( is_array( $remove ) ) {
-                       $remove = array_intersect( array_values( array_unique( $remove ) ), $allGroups );
-                       if ( count( $remove ) ) {
-                               $r[] = $this->msg( 'listgrouprights-removegroup',
-                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $remove ) ),
-                                       count( $remove )
-                               )->parse();
-                       }
-               }
-
-               if ( $addSelf === true ) {
-                       $r[] = $this->msg( 'listgrouprights-addgroup-self-all' )->escaped();
-               } elseif ( is_array( $addSelf ) ) {
-                       $addSelf = array_intersect( array_values( array_unique( $addSelf ) ), $allGroups );
-                       if ( count( $addSelf ) ) {
-                               $r[] = $this->msg( 'listgrouprights-addgroup-self',
-                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $addSelf ) ),
-                                       count( $addSelf )
-                               )->parse();
-                       }
-               }
+               $changeGroups = array(
+                       'addgroup' => $add,
+                       'removegroup' => $remove,
+                       'addgroup-self' => $addSelf,
+                       'removegroup-self' => $removeSelf
+               );
 
-               if ( $removeSelf === true ) {
-                       $r[] = $this->msg( 'listgrouprights-removegroup-self-all' )->parse();
-               } elseif ( is_array( $removeSelf ) ) {
-                       $removeSelf = array_intersect( array_values( array_unique( $removeSelf ) ), $allGroups );
-                       if ( count( $removeSelf ) ) {
-                               $r[] = $this->msg( 'listgrouprights-removegroup-self',
-                                       $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $removeSelf ) ),
-                                       count( $removeSelf )
-                               )->parse();
+               foreach ( $changeGroups as $messageKey => $changeGroup ) {
+                       if ( $changeGroup === true ) {
+                               // For grep: listgrouprights-addgroup-all, listgrouprights-removegroup-all,
+                               // listgrouprights-addgroup-self-all, listgrouprights-removegroup-self-all
+                               $r[] = $this->msg( 'listgrouprights-' . $messageKey . '-all' )->escaped();
+                       } elseif ( is_array( $changeGroup ) ) {
+                               $changeGroup = array_intersect( array_values( array_unique( $changeGroup ) ), $allGroups );
+                               if ( count( $changeGroup ) ) {
+                                       // For grep: listgrouprights-addgroup, listgrouprights-removegroup,
+                                       // listgrouprights-addgroup-self, listgrouprights-removegroup-self
+                                       $r[] = $this->msg( 'listgrouprights-' . $messageKey,
+                                               $lang->listToText( array_map( array( 'User', 'makeGroupLinkWiki' ), $changeGroup ) ),
+                                               count( $changeGroup )
+                                       )->parse();
+                               }
                        }
                }
 
index 6de7c90..edd1a60 100644 (file)
@@ -1423,16 +1423,9 @@ class LoginForm extends SpecialPage {
                }
 
                $template->set( 'secureLoginUrl', $this->mSecureLoginUrl );
-               // Use loginend-https for HTTPS requests if it's not blank, loginend otherwise
-               // Ditto for signupend.  New forms use neither.
+               // Use signupend-https for HTTPS requests if it's not blank, signupend otherwise
                $usingHTTPS = $this->mRequest->getProtocol() == 'https';
-               $loginendHTTPS = $this->msg( 'loginend-https' );
                $signupendHTTPS = $this->msg( 'signupend-https' );
-               if ( $usingHTTPS && !$loginendHTTPS->isBlank() ) {
-                       $template->set( 'loginend', $loginendHTTPS->parse() );
-               } else {
-                       $template->set( 'loginend', $this->msg( 'loginend' )->parse() );
-               }
                if ( $usingHTTPS && !$signupendHTTPS->isBlank() ) {
                        $template->set( 'signupend', $signupendHTTPS->parse() );
                } else {
index 5de543e..89ce2b3 100644 (file)
@@ -1297,7 +1297,8 @@ abstract class UploadBase {
         * @param array $attribs
         * @return bool
         */
-       public function checkSvgScriptCallback( $element, $attribs ) {
+       public function checkSvgScriptCallback( $element, $attribs, $data = null ) {
+
                list( $namespace, $strippedElement ) = $this->splitXmlNamespace( $element );
 
                // We specifically don't include:
@@ -1381,6 +1382,14 @@ abstract class UploadBase {
                        return true;
                }
 
+               # Check <style> css
+               if ( $strippedElement == 'style'
+                       && self::checkCssFragment( Sanitizer::normalizeCss( $data ) )
+               ) {
+                       wfDebug( __METHOD__ . ": hostile css in style element.\n" );
+                       return true;
+               }
+
                foreach ( $attribs as $attrib => $value ) {
                        $stripped = $this->stripXmlNamespace( $attrib );
                        $value = strtolower( $value );
@@ -1423,6 +1432,18 @@ abstract class UploadBase {
                                return true;
                        }
 
+                       # Change href with animate from (http://html5sec.org/#137). This doesn't seem
+                       # possible without embedding the svg, but filter here in case.
+                       if ( $stripped == 'from'
+                               && $strippedElement === 'animate'
+                               && !preg_match( '!^https?://!im', $value )
+                       ) {
+                               wfDebug( __METHOD__ . ": Found animate that might be changing href using from "
+                                       . "\"<$strippedElement '$attrib'='$value'...\" in uploaded file.\n" );
+
+                               return true;
+                       }
+
                        # use set/animate to add event-handler attribute to parent
                        if ( ( $strippedElement == 'set' || $strippedElement == 'animate' )
                                && $stripped == 'attributename'
@@ -1463,23 +1484,23 @@ abstract class UploadBase {
                        }
 
                        # use CSS styles to bring in remote code
-                       # catch url("http:..., url('http:..., url(http:..., but not url("#..., url('#..., url(#....
-                       $tagsList = "font|clip-path|fill|filter|marker|marker-end|marker-mid|marker-start|mask|stroke";
                        if ( $stripped == 'style'
-                               && preg_match_all(
-                                       '!((?:' . $tagsList . ')\s*:\s*url\s*\(\s*["\']?\s*[^#]+.*?\))!sim',
-                                       $value,
-                                       $matches
-                               )
+                               && self::checkCssFragment( Sanitizer::normalizeCss( $value ) )
                        ) {
-                               foreach ( $matches[1] as $match ) {
-                                       if ( !preg_match( '!(?:' . $tagsList . ')\s*:\s*url\s*\(\s*(#|\'#|"#)!sim', $match ) ) {
-                                               wfDebug( __METHOD__ . ": Found svg setting a style with "
-                                                       . "remote url '$attrib'='$value' in uploaded file.\n" );
+                               wfDebug( __METHOD__ . ": Found svg setting a style with "
+                                       . "remote url '$attrib'='$value' in uploaded file.\n" );
+                               return true;
+                       }
 
-                                               return true;
-                                       }
-                               }
+                       # Several attributes can include css, css character escaping isn't allowed
+                       $cssAttrs = array( 'font', 'clip-path', 'fill', 'filter', 'marker',
+                               'marker-end', 'marker-mid', 'marker-start', 'mask', 'stroke' );
+                       if ( in_array( $stripped, $cssAttrs )
+                               && self::checkCssFragment( $value )
+                       ) {
+                               wfDebug( __METHOD__ . ": Found svg setting a style with "
+                                       . "remote url '$attrib'='$value' in uploaded file.\n" );
+                               return true;
                        }
 
                        # image filters can pull in url, which could be svg that executes scripts
@@ -1497,6 +1518,58 @@ abstract class UploadBase {
                return false; //No scripts detected
        }
 
+       /**
+        * Check a block of CSS or CSS fragment for anything that looks like
+        * it is bringing in remote code.
+        * @param string $value a string of CSS
+        * @param bool $propOnly only check css properties (start regex with :)
+        * @return bool true if the CSS contains an illegal string, false if otherwise
+        */
+       private static function checkCssFragment( $value ) {
+
+               # Forbid external stylesheets, for both reliability and to protect viewer's privacy
+               if ( strpos( $value, '@import' ) !== false ) {
+                       return true;
+               }
+
+               # We allow @font-face to embed fonts with data: urls, so we snip the string
+               # 'url' out so this case won't match when we check for urls below
+               $pattern = '!(@font-face\s*{[^}]*src:)url(\("data:;base64,)!im';
+               $value = preg_replace( $pattern, '$1$2', $value );
+
+               # Check for remote and executable CSS. Unlike in Sanitizer::checkCss, the CSS
+               # properties filter and accelerator don't seem to be useful for xss in SVG files.
+               # Expression and -o-link don't seem to work either, but filtering them here in case.
+               # Additionally, we catch remote urls like url("http:..., url('http:..., url(http:...,
+               # but not local ones such as url("#..., url('#..., url(#....
+               if ( preg_match( '!expression
+                               | -o-link\s*:
+                               | -o-link-source\s*:
+                               | -o-replace\s*:!imx', $value ) ) {
+                       return true;
+               }
+
+               if ( preg_match_all(
+                               "!(\s*(url|image|image-set)\s*\(\s*[\"']?\s*[^#]+.*?\))!sim",
+                               $value,
+                               $matches
+                       ) !== 0
+               ) {
+                       # TODO: redo this in one regex. Until then, url("#whatever") matches the first
+                       foreach ( $matches[1] as $match ) {
+                               if ( !preg_match( "!\s*(url|image|image-set)\s*\(\s*(#|'#|\"#)!im", $match ) ) {
+                                       return true;
+                               }
+                       }
+               }
+
+               if ( preg_match( '/[\000-\010\013\016-\037\177]/', $value ) ) {
+                       return true;
+               }
+
+               return false;
+       }
+
        /**
         * Divide the element name passed by the xml parser to the callback into URI and prifix.
         * @param string $element
index 115a918..bf2e3a3 100644 (file)
@@ -143,6 +143,12 @@ class Language {
         */
        static private $fallbackLanguageCache = array();
 
+       /**
+        * Cache for language names
+        * @var MapCacheLRU|null
+        */
+       static private $languageNameCache;
+
        /**
         * Get a cached or new language object for a given language code
         * @param string $code
@@ -846,6 +852,33 @@ class Language {
         * @since 1.20
         */
        public static function fetchLanguageNames( $inLanguage = null, $include = 'mw' ) {
+               wfProfileIn( __METHOD__ );
+               $cacheKey = $inLanguage === null ? 'null' : $inLanguage;
+               $cacheKey .= ":$include";
+               if ( self::$languageNameCache === null ) {
+                       self::$languageNameCache = new MapCacheLRU( 20 );
+               }
+               if ( self::$languageNameCache->has( $cacheKey ) ) {
+                       $ret = self::$languageNameCache->get( $cacheKey );
+               } else {
+                       $ret = self::fetchLanguageNamesUncached( $inLanguage, $include );
+                       self::$languageNameCache->set( $cacheKey, $ret );
+               }
+               wfProfileOut( __METHOD__ );
+               return $ret;
+       }
+
+       /**
+        * Uncached helper for fetchLanguageNames
+        * @param null|string $inLanguage Code of language in which to return the names
+        *              Use null for autonyms (native names)
+        * @param string $include One of:
+        *              'all' all available languages
+        *              'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default)
+        *              'mwfile' only if the language is in 'mw' *and* has a message file
+        * @return array Language code => language name
+        */
+       private static function fetchLanguageNamesUncached( $inLanguage = null, $include = 'mw' ) {
                global $wgExtraLanguageNames;
                static $coreLanguageNames;
 
index 3993ed2..d702388 100644 (file)
        "querypage-disabled": "Hierdie spesiale bladsy is afgeskakel om werkverrigting te verbeter (bediener is oorlaai).",
        "booksources": "Boekbronne",
        "booksources-search-legend": "Soek vir boekbronne",
-       "booksources-go": "Soek",
        "booksources-text": "Hieronder is 'n lys van webtuistes wat nuwe en gebruikte boeke verkoop, en dalk meer inligting oor die boeke waarna u soek kan bevat:",
        "booksources-invalid-isbn": "Die ingevoerde ISBN-kode blyk asof dit ongeldig is; maak asseblief seker dat u dit sonder fout oorgekopiëer het vanaf die oorspronklike bron.",
        "specialloguserlabel": "Uitvoerende gebruiker:",
index bc94329..008e469 100644 (file)
        "passwordreset-emailsent-capture": "Se le ha ninviau un recordatorio por correu electronico, que s'amuestra contino.",
        "passwordreset-emailerror-capture": "S'ha chenerau un recordatorio por correu electronico, que s'amuestra contino, pero o ninvío ta l'usuario ha fallau: $1",
        "changeemail": "Cambiar l'adreza de correu-e",
-       "changeemail-header": "Cambiar l'adreza de correu-e d'a cuenta",
        "changeemail-text": "Replene iste formulario ta cambiar a suya adreza de correu electronico. Habrá d'introducir a clau ta confirmar iste cambeo.",
        "changeemail-no-info": "Debe identificar-se como usuario ta poder acceder dreitament ta ista pachina.",
        "changeemail-oldemail": "Adreza de correu-e actual:",
        "changeemail-newemail": "No bi ha garra adreza de correu electronico",
        "changeemail-none": "(garra)",
        "changeemail-submit": "Cambiar adreza de correu-e",
-       "changeemail-cancel": "Cancelar",
        "bold_sample": "Texto en negreta",
        "bold_tip": "Texto en negreta",
        "italic_sample": "Texto en cursiva",
        "searchrelated": "relacionato",
        "searchall": "totz",
        "showingresults": "Contino se bi {{PLURAL:$1|amuestra '''1''' resultau|amuestran '''$1''' resultaus}} prencipiando por o numero '''$2'''.",
-       "showingresultsheader": "{{PLURAL:$5|Resultau '''$1''' de '''$3'''|Resultaus '''$1-$2''' de '''$3'''}} ta '''$4'''",
        "search-nonefound": "No s'ha trobato garra resultau que cumpla os criterios.",
        "powersearch-legend": "Busca abanzata",
        "powersearch-ns": "Mirar en os espacios de nombres:",
        "querypage-disabled": "Ista pachina especial ye desactivata por motivos de rendimiento.",
        "booksources": "Fuents de libros",
        "booksources-search-legend": "Mirar fuents de libros",
-       "booksources-go": "Ir-ie",
        "booksources-text": "Contino ye una lista de vinclos ta atros puestos an que venden libros nuevos y usatos, talment bi haiga más información sobre os libros que ye mirando.",
        "booksources-invalid-isbn": "O numero d'ISBN dato pareix que no ye conforme; comprebe si no bi ha garra error en copiar d'a fuent orichinal.",
        "specialloguserlabel": "Fedor:",
        "import": "Importar pachinas",
        "importinterwiki": "Importación interwiki",
        "import-interwiki-text": "Trigue un wiki y un títol de pachina ta importar.\nAs calendatas d'as versions y os nombres d'os editors se preservarán.\nTodas as importacions interwiki se rechistran en o [[Special:Log/import|rechistro d'importacions]].",
-       "import-interwiki-source": "Wiki/pachina fuent:",
        "import-interwiki-history": "Copiar todas as versions de l'historial d'ista pachina",
        "import-interwiki-templates": "Incluir-ie todas as las plantillas",
        "import-interwiki-submit": "Importar",
        "logentry-newusers-create2": "$1 creyó una cuenta d'usuario $3",
        "logentry-newusers-autocreate": "S'ha creyau automaticament a cuenta $1",
        "rightsnone": "(garra)",
+       "revdelete-summary": "editar resumen",
        "feedback-bugornote": "Si creye que puede describir en detalle un problema tecnico, [$1 informe d'un bug] por favor.\n\nSi no, puet usar o siguient formulario. O suyo comentario será adhibiu a la pachina [$3 $2], de conchunta con o suyo nombre d'usuario y o navegador que fa servir.",
        "feedback-subject": "Afer:",
        "feedback-message": "Mensache:",
index c349d23..d47c055 100644 (file)
        "booksources": "Пошук кніг",
        "booksources-search-legend": "Пошук кніг",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Паказаць",
+       "booksources-search": "Шукаць",
        "booksources-text": "Ніжэй знаходзіцца сьпіс спасылак на іншыя сайты, якія прадаюць новыя і патрыманыя кнігі, і могуць таксама мець інфармацыю пра кнігі, якія Вы шукаеце:",
        "booksources-invalid-isbn": "Пададзены няслушны ISBN; праверце, магчыма ўзьніклі памылкі пры пераносе нумару з арыгінальнай крыніцы.",
        "specialloguserlabel": "Выканаўца:",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''адключана''')",
        "mediastatistics": "Статыстыка мэдыяфайлаў",
        "mediastatistics-summary": "Статыстыка тыпаў загружаных файлаў. Яна ўключае толькі актуальныя вэрсіі файлаў. Старыя і выдаленыя вэрсіі ня ўлічваюцца.",
-       "mediastatistics-nbytes": "{{PLURAL:$1|$1 байт|$1 байты|$1 байтаў}} ($2; $3%)"
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 байт|$1 байты|$1 байтаў}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME-тып"
 }
index 60739b9..3cebb80 100644 (file)
        "querypage-disabled": "Гэта адмысловая старонка адключана для павышэння прадукцыйнасці.",
        "booksources": "Кнігі",
        "booksources-search-legend": "Знайсці, дзе купіць кнігі",
-       "booksources-go": "Пошук",
        "booksources-text": "Ніжэй паказаны пералік спасылак на іншыя сеціўныя пляцоўкі, якія прадаюць новыя і б/у кнігі, і, магчыма, маюць больш звестак пра кнігі, якіх вы шукаеце:",
        "booksources-invalid-isbn": "Гэты ISBN не выглядае правільным; праверце правільнасць капіравання з арыгіналу.",
        "specialloguserlabel": "Выканаўца:",
index b795045..3e71fb2 100644 (file)
        "querypage-disabled": "Тази специална страница е изключена, защото затруднява производителността на уикито.",
        "booksources": "Източници на книги",
        "booksources-search-legend": "Търсене на информация за книга",
-       "booksources-go": "Отваряне",
        "booksources-text": "По-долу е списъкът от връзки към други сайтове, продаващи нови и използвани книги или имащи повече информация за книгите, които търсите:",
        "booksources-invalid-isbn": "Предоставеният ISBN изглежда е невалиден; проверете за грешки и копирайте от оригиналния източник.",
        "specialloguserlabel": "Изпълнител:",
index 88aa853..d821b17 100644 (file)
        "querypage-disabled": "Ova posebna stranica je onemogućena jer smanjuje performanse.",
        "booksources": "Štampani izvori",
        "booksources-search-legend": "Traži književne izvore",
-       "booksources-go": "Idi",
        "booksources-text": "Ispod se nalazi spisak vanjskih linkova na ostale stranice koje prodaju nove ili korištene knjige kao i stranice koje mogu da imaju važnije podatke o knjigama koje tražite:",
        "booksources-invalid-isbn": "Navedeni ISBN broj nije validan; molimo da provjerite da li je došlo do greške pri kopiranju iz prvobitnog izvora.",
        "specialloguserlabel": "Izvršilac:",
index 05f985b..9e540d9 100644 (file)
        "querypage-disabled": "Aquesta pàgina especial està desactivada per a no perjudicar el rendiment.",
        "booksources": "Obres de referència",
        "booksources-search-legend": "Cerca fonts de llibres",
-       "booksources-go": "Vés-hi",
        "booksources-text": "A sota hi ha una llista d'enllaços d'altres llocs que venen llibres nous i de segona mà, i també podrien tenir més informació dels llibres que esteu cercant:",
        "booksources-invalid-isbn": "El codi ISBN donat no és vàlid. Comproveu si l'heu copiat correctament.",
        "specialloguserlabel": "Realitzador:",
index 642df57..8d9432f 100644 (file)
        "suppress": "Хьулдар",
        "booksources": "Жайнан хьосташ",
        "booksources-search-legend": "Жайнех лаьцна хаам лахар",
-       "booksources-go": "Лаха",
        "specialloguserlabel": "Декъашхо:",
        "speciallogtitlelabel": "Ӏалашо (цӀе я декъашхо):",
        "log": "Тéптарш",
index f097ee5..9f88265 100644 (file)
        "invalidtitle-knownnamespace": "سەردێڕی نادروست بە بۆشایی ناوی «$2» و دەقی «$3»",
        "invalidtitle-unknownnamespace": "سەردێڕی هەڵە لەگەڵ ناوەبۆشایی نەناسراوی ژمارە $1 و دەقی \"$2\"",
        "exception-nologin": "لەژوورەوە نیت",
-       "exception-nologin-text": "تکایە [[Special:Userlogin|بچۆ ژوورەوە]] تا بتوانیت بچیتە نێو ئەم پەڕەیە یان ئەم کردەیە ئەنجام بدەیت.",
+       "exception-nologin-text": "تکایە بچۆ ژوورەوە تا بتوانی دەستت بەم پەڕەیە یان کردەوەیە ڕابگات.",
        "exception-nologin-text-manual": "تکایە $1 تا بتوانیت بچیتە نێو ئەم پەڕەیە یان ئەم کردەیە ئەنجام بدەیت.",
        "virus-badscanner": "پێکەربەندیی نابەجێ: ڤایرس سکەنێری نەناسراو: ''$1''",
        "virus-scanfailed": "سکەن ئەنجام نەدرا(کۆد $1)",
        "rev-delundel": "نیشان بدە/بشارەوە",
        "rev-showdeleted": "نیشان بدە",
        "revisiondelete": "سڕینەوە/ھێنانەوەی پێداچوونەوەکان",
-       "revdelete-nooldid-title": "Ù\85Û\95بÛ\95ستÛ\8c Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95Û\8c Ù\86ادÛ\8cار",
-       "revdelete-nooldid-text": "پێداچوەنەوەی مەبەستت ڕاچاو نەکردە بۆ ئەنجامی ئەم فەنکشێنە یان ئەو پێداچوونەوەی ڕاچاوت کردە بوونی نیە، یا خەریکی هەوڵی داشاردنی پێداچوونەوهی ئێستا‌ ئەدەی.",
+       "revdelete-nooldid-title": "Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95Û\8c Ù\85Û\95بÛ\95ستÛ\8c Ù\86ادرÙ\88ست",
+       "revdelete-nooldid-text": "پێداچوەنەوە(کان)ی مەبەستت بۆ جێبەجێکردنی ئەم کارە دەستنیشان نەکردووە یان پێداچوونەوەی دەستنیشان‌کراو بوونی نییە، یان خەریکی هەوڵی شاردنەوەی پێداچوونەوەی ھەنووکەیی دەدەیت.",
        "revdelete-no-file": "ئەو پەڕگەی ڕاچاوت کردووە بوونی نیە.",
        "revdelete-show-file-confirm": "ئایا دڵنیایت دەتەوێ پێداچوونەوەی سڕاوەی پەڕگەی \"<nowiki>$1</nowiki>\" لە $2، لە $3دا ببیینی؟",
        "revdelete-show-file-submit": "بەڵێ",
+       "revdelete-selected-text": "{{PLURAL:$1|پێداچوونەوەی ھەڵبژێردراوی|پێداچوونەوە ھەڵبژێردراوەکانی}} [[:$2]]:",
        "logdelete-selected": "{{PLURAL:$1|لۆگی ڕووداوەی هەڵبژێراو|لۆگی ڕووداوە هەڵبژێراوەکان}}:",
-       "revdelete-confirm": "تکایە بەڵێن بدە کە دەتەوێ ئەوە بکەی و لە ئەنجامەکانی ئەوە ئاگاداریت و بە پێی [[{{MediaWiki:Policy-url}}|سیاسەتنامە]] ئەنجامی ئەدەی.",
+       "revdelete-text-text": "پێداچوونە سڕاوەکان ھێشتا لە مێژووی پەڕەدا دەردەکەوێت بەڵام بەشێک لە ناوەرۆکەکەیان بۆ ھەمووان لەبەر دەست دەبێت.",
+       "revdelete-text-file": "وەشانە سڕاوەکانی پەڕگە ھێشتا لە مێژووی پەڕگەدا دەردەکەوێت بەڵام بەشێک لە ناوەرۆکەکەیان بۆ ھەمووان لەبەر دەست دەبێت.",
+       "logdelete-text": "ڕووداوە سڕاوەکانی لۆگ ھێشتا لە لۆگەکاندا دەردەکەوێت بەڵام بەشێک لە ناوەرۆکەکەیان بۆ ھەمووان لەبەر دەست دەبێت.",
+       "revdelete-text-others": "بەڕێوەبەرانی تر ھێشتا دەتوانن ناوەرۆکی شاردراو ببینن و بیھێننەوە، مەگەر سنووردارکردنی تر ڕێک بخرێت.",
+       "revdelete-confirm": "تکایە پشتڕاست بکەوە دەتەوێ ئەمە بکەیت و لە ئاکامەکەی ئاگاداریت و ئەمە بە پێی [[{{MediaWiki:Policy-url}}|سیاسەتنامە]] دەکەیت.",
        "revdelete-suppress-text": "بەرگری دەبێ '''تەنها''' بۆ ئەم بابەتانە بەکاربهێندرێت:<br />\n* سووکایەتیکردن بە کەسایەتییەک<br />\n* بڵاوکردنەوەی زانیاریی تاکەکەسی نەگونجاو<br />\n*: '' ناونیشانی ماڵ یا ژمارە تەلەفۆن و وەک ئەمانە.''<br />",
-       "revdelete-legend": "سنووردارکردنی دەرکەوتن",
+       "revdelete-legend": "ڕێکخستنی سنووردارکردنی دیاریکردن",
        "revdelete-hide-text": "دەقی پێداچوونەوە",
        "revdelete-hide-image": "ناوەڕۆکی پەڕگە بشارەوە",
        "revdelete-hide-name": "داشاردنی مەبەست و کردەوە",
        "revdelete-suppress": "بەرگری دراوە لە بەڕێوبەران هەر وەک ئەوانی دیکە",
        "revdelete-unsuppress": "لابردنی بەربەستەکان لە سەر پێداچوونەوە گەڕێندراوەکان",
        "revdelete-log": "هۆکار:",
-       "revdelete-submit": "خستÙ\86Û\95کار Ø¨Û\86 Ø³Û\95ر Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95 {{PLURAL:$1|Ú¾Û\95ڵبÚ\98Û\8eردراÙ\88Û\95Ú©Û\95|ھەڵبژێردراوەکان}}",
+       "revdelete-submit": "بÛ\95کاربÛ\95رÛ\95 Ø¨Û\86 Ø³Û\95ر {{PLURAL:$1|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95Û\8c Ú¾Û\95ڵبÚ\98Û\8eردراÙ\88|Ù¾Û\8eداÚ\86Ù\88Ù\88Ù\86Û\95Ù\88Û\95 ھەڵبژێردراوەکان}}",
        "revdelete-success": "'''چۆنیەتی بیندرانی پێداچوونەوە بە سەرکەوتوویی نوێکراوە.'''",
        "revdelete-failure": "'''ناکرێ دەرکەوتنی پێداچوونەوە نوێبکرێتەوە:'''\n$1",
        "logdelete-success": "'''بیندرانی لۆگ‌ بە سەرکەوتوویی داندرا.'''",
        "difference-multipage": "(جیاوازی نێوان پەڕەکان)",
        "lineno": "ھێڵی  $1:",
        "compareselectedversions": "پیاچوونەوە ھەڵبژێردراوەکان ھەڵسەنگێنە",
-       "showhideselectedversions": "پیاچوونەوە ھەڵبژێردراوەکان نیشانبدە/بشارەوە",
+       "showhideselectedversions": "دیاریکردنی پێداچوونەوە ھەڵبژێردراوەکان بگۆڕە",
        "editundo": "پووچەڵکردنەوە",
        "searchresults": "ئاکامەکانی گەڕان",
        "searchresults-title": "ئاکامەکانی گەڕان بۆ «$1»",
        "search-section": "(بەشی $1)",
        "search-suggest": "ئایا مەبەستت ئەمە بوو: $1",
        "search-interwiki-caption": "پرۆژە خوشکەکان",
-       "search-interwiki-default": "$1 ئەنجام:",
+       "search-interwiki-default": "ئاکام لە $1:",
        "search-interwiki-more": "(زیاتر)",
        "search-relatedarticle": "پەیوەست",
        "searchrelated": "پەیوەست",
        "searchall": "ھەموو",
        "showingresults": "لە خوارەوە {{PLURAL:$1|'''یەک''' ئەنجام|'''$1''' ئەنجام}} نیشان دراوە، بە دەست پێ کردن لە ژمارەی '''$2'''ەوە.",
+       "search-showingresults": "{{PLURAL:$4|ئاکامی <strong>$1</strong> لە <strong>$3</strong>|ئاکامەکانی <strong>$1 - $2</strong> لە <strong>$3</strong>}}",
        "search-nonefound": "ھیچ ئاکامێک کە بە داواکارییەکەت بخوا نەدۆزرایەوە.",
        "powersearch-legend": "گەڕانی پێشکەوتوو",
        "powersearch-ns": "گەڕان لە بۆشاییی ناوەکانی:",
        "recentchanges-legend-heading": "'''کورتکراوەکان:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ھەروەھا بڕوانە [[Special:NewPages|پێرستی پەڕە نوێکان]])",
        "recentchanges-legend-plusminus": "(''±۱٢٣'')",
-       "rcnotefrom": "ژێرەوە گۆڕانکارییەکانە لە <strong>$2</strong>ەوە (ھەتا <strong>$1</strong> نیشان دراوە).",
+       "rcnotefrom": "ژێرەوە {{PLURAL:$5|گۆڕانکارییەکەیە|گۆڕانکارییەکانە}} لە strong>$3، $4</strong>ەوە (ھەتا <strong>$1</strong> نیشان دراوە).",
        "rclistfrom": "گۆڕانکارییە نوێکان نیشان بدە بە دەستپێکردن لە $3 $2",
        "rcshowhideminor": "دەستکارییە بچووکەکان $1",
        "rcshowhideminor-show": "نیشان بدە",
        "suppress": "چاودێری",
        "booksources": "سەرچاوەکانی کتێب",
        "booksources-search-legend": "بۆ سەرچاوەی کتێب بگەڕێ",
-       "booksources-go": "بڕۆ",
        "booksources-text": "لە خوارەوە لیستێک لە بەستەر بۆ ماڵپەڕهایەک کە کتێبی نوێ و بەکارهێنراو دەفرۆشێت و لەوانەیە لەوێ زانیاریی زیاترت دەست‌کەوێت سەبارەت بەو کتێبانەی لە دووی دەگەڕیت:",
        "booksources-invalid-isbn": "ISBN دراو لەوە ناچی بەکار بێت، سەرنج بدە لە کاتی کۆپی کردن لە سەرچاوە تووشی هەڵە نوبوبێت.",
        "specialloguserlabel": "بەجێھێنەر:",
        "alllogstext": "نیشاندانی تێکڕای هەموو لۆگە بەردەستەکانی {{SITENAME}}.\nدەتوانی بە ھەڵبژاردنی جۆرە لۆگێک، ناوی بەکارھێنەرەکە (ھەستیار بە گەورە و بچووکی پیتەکان) یان پەڕە کارتێکراوەکە (ھەستیار بە گەورە و بچووکی پیتەکان)\nبینینەکە سنووردار بکەیتەوە.",
        "logempty": "هیچ بابەتێکی هاوتا لە لۆگەکاندا نەدۆزرایەوە.",
        "log-title-wildcard": "گەڕانی ئەو سەرناوانە بەم دەقەوە دەست پێدەکەن",
-       "showhideselectedlogentries": "بابÛ\95تÛ\95کاÙ\86Û\8c Ú¾Û\95ڵبÚ\98Û\8eردراÙ\88Û\8c Ù\84Û\86Ú¯ Ù\86Û\8cشاÙ\86 Ø¨Ø¯Û\95/بشارÛ\95Ù\88ە",
+       "showhideselectedlogentries": "دÛ\8cارÛ\8cکردÙ\86Û\8c Ø¨Ø§Ø¨Û\95تÛ\95 Ú¾Û\95ڵبÚ\98Û\8eردراÙ\88Û\95کاÙ\86Û\8c Ù\84Û\86Ú¯ Ø¨Ú¯Û\86Ú\95ە",
        "allpages": "ھەموو پەڕەکان",
        "nextpage": "پەڕەی پاشەوە ($1)",
        "prevpage": "پەڕەی پێشەوە ($1)",
        "deletecomment": "ھۆکار:",
        "deleteotherreason": "ھۆکاری تر/زیاتر:",
        "deletereasonotherlist": "ھۆکاری تر",
-       "deletereason-dropdown": "* Ú¾Û\86کارÛ\8c Ø³Ú\95Û\8cÙ\86Û\95Ù\88Û\95\n** Ø¯Ø§Ù\88اکارÛ\8cÛ\8c Ù\86Ù\88Ù\88سÛ\95ر\n** ØªÛ\8eکداÙ\86Û\8c Ù\85اÙ\81Û\8c Ù\84Û\95بÛ\95رگرتÙ\86Û\95Ù\88Û\95\n** Ø®Ø±Ø§Ù¾Ú©Ø§Ø±Û\8c",
+       "deletereason-dropdown": "* Ú¾Û\86کارÛ\95 Ø¨Ø§Ù\88Û\95کاÙ\86Û\8c Ø³Ú\95Û\8cÙ\86Û\95Ù\88Û\95\n** Ø³Ù¾Ø§Ù\85\n** Ø®Ø±Ø§Ù¾Ú©Ø§Ø±Û\8c\n** Ù¾Û\8eØ´Û\8eÙ\84کردÙ\86Û\8c Ù\85اÙ\81Û\8c Ù\84Û\95بÛ\95رگرتÙ\86Û\95Ù\88Û\95\n** Ø¯Ø§Ø®Ù\88ازÛ\8c Ø¯Ø§Ù\86Û\95ر\n** Ú\95Û\95Ù\88اÙ\86Û\95Ú©Û\95رÛ\8c Ø´Ú©Ø§Ù\88",
        "delete-edit-reasonlist": "دەستکاری کردنی ھۆکارەکانی سڕینەوە",
        "delete-toobig": "ئەم لاپەڕە مێژوویەکی دەستکاری زۆر گەورەی هەیە، زیاتر لە $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}.\nبۆ بەرگری لە خراپ‌بوونی چاوەڕوان نەکراوی {{SITENAME}}، سڕینەوەی لاپەڕەی وا بەربەست‌کراوە.",
        "delete-warning-toobig": "ئەم لاپەڕە مێژوویەکی دەستکاری زۆر گەورەی هەیە، زیاتر لە $1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}}.\nسڕینەوی ئەوە لە وانەیە کارەکانی بنکەدراوی {{SITENAME}} تووشی کێشە بکات؛\nدوورنواڕانە جێ‌بەجێی بکە.",
        "whatlinkshere-filters": "پاڵێوکەکان",
        "block": "بەربەستنی بەکارھێنەر",
        "unblock": "لە بەربەست‌دەرهێنانی بەکارهێنەر",
-       "blockip": "بەربەستنی بەکارھێنەر",
+       "blockip": "بەربەستنی {{GENDER:$1|بەکارھێنەر}}",
        "blockip-legend": "بەربەست‌کردنی بەکارهێنەر",
        "blockiptext": "لەم فۆرمەی خوارەوە دەتوانی بۆ بەربەست‌کردنی دەست‌پێ‌گەیشتنی نووسین لە ناونیشانێکی ئای‌پی تایبەت یا ناوی بەکارهێنەریەک، کەڵک وەرگریت.\nئەمە تەنها دەبێ بۆ بەرگری لە خراپکاری بەکاربێت و ڕێکەوتنی هەبێ دەگەڵ [[{{MediaWiki:Policy-url}}|سیاسەتەکان]].\nلە خوارەوە هۆکارێک بە ڕوونی بنووسە (بۆ نموونە بە وردی ئەو لاپەڕانە و خراپکاری تێدا کراوە وەک، وەک بەڵگە، بنووسە).",
        "ipaddressorusername": "ناونیشانی ئایپی یان ناوی‌ بەکارھێنەر:",
        "ipb-unblock-addr": "لە بەربەست‌دەرهێنانی $1",
        "ipb-unblock": "لە بەربەست‌دەرهێنانی ناوی بەکارهێنەریەک یا ناونیشانێکی ئای‌پی",
        "ipb-blocklist": "دیتنی ئەو بەربەستانەی وا هەیە",
-       "ipb-blocklist-contribs": "بەشدارییەکانی $1",
+       "ipb-blocklist-contribs": "بەشدارییەکانی {{GENDER:$1|$1}}",
        "unblockip": "لە بەربەست‌دەرهێنانی بەکارهێنەر",
        "unblockiptext": "بۆ گەڕاندنەوەی دەست‌پی‌گەیشتنی نووسین بۆ ئەو دوایین ئای‌پی یان بەکارهێنەری بەربەست کراوە، لەو فۆرمەی خوارەوە کەڵک وەرگرە.",
        "ipusubmit": "لابردنی ئەم بەربەستە",
        "import-upload": "بارکردنی دراوەی XML",
        "import-token-mismatch": "لەدەستدانی دراوەکانی کۆڕ.\nتکایە دیسان تاقی بکەوە.",
        "import-invalid-interwiki": "لە ویکی‌ دیاریکراو ھاوردن ناکرێ.",
-       "import-error-edit": "پەڕەی «$1» ھاوردە ناکرێ، چون ناتوانی ئەم پەڕەیە دەستکاری بکەی.",
-       "import-error-create": "پەڕەی «$1» ھاوردە ناکرێ، چون ناتوانی ئەم پەڕەیە دروست بکەی.",
-       "import-error-interwiki": "پەڕەی «$1» ھاوردە ناکرێ چون ناوەکەی بۆ بەستەری دەرەکیی (interwiki) گیراوەتەوە.",
-       "import-error-special": "پەڕەی «$1» ھاوردە ناکرێ چون لە بۆشاییی ناوی نەگونجاودایە.",
+       "import-error-edit": "پەڕەی «$1» ھاوردە نەکرا، چون ناتوانی ئەم پەڕەیە دەستکاری بکەی.",
+       "import-error-create": "پەڕەی «$1» ھاوردە نەکرا، چون ناتوانی ئەم پەڕەیە دروست بکەی.",
+       "import-error-interwiki": "پەڕەی «$1» ھاوردە نەکرا چون ناوەکەی بۆ بەستەری دەرەکیی (interwiki) گیراوەتەوە.",
+       "import-error-special": "پەڕەی «$1» ھاوردە نەکرا چون لە بۆشاییی ناوی نەگونجاودایە.",
        "import-error-invalid": "پەڕەی «$1» ھاوردە ناکرێ چون ناوەکەی نادروستە.",
        "importlogpage": "لۆگی ھاوردن",
        "importlogpagetext": "ھاوردنی پەڕەکان لەگەڵ مێژووی دەستکاری لە ویکییەکانی ترەوە.",
        "import-logentry-upload": "[[$1]]ی بە بارکردنی پەڕگە ھاورد",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|پێداچوونەوە}}",
+       "import-logentry-upload-detail": "$1 {{PLURAL:$1|پێداچوونەوە}} ھاوردە کرا",
        "import-logentry-interwiki": "$1ی ناوویکی کرد",
-       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|پێداچوونەوە}} لە $2",
+       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|پێداچوونەوە}} لە $2 ھاوردە کرا",
        "javascripttest": "تاقیکردنەوەی جاڤاسکریپت",
        "tooltip-pt-userpage": "پەڕەی بەکارھێنەرییەکەت",
        "tooltip-pt-anonuserpage": "پەڕەی بەکارھێنەری بۆ ئای‌پی یەکە کە بەناویەوە خەریکی دەستکاری کردنی",
index 3795d95..a10a58d 100644 (file)
        "querypage-disabled": "Tato speciální stránka je z výkonnostních důvodů vypnuta.",
        "booksources": "Zdroje knih",
        "booksources-search-legend": "Vyhledat knižní zdroje",
-       "booksources-go": "Vyhledat",
        "booksources-text": "Níže je seznam odkazů na servery prodávající knihy, nebo které mohou mít další informace o knihách, které hledáte.",
        "booksources-invalid-isbn": "Zadané ISBN se zdá být neplatné. Zkontrolujte jej s originálním zdrojem.",
        "specialloguserlabel": "Původce:",
index 1986965..8ce0dc8 100644 (file)
@@ -82,7 +82,7 @@
        "tog-hideminor": "Kleine Änderungen in den „Letzten Änderungen“ ausblenden",
        "tog-hidepatrolled": "Kontrollierte Änderungen in den „Letzten Änderungen“ ausblenden",
        "tog-newpageshidepatrolled": "Kontrollierte Seiten bei den „Neuen Seiten“ ausblenden",
-       "tog-extendwatchlist": "Beobachtungsliste erweitern, um statt nur der letzten Änderung alle Änderungen anzuzeigen.",
+       "tog-extendwatchlist": "Alle, und nicht nur die aktuellsten Änderungen in der Beobachtungsliste anzeigen",
        "tog-usenewrc": "Änderungen auf „Letzte Änderungen“ und der Beobachtungsliste nach Seite gruppieren",
        "tog-numberheadings": "Überschriften automatisch nummerieren",
        "tog-showtoolbar": "Bearbeiten-Werkzeugleiste anzeigen",
        "querypage-disabled": "Diese Spezialseite wurde aus Gründen der Leistungserhaltung deaktiviert.",
        "booksources": "ISBN-Suche",
        "booksources-search-legend": "Suche nach Bezugsquellen für Bücher",
-       "booksources-go": "Suchen",
+       "booksources-search": "Suchen",
        "booksources-text": "Dies ist eine Liste mit Links zu Internetseiten, die neue und gebrauchte Bücher verkaufen. Dort kann es auch weitere Informationen über die Bücher geben. {{SITENAME}} ist mit keinem dieser Anbieter geschäftlich verbunden.",
        "booksources-invalid-isbn": "Vermutlich ist die ISBN ungültig.\nBitte prüfe, ob sie korrekt von der Quelle übertragen wurde.",
        "specialloguserlabel": "Ausführender Benutzer:",
index 6997657..2ad15de 100644 (file)
        "booksources": "Çımeyê kıtaban",
        "booksources-search-legend": "Seba çımeyanê kıtaban cı geyre",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Şo",
        "booksources-text": "listeya cêrıni, keyepelê kitap rotoxan o.",
        "booksources-invalid-isbn": "ISBN raşt nêasena bıewnê çımeyê orjinali, raşt kopya biya nê nêbiyaya?",
        "specialloguserlabel": "Kerdoğ:",
index 34a90e3..afb65f1 100644 (file)
        "pager-older-n": "{{PLURAL:$1|1 al pió vèc|$1 i pió vèc}}",
        "booksources": "Tèst o documèint da léber.",
        "booksources-search-legend": "Sērca 'd documèint insém a di léber",
-       "booksources-go": "Và",
        "log": "Regéster",
        "allpages": "Tót al pàgini.",
        "allarticles": "Tót al pàgini.",
index cb519c3..e32a1b4 100644 (file)
        "booksources": "Πηγές βιβλίων",
        "booksources-search-legend": "Αναζήτηση για πηγές βιβλίων",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Μετάβαση",
        "booksources-text": "Παρακάτω είναι μια λίστα συνδέσμων σε άλλους ιστοτόπους οι οποίοι πωλούν νέα και μεταχειρισμένα βιβλία, και μπορεί επίσης να έχουν περισσότερες πληροφορίες για βιβλία για τα οποία ψάχνετε:",
        "booksources-invalid-isbn": "Το δοσμένο ISBN δεν φαίνεται να είναι έγκυρο· ελέγξτε για λάθη κατά την αντιγραφή από την αρχική πηγή.",
        "specialloguserlabel": "",
index 8b6e66b..12d1429 100644 (file)
        "blocked-mailpassword": "Your IP address is blocked from editing, and so is not allowed to use the password recovery function to prevent abuse.",
        "eauthentsent": "A confirmation email has been sent to the specified email address.\nBefore any other email is sent to the account, you will have to follow the instructions in the email, to confirm that the account is actually yours.",
        "throttled-mailpassword": "A password reset email has already been sent, within the last {{PLURAL:$1|hour|$1 hours}}.\nTo prevent abuse, only one password reset email will be sent per {{PLURAL:$1|hour|$1 hours}}.",
-       "loginstart": "",
-       "loginend": "",
-       "loginend-https": "",
-       "signupstart": "{{int:loginstart}}",
-       "signupend": "{{int:loginend}}",
+       "signupstart": "",
+       "signupend": "",
        "signupend-https": "",
        "mailerror": "Error sending mail: $1",
        "acct_creation_throttle_hit": "Visitors to this wiki using your IP address have created {{PLURAL:$1|1 account|$1 accounts}} in the last day, which is the maximum allowed in this time period.\nAs a result, visitors using this IP address cannot create any more accounts at the moment.",
        "booksources-summary": "",
        "booksources-search-legend": "Search for book sources",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Go",
+       "booksources-search": "Search",
        "booksources-text": "Below is a list of links to other sites that sell new and used books, and may also have further information about books you are looking for:",
        "booksources-invalid-isbn": "The given ISBN does not appear to be valid; check for errors copying from the original source.",
        "rfcurl": "//tools.ietf.org/html/rfc$1",
index b4fed87..056acee 100644 (file)
        "querypage-disabled": "Tiu ĉi speciala paĝo estas malfunkciigita pro rendimentaj kialoj.",
        "booksources": "Libroservoj",
        "booksources-search-legend": "Serĉi librofontojn",
-       "booksources-go": "Ek",
        "booksources-text": "Jen ligilaro al aliaj TTT-ejoj, kiuj vendas librojn,\nkaj/aŭ informumos pri la libro ligita.\nLa {{SITENAME}} ne estas komerce ligita al tiuj vendejoj, kaj la listo ne estu\nkomprenata kiel rekomendo aŭ reklamo.",
        "booksources-invalid-isbn": "La donata ISBN verŝajne estas nevalida; kontrolu pri erara kopiado el la originala fonto.",
        "specialloguserlabel": "Faranto:",
index 49afad0..241447a 100644 (file)
                        "AVIADOR",
                        "F3RaN",
                        "Amitie 10g",
-                       "Eurodyne"
+                       "Eurodyne",
+                       "Gleki"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "viewhelppage": "Ver página de ayuda",
        "categorypage": "Ver página de categoría",
        "viewtalkpage": "Ver discusión",
-       "otherlanguages": "Otros idiomas",
+       "otherlanguages": "En otros idiomas",
        "redirectedfrom": "(Redirigido desde «$1»)",
        "redirectpagesub": "Página de redirección",
        "redirectto": "Redirigir a:",
        "querypage-disabled": "Esta página especial está deshabilitada por motivos de rendimiento.",
        "booksources": "Fuentes de libros",
        "booksources-search-legend": "Buscar fuentes de libros",
-       "booksources-go": "Ir",
        "booksources-text": "Abajo hay una lista de enlaces a otros sitios que venden libros nuevos y usados, puede que contengan más información sobre los libros que estás buscando.",
        "booksources-invalid-isbn": "El número de ISBN no parece ser válido; comprueba los errores copiándolo de la fuente original.",
        "specialloguserlabel": "Usuario:",
index 5c9ce5f..db6308f 100644 (file)
        "prefs-tokenwatchlist": "Luba",
        "prefs-diffs": "Erinevused",
        "prefs-help-prefershttps": "See eelistus jõustub pärast järgmist sisselogimist.",
+       "prefswarning-warning": "Oled teinud eelistustes muudatusi, mida pole veel salvestatud.\nKui lahkud sellelt leheküljelt ilma nupul \"$1\" klõpsamata, jäävad kehtima senised eelistused.",
        "prefs-tabs-navigation-hint": "Spikker: Kaardiloendis toodud kaartide vahel liikumiseks saad kasutada vasakut ja paremat nooleklahvi.",
        "email-address-validity-valid": "Sobiv e-posti aadress",
        "email-address-validity-invalid": "Sisesta sobiv e-posti aadress.",
        "querypage-disabled": "See erilehekülg on keelatud, et jõudlust hoida.",
        "booksources": "Raamatuotsimine",
        "booksources-search-legend": "Raamatuotsimine",
-       "booksources-go": "Mine",
+       "booksources-search": "Otsi",
        "booksources-text": "Allpool on linke teistele lehekülgedele, kus müüakse uusi ja kasutatud raamatuid. Lehekülgedel võib olla ka lisainfot raamatute kohta:",
        "booksources-invalid-isbn": "Antud ISBN-number ei ole korrektne; kontrolli algallikast kopeerides vigu.",
        "specialloguserlabel": "Täitja:",
        "protect-othertime": "Muu aeg:",
        "protect-othertime-op": "muu aeg",
        "protect-existing-expiry": "Kehtiv aegumisaeg: $2 kell $3",
+       "protect-existing-expiry-infinity": "Kehtiv aegumisaeg: igavene",
        "protect-otherreason": "Muu või täiendav põhjus:",
        "protect-otherreason-op": "Muu põhjus",
        "protect-dropdown": "*Tavalised kaitsmise põhjused\n** Liigne vandalism\n** Liigne rämpspostitamine\n** Redigeerimissõja pidamine\n** Suure liiklusega lehekülg",
        "version-ext-colheader-credits": "Autorid",
        "version-license-title": "Tarkvaralisa $1 litsents",
        "version-license-not-found": "Selle lisa kohta ei leitud üksikasjalikku litsentsiteavet.",
-       "version-credits-title": "Tarkvaralisa $1 tegijad",
+       "version-credits-title": "Tarkvarakomponendi $1 tegijad",
        "version-credits-not-found": "Selle lisa tegijate kohta ei leitud üksikasjalikku teavet.",
        "version-poweredby-credits": "See viki kasutab '''[https://www.mediawiki.org/ MediaWiki]''' tarkvara. Autoriõigus © 2001–$1 $2.",
        "version-poweredby-others": "teised",
        "default-skin-not-found": "Oih! Sinu viki vaikekujundus, milleks muutuja <code dir=\"ltr\">$wgDefaultSkin</code> järgi on <code>$1</code>, pole saadaval.\n\nPaistab, et sinu install sisaldab järgmisi kujundusi. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas neid lubada ja kuidas valida vaikekujundus.\n\n$2\n\n; Kui oled MediaWiki just paigaldanud:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code dir=\"ltr\">skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja.\n\n; Kui oled MediaWikit just täiendanud:\n: MediaWiki 1.24-s ja uuemates versioonides pole paigaldatud kujundused enam automaatselt lubatud (vaata juhendist [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery kujunduste automaatse leidmise] kohta). Saad kleepida järgmised read leheküljele <code>LocalSettings.php</code>, et lubada kõik praegu paigaldatud kujundused:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Kui oled lehekülge <code>LocalSettings.php</code> just muutnud:\n: Kontrolli üle, ega kujunduste nimedes pole trükivigu.",
        "default-skin-not-found-no-skins": "Oih! Sinu viki vaikekujundus, milleks muutuja <code dir=\"ltr\">$wgDefaultSkin</code> järgi on <code>$1</code>, pole saadaval.\n\nÜhtegi kujundust pole paigaldatud.\n\n; Kui oled MediaWiki just paigaldanud või täiendasid seda:\n: Paigaldasid tarkvara ilmselt Giti kaudu või otse lähtekoodist või mõnel muul viisil. See on ootuspärane. MediaWiki 1.24 ja uuemad versioonid ei sisalda peahoidlas ühtegi kujundust. Proovi [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org-i kujunduste kataloogist] mõni kujundus paigaldada. Selleks saad:\n:* laadida alla [https://www.mediawiki.org/wiki/Download lintarhiivi paigaldaja], mis sisaldab mitut kujundust ja tarkvaralisa. Saad sealt kleepimiseks kopeerida kausta <code dir=\"ltr\">skins/</code>;\n:* kopeerida Giti kaudu ühe hoidla (<code>mediawiki/skins/*</code>) oma MediaWiki installi kausta <code>skins/</code>.\n: Selle tegemine ei tohiks häirida Giti hoidlat, kui oled MediaWiki arendaja. Vaata [https://www.mediawiki.org/wiki/Manual:Skin_configuration kujunduste häälestusjuhendist], kuidas kujundusi lubada ja kuidas valida vaikekujundus.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (lubatud)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''keelatud''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''keelatud''')",
+       "mediastatistics": "Meediafailide arvandmestik",
+       "mediastatistics-summary": "Arvandmed üles laaditud failitüüpide kohta. See käib ainult failide viimaste versioonide kohta. Vanu ja kustutatud versioone pole arvesse võetud.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 bait|$1 baiti}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIME tüüp",
+       "mediastatistics-table-extensions": "Võimalikud laiendid",
+       "mediastatistics-table-count": "Failide arv",
+       "mediastatistics-table-totalbytes": "Suurus kokku",
+       "mediastatistics-header-unknown": "Teadmata",
+       "mediastatistics-header-bitmap": "Rasterpildid",
+       "mediastatistics-header-drawing": "Vektorjoonised",
+       "mediastatistics-header-audio": "Helifailid",
+       "mediastatistics-header-video": "Videofailid",
+       "mediastatistics-header-multimedia": "Rikasmeedia failid",
+       "mediastatistics-header-office": "Kontoritarkvara failid",
+       "mediastatistics-header-text": "Tekstifailid",
+       "mediastatistics-header-executable": "Täitmisfailid",
+       "mediastatistics-header-archive": "Tihendatud vormingud"
 }
index a38b679..754bb49 100644 (file)
        "changeemail-oldemail": "نشانی رایانامهٔ کنونی:",
        "changeemail-newemail": "نشانی رایانامهٔ تازه:",
        "changeemail-none": "(هیچ)",
-       "changeemail-password": " {{SITENAME}} رمز عبور شما:",
+       "changeemail-password": "گذرواژهٔ {{SITENAME}} شما:",
        "changeemail-submit": "تغییر رایانامه",
        "changeemail-throttled": "شما به مراتب برای ورود تلاش کرده‌اید.\nلطفاً پیش از آنکه دوباره تلاش کنید $1 صبر کنید.",
        "resettokens": "بازنشانی شناساننده‌ها",
        "difference-multipage": "(تفاوت بین صفحات)",
        "lineno": "سطر $1:",
        "compareselectedversions": "مقایسهٔ نسخه‌های انتخاب‌شده",
-       "showhideselectedversions": "تغییر پدیداری بازبینی‌های انتخاب‌شده",
+       "showhideselectedversions": "تغییر پدیداری نسخه‌های انتخاب‌شده",
        "editundo": "خنثی‌سازی",
        "diff-empty": "(بدون تفاوت)",
        "diff-multi-sameuser": "({{PLURAL:$1|یک نسخهٔ میانی|$1 نسخهٔ میانی}} توسط کاربر مشابهی که نشان داده نشده)",
        "searchrelated": "مرتبط",
        "searchall": "همه",
        "showingresults": "نمایش حداکثر {{PLURAL:$1|'''۱''' نتیجه|'''$1''' نتیجه}} در پایین، آغاز از شماره '''$2'''.",
-       "showingresultsinrange": "نمایش در پائین تا {{PLURAL:$1|<strong>1</strong> نتیجه|<strong>$1</strong> نتیجه}} in range #<strong>$2</strong> تا #<strong>$3</strong>.",
+       "showingresultsinrange": "نمایش در پائین تا {{PLURAL:$1|<strong>1</strong> نتیجه|<strong>$1</strong> نتیجه}} در محدودهٔ #<strong>$2</strong> تا #<strong>$3</strong>.",
        "search-showingresults": "{{PLURAL:$4|نتایج <strong>$1</strong> از <strong>$3</strong>|نتایج <strong>$1 - $2</strong از <strong>$3</strong>}}",
        "search-nonefound": "نتیجه‌ای منطبق با درخواست پیدا نشد.",
        "powersearch-legend": "جستجوی پیشرفته",
        "booksources": "منابع کتاب",
        "booksources-search-legend": "جستجوی منابع کتاب",
        "booksources-isbn": "شابک:",
-       "booksources-go": "برو",
+       "booksources-search": "جستجو",
        "booksources-text": "در زیر فهرستی از پیوندها به وبگاه‌های دیگر آمده‌است که کتاب‌های نو و دست دوم می‌فروشند، و همچنین ممکن است اطلاعات بیشتری راجع به کتاب مورد نظر شما داشته باشند:",
        "booksources-invalid-isbn": "شابک داده شده مجاز به نظر نمی‌رسد؛ از جهت اشکالات هنگام کپی کردن از منبع اصلی بررسی کنید.",
        "specialloguserlabel": "مجری:",
index c062351..985206d 100644 (file)
        "enhancedrc-history": "historia",
        "recentchanges": "Tuoreet muutokset",
        "recentchanges-legend": "Tuoreiden muutosten asetukset",
-       "recentchanges-summary": "Tällä sivulla voi seurata tuoreita {{GRAMMAR:illative|{{SITENAME}}}} tehtyjä muutoksia.",
+       "recentchanges-summary": "Tällä sivulla voi seurata tuoreita tähän wikiin tehtyjä muutoksia.",
        "recentchanges-noresult": "Ei muutoksia, jotka täyttävät nämä kriteerit valitun ajanjakson aikana.",
        "recentchanges-feed-description": "Tällä sivulla voi seurata tuoreita {{GRAMMAR:illative|{{SITENAME}}}} tehtyjä muutoksia.",
        "recentchanges-label-newpage": "Tämä muutos loi uuden sivun",
        "booksources": "Kirjalähteet",
        "booksources-search-legend": "Etsi kirjalähteitä",
        "booksources-isbn": "ISBN",
-       "booksources-go": "Siirry",
        "booksources-text": "Alla linkkejä ulkopuolisiin sivustoihin, joilla myydään uusia ja käytettyjä kirjoja. Sivuilla voi myös olla lisätietoa kirjoista.",
        "booksources-invalid-isbn": "Annettu ISBN-numero ei ole kelvollinen. Tarkista alkuperäisestä lähteestä kirjoitusvirheiden varalta.",
        "specialloguserlabel": "Suorittaja:",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|muutti}} sivun kieltä sivulla $3 kielestä $4 kieleksi $5.",
        "default-skin-not-found": "Hupsista! Oletuksena tuleva ulkoasu sinun wikillesi, joka on määritelty koodissa <code dir=\"ltr\">$wgDefaultSkin</code> muotoon <code>$1</code>, ei ole saatavilla.\n\n\n<strong>Alla on ohjeita englanniksi:</strong>\n\n\nYour installation seems to include the following skins. See [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] for information how to enable them and choose the default.\n\n$2\n\n; If you have just installed MediaWiki: \n: You probably installed from git, or directly from the source code using some other method. This is expected. Try installing some skins from [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory], by: :* Downloading the [https://www.mediawiki.org/wiki/Download tarball installer], which comes with several skins and extensions. You can copy and paste the <code>skins/</code> directory from it. \n:* Cloning one of the <code>mediawiki/skins/*</code> repositories via git into the <code>skins/</code> directory of your MediaWiki installation. \n: Doing this should not interfere with your git repository if you're a MediaWiki developer.\n\n\n; If you have just upgraded MediaWiki: \n: MediaWiki 1.24 and newer no longer automatically enables installed skins (see [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). You can paste the following lines into <code>LocalSettings.php</code> to enable all currently installed skins:\n\n<pre>$3</pre>\n\n; If you have just modified <code>LocalSettings.php</code>: \n: Double-check the skin names for typos.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (käytössä)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ei käytössä''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''ei käytössä''')",
+       "mediastatistics-header-video": "Videot"
 }
index d04d9e5..50dfb0b 100644 (file)
        "booksources": "Ouvrages de référence",
        "booksources-search-legend": "Rechercher parmi des ouvrages de référence",
        "booksources-isbn": "ISBN :",
-       "booksources-go": "Lister",
+       "booksources-search": "Rechercher",
        "booksources-text": "Voici une liste indicative de liens vers d’autres sites vendant des livres neufs et d’occasion et sur lesquels vous trouverez peut-être des informations sur les ouvrages que vous cherchez :",
        "booksources-invalid-isbn": "L’ISBN donné ne semble pas être correct ; vérifiez si vous avez fait une erreur en copiant la source originale.",
        "specialloguserlabel": "Auteur :",
        "sorbs_create_account_reason": "Votre adresse IP est listée comme mandataire ouvert dans le DNSBL utilisé par {{SITENAME}}.\nVous ne pouvez pas créer un compte.",
        "xffblockreason": "Une adresse IP dans l'en-tête X-Forwarded-For, soit la vôtre ou celle d'un serveur proxy que vous utilisez, a été bloquée. La raison du blocage initial est : $1",
        "cant-see-hidden-user": "L’utilisateur que vous tentez de bloquer a déjà été bloqué et masqué. N’ayant pas le droit ''hideuser'', vous ne pouvez pas voir ou modifier le blocage de cet utilisateur.",
-       "ipbblocked": "Vous ne pouvez pas bloquer ou débloquer d'autres utilisateurs, parce que vous êtes vous-même bloqué{{GENDER:||e|(e)}",
+       "ipbblocked": "Vous ne pouvez pas bloquer ou débloquer d'autres utilisateurs, parce que vous êtes vous-même bloqué{{GENDER:||e|}",
        "ipbnounblockself": "Vous n'êtes pas autorisé{{GENDER:||e}} à vous débloquer vous-même",
        "lockdb": "Verrouiller la base de données",
        "unlockdb": "Déverrouiller la base de données",
index 42bf7e9..457f851 100644 (file)
        "passwordreset-email": "Seoladh ríomhphoist:",
        "changeemail-none": "(neamhní)",
        "changeemail-password": "D'fhocal faire {{SITENAME}}:",
-       "changeemail-cancel": "Cealaigh",
        "bold_sample": "Cló trom",
        "bold_tip": "Cló trom",
        "italic_sample": "Cló iodálach",
        "pager-older-n": "{{PLURAL:$1|1 níos sine|$1 níos sine}}",
        "booksources": "Leabharfhoinsí",
        "booksources-search-legend": "Cuardaigh le foinsí leabhar",
-       "booksources-go": "Gabh",
        "specialloguserlabel": "Úsáideoir:",
        "speciallogtitlelabel": "Teideal:",
        "log": "Logaí",
index cd72433..786cfcf 100644 (file)
@@ -25,6 +25,7 @@
        "tog-watchdefault": "Cuir duilleagan a dheasaicheas mi air a' chlàr-fhaire agam",
        "tog-watchmoves": "Cuir duilleagan a ghluaiseas mi air a' chlàr-fhaire agam",
        "tog-watchdeletion": "Cuir duilleagan a sguabas mi às air a' chlàr-fhaire agam",
+       "tog-watchrollback": "Cuir duilleagan air an do rinn mi roladh air ais air a' chlàr-fhaire agam",
        "tog-minordefault": "Comharraich gach mùthadh mar mhùthadh beag a ghnàth",
        "tog-previewontop": "Nochd an ro-shealladh os cionn a' bhogsa deasachaidh",
        "tog-previewonfirst": "Nochd an ro-shealladh nuair a nithear a' chiad deasachadh",
        "otherlanguages": "Ann an cànain eile",
        "redirectedfrom": "(Air ath-sheòladh o $1)",
        "redirectpagesub": "Ath-sheòl an duilleag",
+       "redirectto": "Dèan ath-stiùireadh gu:",
        "lastmodifiedat": "Chaidh an duilleag seo a mhùthadh $1 aig $2 turas mu dheireadh.",
        "viewcount": "Chaidh inntrigeadh a dhèanamh dhan duilleag seo $1 {{PLURAL:$1|turas|thuras|tursan|turas}}.",
        "protectedpage": "Duilleag fo dhìon",
        "hidetoc": "falaich",
        "collapsible-collapse": "Co-theannaich",
        "collapsible-expand": "Leudaich",
+       "confirmable-confirm": "A bheil {{GENDER:$1|thu}} cinnteach?",
+       "confirmable-yes": "Tha",
+       "confirmable-no": "Chan eil",
        "thisisdeleted": "A bheil thu airson $1 a shealltainn no aiseag?",
        "viewdeleted": "A bheil thu airson $1 a shealltainn?",
        "restorelink": "$1 {{PLURAL:$1|deasachadh|dheasachadh|deasachaidhean|deasachadh}} a chaidh a sguabadh às",
        "invalidtitle-knownnamespace": "Tiotal mì-dhligheach leis an ainm-spàs \"$2\" agus an teacsa \"$3\"",
        "invalidtitle-unknownnamespace": "Tiotal mì-dhligheach leis an àireamh ainm-spàis $1 agus an teacsa \"$2\"",
        "exception-nologin": "Chan eil thu air logadh a-steach",
-       "exception-nologin-text": "Feumaidh tu [[Special:Userlogin|logadh a-steach]] mus fhaic thu an duilleag seo no mus urrainn dhut seo a dhèanamh.",
+       "exception-nologin-text": "Dèan logadh a-steach gus cothrom fhaighinn air an duilleag no air a' ghnìomh seo.",
        "exception-nologin-text-manual": "Ma tha thu ag iarraidh cothrom air an duilleag no air a' ghnìomh seo, $1.",
        "virus-badscanner": "Droch cho-dhealbhachd: sganair bhìorasan neo-aithnichte: <em>$1</em>",
        "virus-scanfailed": "dh'fhàillig an sganadh (còd $1)",
        "createaccount-text": "Chruthaich cuideigin cunntas airson a' phost-d agad air {{SITENAME}} ($4) air a bheil \"$2\", leis an fhacal-fhaire \"$3\".\nBu chòir dhut logadh a-steach agus am facal-faire agad atharrachadh gu h-ìosal an-dràsta.\n\n'S urrainn dhut an teachdaireachd seo a leigeil seachad ma chaidh an cunntas a chruthachadh air mhearachd.",
        "login-throttled": "Dh'fheuch thu ri logadh a-steach ro thric o chionn ghoirid.\nFuirich ort $1 mus feuch thu ris a-rithist.",
        "login-abort-generic": "Cha do shoirbhich leat leis an logadh a-steach - Chaidh sgur dheth",
+       "login-migrated-generic": "Chaidh an cunntas agad imrich 's chan eil an t-ainm cleachdaiche agad ann tuilleadh air an uicidh seo.",
        "loginlanguagelabel": "Cànan: $1",
        "suspicious-userlogout": "Chaidh d' iarrtas airson logadh a-mach a dhiùltadh a chionn 's gu bheil coltas gun deach a chur le brabhsair briste no le progsaidh tasglannaidh.",
        "createacct-another-realname-tip": "Cha leig thu leas innse dè am fìor-ainm a tha ort.\nMa bheir thu seachad e, thèid seo a chleachdadh gus urram a thoirt dha na h-ùghdaran airson an cuid obrach.",
        "passwordreset-emailsent-capture": "Chaidh post-d a chum ath-shuidheachadh an fhacail-fhaire a chur agus chì thu sin gu h-ìosal.",
        "passwordreset-emailerror-capture": "Chaidh post-d a chum ath-shuidheachadh an fhacail-fhaire a ghintinn agus chì thu sin gu h-ìosal ach cha b' urrainn dhuinn a chur dhan chleachdaiche: $1",
        "changeemail": "Atharraich am post-d",
-       "changeemail-header": "Atharraich cunntas a' phuist-d",
        "changeemail-text": "Lìon am foirm seo gus am post-d agad atharrachadh. Feumaidh tu am facal-faire agad a chur a-steach a-rithist gus a dhearbhadh.",
        "changeemail-no-info": "Feumaidh tu logadh a-steach mus dèan thu inntrigeadh dìreach dhan duilleag seo.",
        "changeemail-oldemail": "An seòladh puist-d làithreach:",
        "changeemail-none": "(chan eil gin)",
        "changeemail-password": "Am facal-faire agad air {{SITENAME}}:",
        "changeemail-submit": "Atharraich am post-d",
-       "changeemail-cancel": "Sguir dheth",
        "changeemail-throttled": "Dh'fheuch thu ri logadh a-steach ro thric.\nFuirich ort $1 mus feuch thu ris a-rithist.",
        "resettokens": "Ath-shuidhich na tòcanan",
        "resettokens-text": "'S urrainn dhut tòcanan ath-shuidheachadh a bheir cothrom dhut air cuid a dhàta prìobhaideach a tha co-cheangailte ris a' chunntas agad.\n\nBu chòir dhut seo a dhèanamh ma thug thu do chuideigin e air mhearachd no ma bhris cuideigin a-steach air a' chunntas agad.",
        "preview": "Ro-shealladh",
        "showpreview": "Seall an ro-shealladh",
        "showdiff": "Seall na mùthaidhean",
-       "anoneditwarning": "<strong>Rabhadh:</strong> Chan eil thu air logadh a-steach.\nThèid an seòladh IP agad a chlàradh ann an eachdraidh na duilleige seo.",
+       "blankarticle": "<strong>Rabhadh:</strong> Tha an duilleag a tha thu a' cruthachadh bàn.\nMa nì thu briogadh air \"{{int:savearticle}}\" a-rithist, thèid an duilleag a chruthachadh gun susbaint sam bith innte.",
+       "anoneditwarning": "<strong>Rabhadh:</strong> Chan eil thu air logadh a-steach. Chithear an seòladh IP agad gu poblach ma nì thu deasachadh sam bith. Ma nì thu <strong>[$1 logadh a-steach]</strong> no ma <strong>[$2 chruthaicheas tu cunntas]</strong>, thèid d' ainm a chur ris na dheasaich thu 's gheibh thu buannachd a bharrachd às cuideachd.",
        "anonpreviewwarning": "<em>Chan eil thu air logadh a-steach. Ma nì thu sàbhaladh, thèid an seòladh IP agad a chlàradh ann an eachdraidh deasachadh na duilleige seo.</em>",
        "missingsummary": "<strong>Cuimhnich:</strong> Cha dug thu seachad gearr-chunntas air na dh'atharraich thu.\nMa bhriogas tu air \"{{int:savearticle}}\" a-rithist, thèid na dheasaich thu a shàbhaladh as aonais gearr-chunntais.",
        "missingcommenttext": "Cuir a-steach beachd gu h-ìosal.",
        "parser-template-recursion-depth-warning": "Chaidh thu thairis air crìoch doimhne nan ath-chùrsaidhean teamplaid ($1)",
        "language-converter-depth-warning": "Chaidh thu thairis air crìoch doimhne an iompachair chànain ($1)",
        "node-count-exceeded-category": "Duilleagan far an deachas thairis air cunntas nan nòdan",
-       "node-count-exceeded-category-desc": "Roinn-seòrsa airson duilleagan far a bheilear thairis air crìoch nan nòdan.",
-       "node-count-exceeded-warning": "Chaidh an duilleag thairis air cunntas nan nòdan",
+       "node-count-exceeded-category-desc": "Tha barrachd nòdan san duilleag na tha ceadaichte.",
+       "node-count-exceeded-warning": "Bha barrachd nòdan san duilleag na tha ceadaichte.",
        "expansion-depth-exceeded-category": "Duilleagan far an deachas thairis air a' chrìoch leudachaidh",
-       "expansion-depth-exceeded-category-desc": "Seo roinn-seòrsa airson duilleagan far a bheilear thairis air doimhne an leudachaidh.",
-       "expansion-depth-exceeded-warning": "Chaidh an duilleag thairis air an doimhne leudachaidh",
+       "expansion-depth-exceeded-category-desc": "Tha an leudachadh san duilleag nas doimhne na tha ceadaichte.",
+       "expansion-depth-exceeded-warning": "Bha an leudachadh san duilleag na bu dhoimhne na tha ceadaichte",
        "parser-unstrip-loop-warning": "Mhothaich sinn do lùb unstrip",
        "parser-unstrip-recursion-limit": "Chaidheas thairis air crìoch unstrip recursion ($1)",
        "converter-manual-rule-error": "Mhothaich sinn do mhearachd san riaghailt iompachadh làimhe airson cànan",
        "rev-deleted-event": "(chaidh gnìomh an loga a thoirt air falbh)",
        "rev-deleted-user-contribs": "[chaidh an t-ainm-cleachdaiche no an seòladh IP a thoirt air falbh - chaidh an deasachadh fhalach o liosta na h-obrach]",
        "rev-deleted-text-permission": "Chaidh mùthadh na duilleige seo <strong>a sguabadh às</strong>.\nGheibh thu mion-fhiosrachadh air [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ann an loga nan rudan a chaidh a sguabadh às].",
+       "rev-suppressed-text-permission": "Chaidh mùthadh na duilleige seo <strong>a mhùchadh</strong>.\nGheibh thu mion-fhiosrachadh air [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ann an loga nan rudan a chaidh a mhùchadh].",
        "rev-deleted-text-unhide": "Chaidh mùthadh na duilleige seo <strong>a sguabadh às</strong>.\nGheibh thu mion-fhiosrachadh air [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ann an loga nan rudan a chaidh a sguabadh às].\n'S urrainn dhut [$1 am mùthadh seo fhaicinn fhathast] ma tha thu airson leantainn air adhart.",
        "rev-suppressed-text-unhide": "Chaidh mùthadh na duilleige seo <strong>a mhùchadh</strong>.\nGheibh thu mion-fhiosrachadh air [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} ann an loga nan rudan a chaidh a mhùchadh].\n'S urrainn dhut [$1 am mùthadh seo fhaicinn fhathast] ma tha thu airson leantainn air adhart.",
        "rev-deleted-text-view": "Chaidh mùthadh na duilleige seo <strong>a sguabadh às</strong>.\n'S urrainn dhut coimhead air, gheibh thu mion-fhiosrachadh air [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} ann an loga nan rudan a chaidh a sguabadh às].",
        "revdelete-text-text": "Nochdaidh mùthaidhean a chaidh a sguabadh às ann an eachdraidh na duilleige fhathast ach chan fhaic buill a' phobaill cuid dhen t-susbaint aca.",
        "revdelete-text-file": "Nochdaidh tionndaidhean dhen fhaidhle a chaidh a sguabadh às ann an eachdraidh na duilleige fhathast ach chan fhaic buill a' phobaill cuid dhen t-susbaint aca.",
        "logdelete-text": "Nochdaidh tachartasan san loga a chaidh a sguabadh às ann an eachdraidh na duilleige fhathast ach chan fhaic buill a' phobaill cuid dhen t-susbaint aca.",
-       "revdelete-text-others": "Gheibh rianairean eile air {{SITENAME}} cothrom air an t-susbaint fhalaichte fhathast agus is urrainn dhaibh an sguabadh às a neo-dhèanamh san dearbh eadar-aghaidh mur an deach cuingeachaidhean a bharrachd a chur orra.",
+       "revdelete-text-others": "Gheibh rianairean eile cothrom air an t-susbaint fhalaichte fhathast agus is urrainn dhaibh an sguabadh às a neo-dhèanamh mur an deach cuingeachaidhean a bharrachd a chur orra.",
        "revdelete-confirm": "Dearbhaich gu bheil thu airson seo a dhèanamh, gu bheil thu a' tuigsinn na thachras ri linn agus gu bheil thu a' dèanamh seo a-rèir [[{{MediaWiki:Policy-url}}|a' phoileasaidh]].",
        "revdelete-suppress-text": "Cha bu chòir dhut mùchadh a chleachdadh <strong>ach</strong> ann an suidheachaidhean mar seo:\n* Fiosrachadh a dh'fhaodadh a bhith dìteachail\n* Fiosrachadh pearsanta a tha cearr\n*: <em>seòladh taighe, àireamhan fòn, àireamhan NI is msaa.</em>",
        "revdelete-legend": "Suidhich cuingeachaidhean na faicsinneachd",
        "searchall": "a h-uile",
        "showingresults": "A' sealltainn suas ri <strong>$1</strong> {{PLURAL:$1|toradh|thoradh|toraidhean|toradh}} gu h-ìosal a' tòiseachadh le àireamh <strong>$2</strong>.",
        "showingresultsinrange": "A' sealltainn suas ri <strong>$1</strong> {{PLURAL:$1|toradh|thoradh|toraidhean|toradh}} san rainse eadar àireamh <strong>$2</strong> is <strong>$3</strong>.",
-       "showingresultsheader": "{{PLURAL:$5|Toradh <strong>$1</strong> à <strong>$3</strong>|Toraidhean <strong>$1 - $2</strong> à <strong>$3</strong>}} airson <strong>$4</strong>",
+       "search-showingresults": "{{PLURAL:$4|Toradh <strong>$1</strong> à <strong>$3</strong>|Toraidhean <strong>$1 - $2</strong> à <strong>$3</strong>|Toraidhean <strong>$1 - $2</strong> à <strong>$3</strong>|Toraidhean <strong>$1 - $2</strong> à <strong>$3</strong>}}",
        "search-nonefound": "Cha do fhreagair toradh sam bith ri d' iarrtas.",
        "powersearch-legend": "Rannsachadh adhartach",
        "powersearch-ns": "Lorg ann an ainm-spàsan:",
        "preferences": "Roghainnean",
        "mypreferences": "Na roghainnean agam",
        "prefs-edits": "Co mheud deasachadh:",
-       "prefsnologintext2": "Ma tha thu airson na roghainnean agad atharrachadh, $1.",
+       "prefsnologintext2": "Log a-steach gus na roghainnean agad atharrachadh.",
        "prefs-skin": "Bian",
        "skin-preview": "Ro-shealladh",
        "datedefault": "Gun roghainnean",
        "prefs-tokenwatchlist": "Tòcan",
        "prefs-diffs": "Diofaran",
        "prefs-help-prefershttps": "Thèid an roghainn seo a chur an sàs an ath thuras a nì thu logadh a-steach.",
+       "prefswarning-warning": "Rinn thu atharrachadh air na roghainnean agad nach deach a shàbhaladh fhathast.\nCha tèid na roghainnean agad ùrachadh ma dh'fhàgas tu an duilleag seo gun bhriogadh air \"$1\".",
        "prefs-tabs-navigation-hint": "Gliocas: 'S urrainn dhut na h-iuchraichean saighde chlì 's dheas a chleachdadh gus leum a ghearradh o thaba gu taba air liosta nan taba.",
        "email-address-validity-valid": "Tha coltas gu bheil am post-d dligheach",
        "email-address-validity-invalid": "Cuir a-steach post-d dligheach",
        "right-deletedtext": "Cead teacsa 's atharraichean eadar mùthaidhean air an sguabadh às a shealltainn",
        "right-browsearchive": "Cead lorg sna duilleagan air an sguabadh às",
        "right-undelete": "Cead duilleagan air an sguabadh às aiseag",
-       "right-suppressrevision": "Cead sùil a thoirt air mùthaidhean a chaidh a sguabadh às 's am falach o na rianairean 's an aiseag",
+       "right-suppressrevision": "Seall, falaich 's neo-fhalaich mùthaidhean sònraichte de dhuilleagan o chleachdaiche sam bith",
+       "right-viewsuppressed": "Seall na mùthaidhean a tha falaichte o chleachdaiche sam bith",
        "right-suppressionlog": "Cead logaichean prìobhaideach a shealltainn",
        "right-block": "Cead càch a bhacadh o dheasachadh",
        "right-blockemail": "Cead cleachdaiche a bhacadh o chur phost-d",
        "recentchanges-legend-heading": "'''Treòir:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (faic [[Special:NewPages|liosta nan duilleagan ùra]] cuideachd)",
        "recentchanges-legend-plusminus": "(<em>±123</em>)",
-       "rcnotefrom": "Gheibhear na mùthaidhean a-mach o <strong>$2</strong> (gu ruige <strong>$1</strong>) gu h-ìosal.",
+       "rcnotefrom": "Chì thu {{PLURAL:$5|am mùthadh|na mùthaidhean|na mùthaidhean|na mùthaidhean}} o <strong>$3 $4</strong> (gu ruige <strong>$1</strong> dhiubh) gu h-ìosal.",
        "rclistfrom": "Seall na mùthaidhean ùra a-mach o $3 $2",
        "rcshowhideminor": "$1 mùthaidhean beaga",
        "rcshowhideminor-show": "Seall",
        "license": "Ceadachadh:",
        "license-header": "Ceadachadh",
        "nolicense": "Cha deach gin a thaghadh",
+       "licenses-edit": "Deasaich roghainnean a' cheadachais",
        "license-nopreview": "(Chan eil ro-shealladh ri làimh)",
-       "upload_source_url": "(URL dligheach a ghabhas inntrigeadh gu poblach)",
-       "upload_source_file": "(faidhle air a' choimpiutair agad)",
+       "upload_source_url": "(am faidhle a thagh thu o URL dligheach a ghabhas inntrigeadh gu poblach)",
+       "upload_source_file": "(am faidhle a thagh thu air a' choimpiutair agad)",
+       "listfiles-delete": "sguab às",
        "listfiles-summary": "Seallaidh an duilleag shònraichte seo gach faidhle a chaidh a luchdadh suas.",
        "listfiles_search_for": "Lorg airson ainm a' mheadhain:",
        "imgfile": "faidhle",
        "randomincategory": "Duilleag air thuaiream san roinn-seòrsa",
        "randomincategory-invalidcategory": "Chan e \"$1\" 'na ainm roinn-seòrsa dligheach.",
        "randomincategory-nopages": "Chan eil duilleag san roinn-seòrsa [[:Category:$1|$1]].",
-       "randomincategory-selectcategory": "Faigh duilleag air thuaiream a tha san roinn-seòrsa: $1 $2.",
-       "randomincategory-selectcategory-submit": "Siuthad",
+       "randomincategory-category": "Roinn-seòrsa:",
+       "randomincategory-legend": "Duilleag air thuaiream san roinn-seòrsa",
        "randomredirect": "Ath-stiùireadh air thuaiream",
        "randomredirect-nopages": "Chan eil ath-stiùireadh san ainm-spàs \"$1\".",
        "statistics": "Stadastaireachd",
        "wantedpages-badtitle": "Tha tiotal mì-dhligheach am measg nan toraidhean: $1",
        "wantedfiles": "Faidhlichean a thathar 'gan iarraidh",
        "wantedfiletext-cat": "Tha na faidhlichean a leanas 'gan cleachdadh ach chan eil iad ann. Dh'fhaoidte gum bi faidhlichean o ionadan-tasgaidh cèine 'gan sealltainn an-seo ged a tha iad ann. Bidh <del>loidhne tro</del> na toraidhean a bharrachd seo. A bharrachd air sin, chì thu na duilleagan sa bhios faidhlichean nach eil ann leabaichte air [[:$1]].",
+       "wantedfiletext-cat-noforeign": "Tha na faidhlichean a leanas 'gan cleachdadh ach chan eil iad ann. A bharrachd air sin, chì thu na duilleagan le faidhlichean leabaichte nach eil ann air [[:$1]].",
        "wantedfiletext-nocat": "Tha na faidhlichean a leanas 'gan cleachdadh ach chan eil iad ann. Dh'fhaoidte gum bi faidhlichean o ionadan-tasgaidh cèine 'gan sealltainn an-seo ged a tha iad ann. Bidh <del>loidhne tro</del> na toraidhean a bharrachd seo.",
+       "wantedfiletext-nocat-noforeign": "Tha na faidhlichean a leanas 'gan cleachdadh ach chan eil iad ann.",
        "wantedtemplates": "Teamplaidean a thathar 'gan iarraidh",
        "mostlinked": "Na duilleagan ris a bheil an àireamh as motha de cheanglaichean",
        "mostlinkedcategories": "Na roinnean-seòrsa ris a bheil an àireamh as motha de cheanglaichean",
        "booksources": "Tùsan a tha 'nan leabhraichean",
        "booksources-search-legend": "Lorg tùsan a tha 'nan leabhraichean",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Siuthad",
        "booksources-text": "Chì thu liosta dhe cheanglaichean gu làraichean eile a reiceas leabhraichean ùra 's cleachdte gu h-ìosal 's ma dh'fhaoidte gum faigh thu barrachd fiosrachaidh orra mu leabhraichean a tha thu a' sireadh:",
        "booksources-invalid-isbn": "Tha coltas mì-dhligheach air an ISBN a chaidh a thoirt seachad; dearbhaich gun deach lethbhreac a dhèanamh dheth on tùs gun mhearachd.",
        "specialloguserlabel": "Cò rinn e:",
        "noindex-category-desc": "Cha dèid an duilleag seo a chur ris an inneacs luirg le botaichean on a tha am facal draoidheach <code><nowiki>__NOINDEX__</nowiki></code> air 's a tha i ann an ainm-spàs far a bheil a' bhratach seo ceadaichte.",
        "index-category-desc": "Tha <code><nowiki>__INDEX__</nowiki></code> air an duilleag seo ('s tha i ann an ainm-spàs far a bheil a' bhratach seo ceadaichte) 's mar sin thèid a chur ri inneacsan luirg le botaichean ged nach tachradh seo gu h-àbhaisteach.",
        "post-expand-template-inclusion-category-desc": "Bhiodh an duilleag nas motha na <code>$wgMaxArticleSize</code> às dèidh a h-uile teamplaid a leudachadh 's mar sin cha deach a h-uile teamplaid a leudachadh.",
-       "post-expand-template-argument-category-desc": "Bidh an duilleag nas motha na  <code>$wgMaxArticleSize</code> às dèidh argamaid teamplaid a leudachadh (rudeigin eadar camagan dualach trìoblaichte, can <code>{{{Foo}}}</code>).",
-       "expensive-parserfunction-category-desc": "Tha cus foincseanan cosgail a' pharsair (can <code>#ifexist</code>) am broinn duilleige. Faic [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
-       "broken-file-category-desc": "Thèid an roinn-seòrsa seo a chur ris nuair a bhios ceangal gu faidhle briste am broinn na duilleige (ceangal gus faidhle a leabachadh mur eil am faidhle ann).",
-       "hidden-category-category-desc": "Seo ronn-seòrsa le <code><nowiki>__HIDDENCAT__</nowiki></code> oirre ach nach nochd i ann am bogsa nan ceanglaichean gu roinnean-seòrsa air na duilleagan o thùs.",
+       "post-expand-template-argument-category-desc": "Bidh an duilleag nas motha na <code>$wgMaxArticleSize</code> às dèidh argamaid teamplaid a leudachadh (rudeigin eadar camagan dualach trìoblaichte, can <code>{{{Foo}}}</code>).",
+       "expensive-parserfunction-category-desc": "Tha cus foincseanan cosgail a' pharsair (can <code>#ifexist</code>) am broinn na duilleige. Faic [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit].",
+       "broken-file-category-desc": "Tha ceangal gu faidhle briste am broinn na duilleige (ceangal gus faidhle a leabachadh fad 's nach eil am faidhle ann).",
+       "hidden-category-category-desc": "Seo roinn-seòrsa le <code><nowiki>__HIDDENCAT__</nowiki></code> 'na susbaint ach nach nochd i ann am bogsa nan ceanglaichean gu roinnean-seòrsa air na duilleagan o thùs.",
        "trackingcategories-nodesc": "Chan eil tuairisgeul ri làimh.",
        "trackingcategories-disabled": "Tha an roinn-seòrsa à comas",
        "mailnologin": "Gun seòladh an t-seòladair",
        "mywatchlist": "An clàr-faire",
        "watchlistfor2": "aig $1 $2",
        "nowatchlist": "Chan eil rud sam bith air a' chlàr-fhaire agad.",
-       "watchlistanontext": "$1 gus nithean air a' chlàr-fhaire agad a shealltainn no a dheasachadh.",
+       "watchlistanontext": "Log a-steach gus nithean air a' chlàr-fhaire agad a shealltainn no a dheasachadh.",
        "watchnologin": "Chan eil thu air logadh a-steach",
        "addwatch": "Cuir air a' chlàr-fhaire",
        "addedwatchtext": "Chaidh an duilleag \"[[:$1]]\" a chur ris a' [[Special:Watchlist|chlàr-fhaire]] agad.\nNochdaidh mùthaidhean a nithear air an duilleag seo 's air an duilleag deasbaireachd a tha co-cheangailte ris an-seo san àm ri teachd.",
        "watchlist-details": "Tha {{PLURAL:$1|$1 duilleag|$1 dhuilleag|$1 duilleagan|$1 duilleag}} air a' chlàr-fhaire agad, gun luaidh air na duilleagan deasbaireachd.",
        "wlheader-enotif": "Tha brathan-naidheachd air a' phost-d an comas.",
        "wlheader-showupdated": "Tha clò <strong>trom</strong> air duilleagan a chaidh atharrachadh on turas mu dheireadh a thadhail thu orra.",
-       "wlnote": "Seo {{PLURAL:$1|an $1 mhùthadh|$1 mhùthadh|na $1 mùthaidhean|$1 mùthadh}} mu dheireadh san {{PLURAL:$2|$2 uair a thìde|$2 uair a thìde|$2 uairean a thìde|$2 uair a thìde}} mu dheireadh, mar a bha e $3, $4.",
+       "wlnote": "Chì thu gu h-ìosal {{PLURAL:$1|a' $1 mhùthadh|an $1 mhùthadh|na $1 mùthaidhean|am $1 mùthadh}} mu dheireadh san {{PLURAL:$2|$2 uair a thìde|$2 uair a thìde|$2 uairean a thìde|$2 uair a thìde}} mu dheireadh, mar a bha e $3, $4.",
        "wlshowlast": "Seall na $1 uairean a thìde mu dheireadh $2 làithean mu dheireadh $3",
        "watchlist-options": "Roghainnean mo chlàir-faire",
        "watching": "'Ga chur air a' chlàr-fhaire...",
        "delete-edit-reasonlist": "Deasaich adhbharan sguabadh às",
        "delete-toobig": "Tha eachdraidh deasachaidh mòr aig an duilleag seo sa bheil barrachd air $1 {{PLURAL:$1|mhùthadh|mhùthadh|mùthaidhean|mùthadh}}.\nChaidh sguabadh às nan duilleagan dhen leithid a chuingeachadh ach na dèid cron a dhèanamh air {{SITENAME}} le mearachd.",
        "delete-warning-toobig": "Tha eachdraidh deasachaidh mòr aig an duilleag seo sa bheil barrachd air $1 {{PLURAL:$1|mhùthadh|mhùthadh|mùthaidhean|mùthadh}}.\nMa sguabas tu às dhi, dh'fhaoidte gun dèan thu cron air na gnìomhan stòr-dàta aig {{SITENAME}}; mar sin, thoir an aire.",
+       "deleteprotected": "Chan urrainn dhut an duilleag seo a sguabadh às on a chaidh a dìon.",
        "deleting-backlinks-warning": "'''Rabhadh:''' Tha [[Special:WhatLinksHere/{{FULLPAGENAME}}|duilleag eile]] a' ceangal ris an duilleag a tha thu airson sguabadh às no 'ga gabhail a-steach 'na h-iomradh.",
        "rollback": "Roilig atharraichean air ais",
        "rollback_short": "Roladh air ais",
        "protect-othertime": "Àm eile:",
        "protect-othertime-op": "àm eile",
        "protect-existing-expiry": "Falbhaidh an ùine air mar-thà: $2 $3",
+       "protect-existing-expiry-infinity": "Chan fhalbh an ùine air gu buan mar-thà",
        "protect-otherreason": "Adhbhar eile/a bharrachd:",
        "protect-otherreason-op": "Adhbhar eile",
        "protect-dropdown": "*Na h-adhbharan dìona as cumanta\n** Cus bhandalachd\n** Cus spama\n** Còmhstrithean deasachaidh nach eil torrach\n** Duilleag air a bheil trafaig mhòr",
        "unblocked": "Chaidh [[User:$1|$1]] a neo-bhacadh.",
        "unblocked-range": "Chaidh $1 a neo-bhacadh.",
        "unblocked-id": "Chaidh am bacadh $1 a thoirt air falbh.",
+       "unblocked-ip": "Chaidh [[Special:Contributions/$1|$1]] a neo-bhacadh.",
        "blocklist": "Cleachdaichean a chaidh a bhacadh",
        "ipblocklist": "Cleachdaichean a chaidh a bhacadh",
        "ipblocklist-legend": "Lorg cleachdaiche a chaidh a bhacadh",
        "import": "Ion-phortaich duilleagan",
        "importinterwiki": "Ion-phortachadh tar-uicidh",
        "import-interwiki-text": "Tagh uicidh 's tiotal na duilleige airson ion-phortachadh.\nThèid cinn-là nam mùthaidhean 's ainmean nan deasaichean a ghlèidheadh.\nThèid gach gnìomh ion-phortachadh tar-uicidh a chur ris an [[Special:Log/import|loga ion-phortachaidh]].",
-       "import-interwiki-source": "An uicidh/duilleag thùsail:",
+       "import-interwiki-sourcewiki": "An uicidh thùsail:",
+       "import-interwiki-sourcepage": "An duilleag thùsail:",
        "import-interwiki-history": "Dèan lethbhreac de dh'eachdraidh nam mùthaidhean slàna airson na duilleige seo",
        "import-interwiki-templates": "Gabh a-steach na teamplaidean uile",
        "import-interwiki-submit": "Ion-phortaich",
        "import-error-create": "Cha deach an duilleag \"$1\" ion-phortachadh o nach fhaod thu a cruthachadh.",
        "import-error-interwiki": "Cha deach an duilleag \"$1\" ion-phortachadh on a chaidh ainm a ghlèidheadh airson ceangal a-mach (eadar-uicidh).",
        "import-error-special": "Cha deach an duilleag \"$1\" ion-phortadh on a bhuineas i ri ainm-spàs sònraichte nach ceadaich duilleagan.",
-       "import-error-invalid": "Cha deach an duilleag \"$1\" ion-phortachadh on a tha ainm mì-dhligheach.",
+       "import-error-invalid": "Cha deach an duilleag \"$1\" ion-phortachadh on a tha a h-ainm mì-dhligheach air an uicidh seo.",
        "import-error-unserialize": "Cha ghabh mùthadh $2 dhen duilleag \"$1\" a thogail on tionndadh serialized. Chaidh aithris gun cleachd am mùthadh modail susbaint $3 a tha serialized mar $4.",
        "import-error-bad-location": "Cha ghabh am mùthadh $2 a chleachdas modail susbainte $3 a stòradh air \"$1\" air an uicidh seo o nach cuir an duilleag ud taic ris a' mhodail seo.",
        "import-options-wrong": "{{PLURAL:$2|Roghainn cearr|Roghainnean cearra}}: <nowiki>$1</nowiki>",
        "importlogpage": "Loga an ion-phortachaidh",
        "importlogpagetext": "Ion-phortachadh rianachd de dhuilleagan aig a bheil eachdraidh mhùthaidhean o uicidhean eile.",
        "import-logentry-upload": "chaidh [[$1]] ion-phortachadh le luchdadh suas faidhle",
-       "import-logentry-upload-detail": "$1 {{PLURAL:$1|mhùthadh|mùthadh|mùthaidhean|mùthadh}}",
+       "import-logentry-upload-detail": "Chaidh $1 {{PLURAL:$1|mhùthadh|mùthadh|mùthaidhean|mùthadh}} ion-phortachadh",
        "import-logentry-interwiki": "air fhaighinn 'na thar-uicidh $1",
-       "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|mhùthadh|mhùthadh|mùthaidhean|mùthadh}} o $2",
+       "import-logentry-interwiki-detail": "Chaidh $1 {{PLURAL:$1|mhùthadh|mhùthadh|mùthaidhean|mùthadh}} ion-phortachadh o $2",
        "javascripttest": "Deuchainn air JavaScript",
        "javascripttest-title": "A' ruith deuchainnean aig $1",
        "javascripttest-pagetext-noframework": "Tha an duilleag seo glèidhte airson deuchainnean JavaScript a ruith.",
        "autosumm-replace": "Chaidh \"$1\" a chur an àite na susbaint",
        "autoredircomment": "Chaidh an duilleag ath-stiùireadh gu [[$1]]",
        "autosumm-new": "Chaidh duilleag le \"$1\" a chruthachadh",
+       "autosumm-newblank": "Chaidh duilleag bhàn a chruthachadh",
        "size-bytes": "$1 B",
        "size-kilobytes": "$1 KB",
        "size-megabytes": "$1 MB",
        "timezone-utc": "UTC",
        "unknown_extension_tag": "Taga leudachain \"$1\" neo-aithnichte",
        "duplicate-defaultsort": "<strong>Rabhadh:</strong> Tha an iuchair seòrsachaidh bhunaiteach \"$2\" a' dol thairis air seann iuchair eile, \"$1\".",
+       "duplicate-displaytitle": "<strong>Rabhadh:</strong> Tha an tiotal taisbeanaidh \"$2\" a' dol thairis air seann tiotal taisbeanaidh eile, \"$1\".",
        "version": "Tionndadh",
        "version-extensions": "Leudachain air an stàladh",
        "version-skins": "Craicnean",
        "logentry-rights-rights": "Dh'atharraich $1 {{GENDER:$2|a bhallrachd|a ballrachd}} ann am buidheann airson $3 o $4 gu $5",
        "logentry-rights-rights-legacy": "Dh'atharraich $1 {{GENDER:$2|a bhallrachd|a ballrachd}} ann am buidheann airson $3",
        "logentry-rights-autopromote": "Chaidh $1 àrdachadh o $4 gu $5 gu fèin-obrachail",
+       "logentry-upload-upload": "Luchdaich $1 $3 suas",
+       "logentry-upload-overwrite": "Luchdaich $1 tionndadh ùr de $3 suas",
+       "logentry-upload-revert": "Luchdaich $1 $3 suas",
        "rightsnone": "(chan eil gin)",
+       "revdelete-summary": "gearr-chunntas an deasachaidh",
        "feedback-bugornote": "Ma tha fiosrachadh mionaideach agad air duilgheadas teicnigeach, feuch an dèan thu [$1 aithris air buga].\nMur eil, 's urrainn dhut am foirm furasta a chleachdadh gu h-ìosal. Thèid do bheachd a chur ris an duilleag \"[$3 $2]\" is d' ainm-cleachdaiche a chur ris.",
        "feedback-subject": "Cuspair:",
        "feedback-message": "Teachdaireachd:",
        "duration-centuries": "$1 {{PLURAL:$1|linn|linn|linntean|linn}}",
        "duration-millennia": "$1 {{PLURAL:$1|mhìle bliadhna|mhìle bliadhna|mìle bliadhna|mìle bliadhna}}",
        "rotate-comment": "Chaidh an dealbh a chuairteachadh le $1 {{PLURAL:$1|cheum|cheum|ceuman|ceum}} gu tuathal",
+       "limitreport-title": "Dàta pròifil a' pharsair",
+       "limitreport-cputime": "Cleachdadh ùine a' CPU",
        "limitreport-cputime-value": "$1 {{PLURAL:$1|diog|dhiog|diogan|diog}}",
+       "limitreport-walltime": "Cleachdadh fìor-ùine",
        "limitreport-walltime-value": "$1 {{PLURAL:$1|diog|dhiog|diogan|diog}}",
+       "limitreport-ppvisitednodes": "Àireamh nan nòdan ris an do thadhal an ro-phròiseasar",
        "limitreport-ppvisitednodes-value": "$1/$2",
+       "limitreport-ppgeneratednodes": "Àireamh nan nòdan a ghin an ro-phròiseasar",
        "limitreport-ppgeneratednodes-value": "$1/$2",
+       "limitreport-postexpandincludesize": "Meud na gabhail a-steach às dèidh an leudachaidh",
        "limitreport-postexpandincludesize-value": "$1/$2 {{PLURAL:$2|bhaidht|bhaidht|baidhtichean|baidht}}",
+       "limitreport-templateargumentsize": "Meud nan argamaidean air an teamplaid",
        "limitreport-templateargumentsize-value": "$1/$2 {{PLURAL:$2|bhaidht|bhaidht|baidhtichean|baidht}}",
+       "limitreport-expansiondepth": "Doimhne as motha an leudachaidh",
        "limitreport-expansiondepth-value": "$1/$2",
+       "limitreport-expensivefunctioncount": "Cunntadh air foincseanan daora a' pharsair",
        "limitreport-expensivefunctioncount-value": "$1/$2",
        "expandtemplates": "Leudaich na templaidean",
        "expand_templates_intro": "Gabhaidh an duilleag shònraichte seo ri teacsa agus leudaichidh i a h-uile teamplaid na broinn gu ath-chùrsach.\nLeudaichidh i cuideachd foincseanan parsair ris a chuirear taic, can\n<code><nowiki>{{</nowiki>#language:…}}</code> agus caochladairean mar\n<code><nowiki>{{</nowiki>CURRENTDAY}}</code>.\nAir deireadh na sgeòil, leudaichidh i cha mhòr gach rud eadar camagan dualach dùbailte.",
        "action-pagelang": "atharraich cànan nan duilleagan",
        "log-name-pagelang": "Loga air atharrachadh nan cànan",
        "log-description-pagelang": "Seo loga dhe na h-atharraichean air cànanan nan duilleagan.",
-       "logentry-pagelang-pagelang": "Dh'atharraich $1 cànan nan duilleagan airson $3 o $4 gu $5."
+       "logentry-pagelang-pagelang": "Dh'atharraich $1 cànan nan duilleagan airson $3 o $4 gu $5.",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (an comas)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''à comas''')",
+       "mediastatistics": "Stadastaireachd nam meadhanan",
+       "mediastatistics-summary": "Stadastaireachd air na seòrsaichean faidhle a chaidh a luchdadh suas. Cha ghabh seo a-steach ach an tionndadh as ùire de gach faidhle. Tha seann-tionndaidhean 's faidhlichean air an sguabadh às 'gan leigeil seachad.",
+       "mediastatistics-nfiles": "$1 ($2%)",
+       "mediastatistics-nbytes": "%1 {{PLURAL:$1|bhaidht|bhaidht|baidhtichean|baidht}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "Seòrsa MIME",
+       "mediastatistics-table-extensions": "Leudachain comasach",
+       "mediastatistics-table-count": "Àireamh de dh'fhaidhlichean",
+       "mediastatistics-table-totalbytes": "Meud iomlan",
+       "mediastatistics-header-unknown": "Chan eil fhios",
+       "mediastatistics-header-bitmap": "Dealbhan bitmap",
+       "mediastatistics-header-drawing": "Tàirngean (dealbhan vector)",
+       "mediastatistics-header-audio": "Fuaim",
+       "mediastatistics-header-video": "Videothan",
+       "mediastatistics-header-multimedia": "Meadhanan beartach",
+       "mediastatistics-header-office": "Oifis",
+       "mediastatistics-header-text": "Teacsa",
+       "mediastatistics-header-executable": "Faidhlichean so-ghnìomhaichte",
+       "mediastatistics-header-archive": "Fòrmatan dùmhlaichte"
 }
index ae70e1a..ae239ba 100644 (file)
        "booksources": "משאבי ספרות חיצוניים",
        "booksources-search-legend": "חיפוש משאבי ספרות חיצוניים",
        "booksources-isbn": "מסת\"ב (ISBN):",
-       "booksources-go": "הצגה",
+       "booksources-search": "חיפוש",
        "booksources-text": "להלן רשימת קישורים לאתרים אחרים המוכרים ספרים חדשים ויד־שנייה, ושבהם עשוי להיות מידע נוסף לגבי ספרים שאתם מחפשים:",
        "booksources-invalid-isbn": "המסת\"ב שניתן כנראה אינו תקין; אנא בדקו אם ביצעתם טעויות בהעתקה מהמידע המקורי.",
        "specialloguserlabel": "בוצעו על־ידי המשתמש:",
index 8fb0354..72d6c62 100644 (file)
        "booksources": "पुस्तकों के स्रोत",
        "booksources-search-legend": "पुस्तकों के स्रोत खोजें",
        "booksources-isbn": "आइ॰एस॰बी॰एन:",
-       "booksources-go": "जायें",
        "booksources-text": "नीचे पुरानी और नई पुस्तकें बेचने वाली वेबसाइटों के एड्रेस हैं, जिसमें आपको आप द्वारा खोजी जाने वाली पुस्तक के बारे में अधिक जानकारी मिल सकती है:",
        "booksources-invalid-isbn": "यह आइ॰एस॰बी॰एन सही नहीं लग रहा है; मूल स्रोत से नकल करने में हुई त्रुटि के लिए जाँचें।",
        "specialloguserlabel": "कर्ता:",
index 53746ac..c91c475 100644 (file)
        "querypage-disabled": "Ova posebna stranica onemogućena je jer bi usporila funkcioniranje projekta.",
        "booksources": "Pretraživanje po ISBN-u",
        "booksources-search-legend": "Traženje izvora za knjigu",
-       "booksources-go": "Kreni",
        "booksources-text": "Ovdje je popis vanjskih poveznica na internetskim stranicama koje prodaju nove i rabljene knjige, ali mogu sadržavati i ostale podatke o knjigama koje tražite:",
        "booksources-invalid-isbn": "Čini se da dani ISBN nije valjan; provjerite greške kopirajući iz izvornika.",
        "specialloguserlabel": "Suradnik:",
index 62f05c2..43bc21f 100644 (file)
        "createaccount-text": "Valaki létrehozott számodra egy \"$2\" nevű {{SITENAME}}-azonosítót ($4).\nA hozzá tartozó jelszó \"$3\", melyet a bejelentkezés után minél előbb változtass meg.\n\nHa nem kértél új azonosítót, és tévedésből kaptad ezt a levelet, hagyd figyelmen kívül.",
        "login-throttled": "Túl sok hibás bejelentkezés.\nVárj $1, mielőtt újra próbálkozol.",
        "login-abort-generic": "A bejelentkezés sikertelen – megszakítva",
-       "login-migrated-generic": "A fiók áttelepítése megtörtént, felhasználóneve már nem létezik ezen a wikin.",
+       "login-migrated-generic": "A fiók áttelepítése megtörtént, felhasználóneved már nem létezik ezen a wikin.",
        "loginlanguagelabel": "Nyelv: $1",
        "suspicious-userlogout": "A kijelentkezési kérésed vissza lett utasítva, mert úgy tűnik, hogy egy hibás böngésző vagy gyorsítótárazó proxy küldte.",
        "createacct-another-realname-tip": "A valódi nevet nem kötelező megadni, de ha úgy döntesz, hogy megadod, azzal leszel feltüntetve a munkád szerzőjeként.",
        "querypage-disabled": "Ez a speciális lap a megfelelő teljesítmény fenntartása érdekében le van tiltva.",
        "booksources": "Könyvforrások",
        "booksources-search-legend": "Könyvforrások keresése",
-       "booksources-go": "Keresés",
+       "booksources-search": "Keresés",
        "booksources-text": "Alább látható a másik webhelyekre mutató hivatkozások listája, ahol új és használt könyveket árulnak, és\ntovábbi információkat lelhetsz ott az általad keresett könyvekről:",
        "booksources-invalid-isbn": "A megadott ISBN hibásnak tűnik; ellenőrizd, hogy jól másoltad-e át az eredeti forrásból.",
        "specialloguserlabel": "Szerkesztő:",
        "version-hook-name": "Hook neve",
        "version-hook-subscribedby": "Használja",
        "version-version": "(verzió: $1)",
-       "version-no-ext-name": "(nincs név)",
+       "version-no-ext-name": "[nincs név]",
        "version-license": "MediaWiki licenc",
        "version-ext-license": "Licenc",
        "version-ext-colheader-name": "Kiterjesztés",
index 3edf919..3ad582d 100644 (file)
        "userlogin-resetlink": "Datos de authentication oblidate?",
        "userlogin-resetpassword-link": "Contrasigno oblidate?",
        "userlogin-helplink2": "Adjuta al accesso",
+       "userlogin-loggedin": "Tu ha jam aperite session como {{GENDER:$1|$1}}.\nUsa le formulario sequente pro aperir session como altere usator.",
+       "userlogin-createanother": "Crear un altere conto",
        "createacct-emailrequired": "Adresse de e-mail",
        "createacct-emailoptional": "Adresse de e-mail (optional)",
        "createacct-email-ph": "Entra tu adresse de e-mail",
        "passwordreset-emailsent-capture": "Un message de e-mail pro le reinitialisation del contrasigno ha essite inviate; iste message es monstrate hic infra.",
        "passwordreset-emailerror-capture": "Un e-mail pro le reinitialisation del contrasigno ha essite generate; iste message es monstrate hic infra, ma le invio al {{GENDER:$2|usator}} ha fallite: $1",
        "changeemail": "Cambiar adresse de e-mail",
-       "changeemail-header": "Cambiar le adresse de e-mail del conto",
        "changeemail-text": "Completa iste formulario pro cambiar tu adresse de e-mail. Essera necessari entrar tu contrasigno pro confirmar iste cambio.",
        "changeemail-no-info": "Tu debe aperir un session pro poter acceder directemente a iste pagina.",
        "changeemail-oldemail": "Adresse de e-mail actual:",
        "changeemail-none": "(nulle)",
        "changeemail-password": "Contrasigno de {{SITENAME}}:",
        "changeemail-submit": "Cambiar e-mail",
-       "changeemail-cancel": "Cancellar",
        "changeemail-throttled": "Tu ha facite troppo de tentativas de aperir session.\nPer favor attende $1 ante de probar lo novemente.",
        "resettokens": "Reinitialisar indicios",
        "resettokens-text": "Hic tu pote reinitialisar le indicios que permitte le accesso a certe datos private associate a tu conto.\n\nTu deberea facer lo si tu los ha accidentalmente dividite con un altere persona o si tu conto ha essite compromittite.",
        "searchall": "totes",
        "showingresults": "Infra se monstra non plus de {{PLURAL:$1|'''1''' resultato|'''$1''' resultatos}} a partir del numero '''$2'''.",
        "showingresultsinrange": "In basso es monstrate usque a {{PLURAL:$1|<strong>1</strong> resultato|<strong>$1</strong> resultatos}} inter #<strong>$2</strong> e #<strong>$3</strong>.",
+       "search-showingresults": "{{PLURAL:$4|Resultato <strong>$1</strong> de <strong>$3</strong>|Resultatos <strong>$1 - $2</strong> de <strong>$3</strong>}}",
        "search-nonefound": "Le recerca non ha producite resultatos.",
        "powersearch-legend": "Recerca avantiate",
        "powersearch-ns": "Cercar in spatios de nomines:",
        "prefs-tokenwatchlist": "Indicio",
        "prefs-diffs": "Differentias",
        "prefs-help-prefershttps": "Iste preferentia habera effecto a partir de tu proxime session.",
+       "prefswarning-warning": "To ha facite modificationes in tu preferentias que non ha ancora essite confirmate. Si tu quita iste pagina sin cliccar sur \"$1\", tu preferentias non essera cambiate.",
        "prefs-tabs-navigation-hint": "Consilio: Tu pote usar le claves de sagitta sinistre e dextre pro navigar inter le schedas in le lista.",
        "email-address-validity-valid": "Sembla valide",
        "email-address-validity-invalid": "Un adresse valide es obligatori!",
        "querypage-disabled": "Iste pagina special es disactivate pro evitar de supercargar le systema.",
        "booksources": "Fontes de libros",
        "booksources-search-legend": "Cercar fontes de libros",
-       "booksources-go": "Va",
        "booksources-text": "Infra es un lista de ligamines a altere sitos que vende libros nove e usate, e pote etiam haber altere informationes super libros que tu cerca:",
        "booksources-invalid-isbn": "Le ISBN date non pare esser valide; verifica que tu non ha facite errores copiante lo del fonte original.",
        "specialloguserlabel": "Executor:",
        "protect-othertime": "Altere duration:",
        "protect-othertime-op": "altere duration",
        "protect-existing-expiry": "Expiration existente: le $2 a $3",
+       "protect-existing-expiry-infinity": "Termino de expiration existente: infinite",
        "protect-otherreason": "Motivo altere/additional:",
        "protect-otherreason-op": "Altere motivo",
        "protect-dropdown": "*Motivos commun de protection\n** Vandalismo excessive\n** Spam excessive\n** Guerra de modificationes contraproductive\n** Pagina frequentemente visitate",
        "unblocked": "[[User:$1|$1]] ha essite disblocate",
        "unblocked-range": "$1 ha essite disblocate",
        "unblocked-id": "Le blocada $1 ha essite eliminate",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]] ha essite disblocate.",
        "blocklist": "Usatores blocate",
        "ipblocklist": "Usatores blocate",
        "ipblocklist-legend": "Cercar un usator blocate",
        "logentry-upload-overwrite": "$1 {{GENDER:$2|ha incargate}} un nove version de $3",
        "logentry-upload-revert": "$1 {{GENDER:$2|ha incargate}} $3",
        "rightsnone": "(nulle)",
+       "revdelete-summary": "summario del modification",
        "feedback-bugornote": "Si tu es preste a describer un problema technic in detalio, per favor [$1 reporta un falta].\nSi non, tu pote usar le formulario facile hic infra. Tu commento essera addite al pagina \"[$3 $2]\", con tu nomine de usator e le navigator del web que tu usa.",
        "feedback-subject": "Subjecto:",
        "feedback-message": "Message:",
        "log-description-pagelang": "Isto es un registro de cambios de lingua in paginas.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|cambiava}} le lingua del pagina $3 de $4 a $5.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (activate)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disactivate''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''disactivate''')",
+       "mediastatistics": "Statisticas de multimedia",
+       "mediastatistics-summary": "Statisticas sur le typos de file incargate. Isto include solmente le version le plus recente de un file. Versiones ancian o delite de files es excludite.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 byte|$1 bytes}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "Typo MIME",
+       "mediastatistics-table-extensions": "Extensiones possibile",
+       "mediastatistics-table-count": "Numero de files",
+       "mediastatistics-table-totalbytes": "Dimension combinate",
+       "mediastatistics-header-unknown": "Incognite",
+       "mediastatistics-header-bitmap": "Imagines de mappa de bits",
+       "mediastatistics-header-drawing": "Designos (imagines vectorial)",
+       "mediastatistics-header-audio": "Audio",
+       "mediastatistics-header-video": "Video",
+       "mediastatistics-header-multimedia": "Multimedia complexe",
+       "mediastatistics-header-office": "Officio",
+       "mediastatistics-header-text": "Textual",
+       "mediastatistics-header-executable": "Executabiles",
+       "mediastatistics-header-archive": "Formatos comprimite"
 }
index 056d4ca..d785a51 100644 (file)
        "prefs-tokenwatchlist": "Tanda",
        "prefs-diffs": "Beda",
        "prefs-help-prefershttps": "Preferensi ini akan diaktifkan kali berikutnya Anda masuk log.",
+       "prefswarning-warning": "Perubahan preferensi anda belum tersimpan. Apabila anda meninggalkan halaman ini tanpa men-klik \"$1\" preferensi anda tidak akan diperbarui.",
        "prefs-tabs-navigation-hint": "Tip: Anda dapat menggunakan tombol panah kiri dan kanan untuk bernavigasi antartab di dalam daftar tab.",
        "email-address-validity-valid": "Alamat surel tampaknya sah",
        "email-address-validity-invalid": "Masukkan alamat surel yang sah",
        "booksources": "Sumber buku",
        "booksources-search-legend": "Cari di sumber buku",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Tuju ke",
        "booksources-text": "Di bawah ini adalah daftar pranala ke situs lain yang menjual buku baru dan bekas, dan mungkin juga mempunyai informasi lebih lanjut mengenai buku yang sedang Anda cari:",
        "booksources-invalid-isbn": "ISBN yang diberikan tampaknya tidak valid; periksa kesalahan penyalinan dari sumber asli.",
        "specialloguserlabel": "Pengguna:",
        "log-description-pagelang": "Ini adalah log perubahan dalam bahasa halaman.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|mengubah}} bahasa halaman $3 dari $4 menjadi $5.",
        "mediastatistics-summary": "Statistik tentang jenis file yang terunggah. Ini hanya mencakup versi terbaru dari sebuah file. Terkecuali file lama dan file yang sudah dihapus",
+       "mediastatistics-table-count": "Jumlah file",
+       "mediastatistics-table-totalbytes": "Ukuran gabungan",
        "mediastatistics-header-unknown": "Tidak diketahui",
-       "mediastatistics-header-video": "Video"
+       "mediastatistics-header-bitmap": "Gambar bitmap",
+       "mediastatistics-header-audio": "Audio",
+       "mediastatistics-header-video": "Video",
+       "mediastatistics-header-office": "Office",
+       "mediastatistics-header-text": "Tekstual",
+       "mediastatistics-header-executable": "Executable",
+       "mediastatistics-header-archive": "Format terkompresi"
 }
index fe04b20..2acfdaf 100644 (file)
        "createacct-benefit-body2": "{{PLURAL:$1|pagina|pagine}}",
        "createacct-benefit-body3": "{{PLURAL:$1|contributore recente|contributori recenti}}",
        "badretype": "Le password inserite non coincidono tra loro.",
-       "userexists": "Il nome utente inserito è già utilizzato.\nScegliere un nome utente diverso.",
+       "userexists": "Il nome utente inserito è già utilizzato.\nScegli un nome utente diverso.",
        "loginerror": "Errore durante l'accesso",
        "createacct-error": "Errore durante la creazione dell'utenza",
        "createaccounterror": "Impossibile creare l'account: $1",
        "booksources": "Fonti librarie",
        "booksources-search-legend": "Ricerca di fonti librarie",
        "booksources-isbn": "Codice ISBN:",
-       "booksources-go": "Vai",
+       "booksources-search": "Cerca",
        "booksources-text": "Di seguito sono elencati alcuni collegamenti verso siti esterni che vendono libri nuovi e usati, attraverso i quali è possibile ottenere maggiori informazioni sul testo cercato.",
        "booksources-invalid-isbn": "L'ISBN inserito sembra non essere valido; verificare che non siano stati commessi errori nel copiarlo dalla fonte originale.",
        "specialloguserlabel": "Azione effettuata da:",
index 6650352..b7d051f 100644 (file)
        "otherlanguages": "他言語版",
        "redirectedfrom": "($1から転送)",
        "redirectpagesub": "転送ページ",
+       "redirectto": "転送先:",
        "lastmodifiedat": "このページの最終更新日時は $1 $2 です。",
        "viewcount": "このページは {{PLURAL:$1|$1 回}}アクセスされました。",
        "protectedpage": "保護されたページ",
        "searchall": "すべて",
        "showingresults": "<strong>$2</strong> 件目以降の最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。",
        "showingresultsinrange": "<strong>$2</strong> 件目から<strong>$3</strong> 件目までの範囲内で最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。",
+       "search-showingresults": "{{PLURAL:$4|<strong>$3</strong> 件中の <strong>$1</strong> 件目|<strong>$3</strong> 件中の <strong>$1</strong> 件目から <strong>$2</strong> 件目}}",
        "search-nonefound": "問い合わせに合致する検索結果はありませんでした。",
        "powersearch-legend": "高度な検索",
        "powersearch-ns": "名前空間を指定して検索:",
        "prefs-tokenwatchlist": "トークン",
        "prefs-diffs": "差分",
        "prefs-help-prefershttps": "この設定は、次回ログインの際に反映されます。",
+       "prefswarning-warning": "個人設定にまだ保存されていない変更があります。\n「$1」をクリックせずに離れた場合、個人設定は更新されません。",
        "prefs-tabs-navigation-hint": "ヒント: ← キーと → キーで、タブ一覧内のタブ間を移動できます。",
        "email-address-validity-valid": "メールアドレスは有効のようです",
        "email-address-validity-invalid": "有効なメールアドレスを入力してください",
        "booksources": "書籍情報源",
        "booksources-search-legend": "書籍情報源を検索",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "検索",
        "booksources-text": "お探しの書籍の新品/中古品を販売している外部サイトへのリンクを以下に列挙します。この書籍についてさらに詳しい情報があるかもしれません:",
        "booksources-invalid-isbn": "指定した ISBN は有効ではないようです。情報源から写し間違えていないか確認してください。",
        "specialloguserlabel": "実行者:",
        "protect-othertime": "その他の期間:",
        "protect-othertime-op": "その他の期間",
        "protect-existing-expiry": "現在の保護期限: $2 $3",
+       "protect-existing-expiry-infinity": "既存の有効期限: 無期限",
        "protect-otherreason": "他の、または追加の理由:",
        "protect-otherreason-op": "その他の理由",
        "protect-dropdown": "*よくある保護理由\n** 度重なる荒らし\n** 度重なるスパム投稿\n** 非生産的な編集合戦\n** 高負荷ページ",
        "unblocked": "[[User:$1|$1]]のブロックを解除しました。",
        "unblocked-range": "$1のブロックを解除しました。",
        "unblocked-id": "ブロック$1を除去しました。",
+       "unblocked-ip": "[[Special:Contributions/$1|$1]]はブロックされています。",
        "blocklist": "ブロックされている利用者",
        "ipblocklist": "ブロックされている利用者",
        "ipblocklist-legend": "ブロックされている利用者の検索",
        "default-skin-not-found": "おっと! あなたのウィキの既定の外装「<code>$1</code>」 (<code>$wgDefaultSkin</code>)は利用できません。\n\nあなたのインストールには以下の外装が含まれています。外装の有効化と既定の選択については、[https://www.mediawiki.org/wiki/Manual:Skin_configuration マニュアル: 外装設定] をご覧ください。\n\n$2\n\n; MediaWikiをインストールしたばかりの場合:\n: gitからインストールしたか、その他の何らかの方法でソースコードから直接インストールした場合には、これは期待されたとおりの動作です。\n:* [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] から外装をインストールしてみてください。\n:* [https://www.mediawiki.org/wiki/Download tarball installer] をダウンロードしてみてください。これにはいくつかの外装と拡張機能が含まれています。 <code>skins/</code> ディレクトリからコピー&ペーストできます。\n: あなたがMediaWiki開発者の場合、これを行うことであなたのgitリポジトリに干渉することはありません。\n\n; MediaWiki をアップグレードした場合:\n: MediaWiki 1.24 以降のバージョンでは、インストール済みの外装は自動的には有効になりません。 ([https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery マニュアル:外装の自動探索] をご覧ください)。<code>LocalSettings.php</code> に以下の行をペーストして、現在インストールされている外装を有効にできます。\n\n<pre>$3</pre>\n\n; <code>LocalSettings.php</code>を編集したばかりの場合:\n: 外装名に打ち間違いがないか再度確認してください。",
        "default-skin-not-found-no-skins": "おっと! あなたのウィキの既定の外装「<code>$1</code>」 (<code>$wgDefaultSkin</code>)は利用できません。\n\n外装をインストールしていません。\n\n; MediaWikiをインストールしたばかりの場合:\n: gitからインストールしたか、その他の何らかの方法でソースコードから直接インストールした場合には、これは期待されたとおりの動作です。\n:* [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory] から外装をインストールしてみてください。\n:* [https://www.mediawiki.org/wiki/Download tarball installer] をダウンロードしてみてください。これには外装と拡張機能がいくつか含まれています。 <code>skins/</code> ディレクトリからコピー&ペーストできます。\n: あなたがMediaWiki開発者の場合、これを行うことであなたのgitリポジトリに干渉することはありません。外装の有効化と既定の選択についての情報は、[https://www.mediawiki.org/wiki/Manual:Skin_configuration マニュアル:外装設定] をご覧ください。",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (有効)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''無効''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''無効''')",
+       "mediastatistics": "メディア統計",
+       "mediastatistics-summary": "アップロードされたファイルの種類に関する統計。これはファイルの最新バージョンのみを含みます。以前のまたは削除されたバージョンについては除外されています。",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 バイト|$1 バイト}} ($2; $3%)",
+       "mediastatistics-table-mimetype": "MIMEタイプ",
+       "mediastatistics-table-extensions": "取りうる拡張子",
+       "mediastatistics-table-count": "ファイル数",
+       "mediastatistics-table-totalbytes": "合計サイズ",
+       "mediastatistics-header-unknown": "不明",
+       "mediastatistics-header-bitmap": "ビットマップ画像",
+       "mediastatistics-header-drawing": "線画 (ベクタイメージ)",
+       "mediastatistics-header-audio": "オーディオ",
+       "mediastatistics-header-video": "動画",
+       "mediastatistics-header-multimedia": "リッチメディア",
+       "mediastatistics-header-office": "オフィス",
+       "mediastatistics-header-text": "テキスト",
+       "mediastatistics-header-executable": "実行ファイル",
+       "mediastatistics-header-archive": "圧縮フォーマット"
 }
index fab353a..f9f977b 100644 (file)
        "booksources": "წიგნის წყაროები",
        "booksources-search-legend": "წიგნის წყაროს ძებნა",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "გადასვლა",
        "booksources-text": "ქვემოთ არის ვებ გვერდების ბმულების სია სადაც იყიდება ახალი და ნახმარი წიგნები, და შესაძლოა შეიცავდნენ დამატებით ინფორმაციას წიგნების შესახებ, რომლებსაც ეძებთ:",
        "booksources-invalid-isbn": "თქვენს მიერ მითითებული ISBN, შეცდომას შეიცავს.  შეამოწმეთ, თუ თავდაპირველი წყარო სწორადაა აკრეფილი.",
        "specialloguserlabel": "შემსრულებელი:",
index da11257..084e444 100644 (file)
        "otherlanguages": "En ander Schprooche",
        "redirectedfrom": "(Ömjeleit vun $1)",
        "redirectpagesub": "Ömleidongssigg",
+       "redirectto": "Ömleide op:",
        "lastmodifiedat": "Heh di Sigg es et letz aam $1 öm $2 Uhr jeändert woode.",
        "viewcount": "De Sigg es bes jetz {{PLURAL:$1|eimol|$1 Mol|keijmol}} avjerofe woode.",
        "protectedpage": "Jeschötzte Sigg",
        "hidetoc": "ußblände",
        "collapsible-collapse": "Zohklappe",
        "collapsible-expand": "Opklappe",
+       "confirmable-confirm": "{{GENDER:$1|Verhaftesch}}?",
+       "confirmable-yes": "Joh",
+       "confirmable-no": "Nää",
        "thisisdeleted": "$1 - aanluure oder widder zeröckholle?",
        "viewdeleted": "$1 aanzeije?",
        "restorelink": "{{PLURAL:$1|eijn fottjeschmesse Änderung|$1 fottjeschmesse Änderunge|keij fottjeschmesse Änderunge}}",
        "passwordreset-emailsent-capture": "En <i lang=\"en\">e-mail</i> met Aanjaabe zom neue Paßwoot för der Zohjang heh es verscheck woode. Heh dronger kanns De se lässe.",
        "passwordreset-emailerror-capture": "En <i lang=\"en\">e-mail</i> met Aanjaabe zom neue Paßwoot för der Zohjang heh sullt verscheck wääde, ävver dat Verschecke aan {{GENDER:$2|dä|dat|dä Metmaacher|de|dat}} $2 hät nit jeflup: $1",
        "changeemail": "Donn Ding Address för de <i lang=\"en\">e-mail</i> ändere",
-       "changeemail-header": "Donn en Adräß för de <i lang=\"en\">e-mail</i> ändere",
        "changeemail-text": "Föll dat Fommulaa uß, öm Ding Adräß för de <i lang=\"en\">e-mail</i> ze ändere.\nDo moß Ding Paßwoot enjävve, öm Ding Änderong ze bschtäätejje.",
        "changeemail-no-info": "Do mööts ald enjelogg sin, öm tiräk op di Sigg jonn ze dörve",
        "changeemail-oldemail": "Ding Address för de <i lang=\"en\">e-mail</i> es jäz:",
        "changeemail-none": "(kein)",
        "changeemail-password": "Ding Passwoot {{GRAMMAR:en 3|{{ucfirst:{{SITENAME}}}}}}:",
        "changeemail-submit": "Lohß jonn!",
-       "changeemail-cancel": "Ophüre",
        "changeemail-throttled": "Do häs zoh öff versöhk, enzelogge. Waat $1 Ih dat De es widder probeers.",
        "resettokens": "Neue Schlößel maache",
        "resettokens-text": "Do kanns neue Schlößel maache lohße för op beschtemmpte päsöhnlesche Daate uohjriife ze künne, di met Dingem Zohjang heh ze donn han.\n\nDonn dat op jeede Fall, wann se enem Andere bikannt jewoode sin, udder wann Dinge Zohjang jeknack woode es.",
        "searchall": "all",
        "showingresults": "Onge {{PLURAL:$1|weed <strong>eine</strong>|wääde bes <strong>$1</strong>|weed <strong>keine</strong>}} vun de jefonge Endrähsch jezeisch, vun de Nommer <strong>$2</strong> av.",
        "showingresultsinrange": "{{PLURAL:$1|<strong>Ein</strong> Saachjropp|<strong>$1</strong> Saachjroppe|Kein Saachjropp}}, vun Nommer <strong>$2</strong> bes Nommer <strong>$3</strong> {{PLURAL:$1|weed|wääde|weed}} heh opjeleß.",
-       "showingresultsheader": "Jefonge un aanjezeisch: {{PLURAL:$5|'''$1''' vun '''$3'''|'''$1''' beß '''$2''' vun '''$3'''|nix}} för '''$4'''",
+       "search-showingresults": "{{PLURAL:$4|Heh es dä <strong>$1</strong>-te vun <strong>$3</strong> Träffere.|Träffer Nommero <strong>$1 bes $2</strong> vun <strong>$3</strong> Träffer.|Jevonge woodt woodt nix.}}",
        "search-nonefound": "Mer han nix zopaß jefonge för Ding Aanfrohch.",
        "powersearch-legend": "Extra Söhke",
        "powersearch-ns": "Söök en de Apachtemangs:",
        "prefs-registration-date-time": "dem $2 öm $3 Uhr",
        "yourrealname": "Dinge richtije Name *",
        "yourlanguage": "Di Schprooch, di et Wiki kalle soll:",
-       "yourvariant": "Der Dijaläk, de Schriefwies, de Zoot Shprooch för der Enhald.",
-       "prefs-help-variant": "Der Dijaläk udder de Schriefwies udder de Zoot Shprooch, di De för der Enhald.vun Sigge am leevsde häs.",
+       "yourvariant": "Der Dijaläk, de Schriefwies, de Zoot Schprohch för der Enhald:",
+       "prefs-help-variant": "Der Dijalägg udder de Schriefwies udder de Zoot Schprohch, di De för der Enhald vun Sigge am leevsde häß.",
        "yournick": "Ding&nbsp;„Ongerschreff“&nbsp;*",
        "prefs-help-signature": "* Beidrääsch op Klaafsigge sullte met „<nowiki>~~~~</nowiki>“ ophüere, dat weed beim Afshpeishere en Ding „Ongerschreff“ met de Uhrzig un em Dattum ömjewandelt.",
        "badsig": "Di Ungeschreff jëijd_esu nit — luer noh dem HTML do_dren un maach et rėshtėsh.",
        "right-browsearchive": "Noh fottjeschmesse Sigge söke",
        "right-undelete": "Fottjeschmeße Sigge widder zeröck holle",
        "right-suppressrevision": "Versione vun Sigge beloore un zeröck holle, di sujaa för de Wiki-Köbesse verstoche sin",
+       "right-viewsuppressed": "Beloor de Väsjohne, di vun jeedem verschtoche sin.",
        "right-suppressionlog": "De private Logböcher aanloore",
        "right-block": "Medmaacher Sperre, un domet am Schrive hindere",
        "right-blockemail": "Metmaacher för et E-Mail Verschecke sperre",
        "windows-nonascii-filename": "Heh dat Wiki löht kein Datteiname met Sönderzeische zoh.",
        "fileexists": "Et jitt ald en Datei met däm Name.\nWann De op „Datei avspeichere“ klicks, weed se ersetz.\nBes esu jod  un luur Der <strong>[[:$1]]</strong> aan, wann De nit 100% secher bes.\n[[$1|thumb]]",
        "filepageexists": "En Sigg övver di Datei met däm Tittel <strong>[[:$1]]</strong> es ald doh, ävver en Datei met däm Name ham_mer nit. Dinge Tex kütt nit automattesch op di Sigg övver di Dattei. Di Sigg moß De wann nüüdesch noch ens extra ändere.\n[[$1|thumb]]",
-       "fileexists-extension": "Mer han ald en Dattei, di bahl jenou esu heijß: [[$2|thumb]]\n* Huh am laade sim_mer: <strong>[[:$1]]</strong>\n* Ald om ßörve eß:</td><td><strong>[[:$2]]</strong>\nBes esu joot, un söök Der ene ander Name fö di Datei us.",
+       "fileexists-extension": "Mer han ald en Dattei, di bahl jenou esu heijß: [[$2|thumb]]\n* Huh am laade sim_mer: <strong>[[:$1]]</strong>\n* Ald om ßörve eß: <strong>[[:$2]]</strong>\nWels De nit leever ene andere Nahme fö di Datei ußsöhke?",
        "fileexists-thumbnail-yes": "Dat süühd uß, wi wann dat hee en Minni-Beldsche em Breefmarrke-Fommaat (''<span lang=\"en\">thumbnail</span>'') wöhr. [[$1|thumb]]\nDon ens di Dattei <strong>[[:$1]]</strong> prööfe.\nWann dat de Orjinaaljrüß es, do moß keij för dat Beld keij extra Vör-Aansich huhjelade wäde.",
        "file-thumbnail-no": "Dä Name fö di Datei fängk met <strong>$1</strong> aan.\nDat süühd uß, wi wann dat en Minni-Beldsche em Breefmarrke-Fommaat\n(''<span lang=\"en\">thumbnail</span>'') wöhr. Don ens di Dattei\n<strong>$1</strong> prööfe, of de nit e besser opjelööß Beld\ndofun häß, un don dat met singe Orjinaaljrüß huhlade, wann möjjelesch.\nSöns donn besser ene andere Dateiname ußsöke.",
        "fileexists-forbidden": "Et jitt ald en Dattei met däm Name, un mer kann se nit övverschriive.\nWann de Ding Dattei trozdämm huhlaade wells, da jangk zeröck un lad se\nunger enem andere Name huh. [[File:$1|thumb|center|$1]]",
        "randomincategory": "En zohfälleje Sigg us ener Saachjropp",
        "randomincategory-invalidcategory": "„$1“ es keine jölteje Nahme för en Saachjropp.",
        "randomincategory-nopages": "et sinn er kein Sigge en dä Saachjropp [[:Category:$1|$1]] dren.",
-       "randomincategory-selectcategory": "Holl en zohfälleje Sigg us dä Saachjropp: $1 $2.",
-       "randomincategory-selectcategory-submit": "Lohß Jonn!",
+       "randomincategory-category": "Saachjropp:",
+       "randomincategory-legend": "En zohfälleje Sigg us dä Saachjropp",
        "randomredirect": "Zofällije Ömleitung",
        "randomredirect-nopages": "En däm Appachtemang „$1“ sin ja kein Ömleidonge dren.",
        "statistics": "Schtatistike",
        "booksources": "Böcher",
        "booksources-search-legend": "Söök noh Bezochsquelle för Bööcher",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Lohß Jonn!",
+       "booksources-search": "Söhke",
        "booksources-text": "Hee noh küdd_en Leßß met Websigge,\nwo mir {{GRAMMAR:Dative fun|{{SITENAME}}}} nix wigger med ze donn hänn,\nwo mer jät övver Böösher erfaare\nun zom Dëijl och Böösher koufe kann.\nDoför moßß De Desh mannshmool allodengs eetß ennß aanmällde,\nwat Koßte un Jefaare met sesh brenge künndt.\nWo_t jëijdt,\njonn di Lengkß hee tirrägg_op dat Booch,\nwadd_Er am Sööke sidt.",
        "booksources-invalid-isbn": "De ISBNummer schingk verkeeht ze sin. Loohr ens donoh, woh se häe kütt.",
        "specialloguserlabel": "Dä Metmaacher, dä et jedonn hät:",
        "listgrouprights-removegroup-self-all": "Kann sesch sällver uß alle Metmaacherjroppe eruß nämme",
        "listgrouprights-namespaceprotection-namespace": "Appachtemang",
        "trackingcategories-name": "Dä Nohreesch udder däm Täxschtöck singe Nahme",
+       "broken-file-category-desc": "En heh dä Sigg es ene Lengk obb en Dattei, di mer nit han.",
        "trackingcategories-disabled": "Di Saachjrobb es afjeschalldt.",
        "mailnologin": "Keij E-Mail Adress",
        "mailnologintext": "Do mööts ald aanjemeldt un [[Special:UserLogin|enjelogg]] sin, un en jode E-Mail\nAdress en Dinge [[Special:Preferences|ming Enstellunge]] stonn han, öm en E-Mail aan andere Metmaacher ze\nschecke.",
        "mywatchlist": "Oppaßleß",
        "watchlistfor2": "För dä $1 $2",
        "nowatchlist": "En Ding Oppassliss es nix dren.",
-       "watchlistanontext": "Do muss $1, domet de en Ding Oppassliss erenluure kanns, oder jet dran ändere.",
+       "watchlistanontext": "Do moß enlogge, domet de en Ding Oppassliss erenluure kanns, oder jet dran ändere.",
        "watchnologin": "Nit enjelogg",
        "addwatch": "En de Oppassliss don",
        "addedwatchtext": "Die Sigg „[[:$1]]“ es jetz en Dinge [[Special:Watchlist|Oppaßleß]].\nWann di Sigg udder ier Klaafsigg verändert weed, kütt dat af jäz heh en di Oppaßleß.",
        "watchlist-details": "Do häß {{PLURAL:$1|ein Sigg|$1 Sigge|kein Sigg}} en Dinge Oppaßleß{{PLURAL:$1|, un di Klaafsigg dohzoh|, un de Klaafsigge dohzoh|}}.",
        "wlheader-enotif": "Et <i lang=\"en\">e-mail</i> Schecke es enjeschalt.",
        "wlheader-showupdated": "Wann se Einer jeändert hätt, zickdäm De se et letzte Mol aanjeluurt häs, sin die Sigge <strong>extra markeet</strong>.",
-       "wlnote": "{{PLURAL:$1|Hee es de letzte Änderung us|Hee sin de letzte <strong>$1</strong> Änderunge us|Mer han kein Äbderunge en}} de letzte {{PLURAL:$2|Stund|<strong>$2</strong> Stunde|<strong>noll</strong> Stunde}} zigg em $3 öm $4 Uhr.",
+       "wlnote": "{{PLURAL:$1|Hee es de läzde Änderong uß|Hee sin de läzde <strong>$1</strong> Änderonge uß|Mer han kein Änderonge en}} de läzde {{PLURAL:$2|Stund|<strong>$2</strong> Stunde|<strong>noll</strong> Stunde}} zigg em $3 öm $4 Uhr.",
        "wlshowlast": "Zeich de letzte | $1 | Stunde | $2 | Dage | $3 | aan, dun",
        "watchlist-options": "Eijeschaffte fun de Oppassless",
        "watching": "Drop oppasse…",
        "exbeforeblank": "drop stundt vörher: „$1“",
        "delete-confirm": "„$1“ fottschmieße",
        "delete-legend": "Fottschmieße",
-       "historywarning": "<strong>Opjepass:</strong> Die Sigg, di De fott schmiiße wells, hät {{PLURAL:$1|ein ällder Version|ald Stöcker $1 ällder Versione|jaa kei ällder Versione}}.",
+       "historywarning": "<strong>Opjepass:</strong> Die Sigg, di De fott schmiiße wells, hät {{PLURAL:$1|ein ällder Väsjohn|ald $1 ällder Väsjohne|jaa kein ällder Väsjohne}}.",
        "confirmdeletetext": "Do bes koot dovör, en Sigg för iwich fottzeschmieße. Dobei verschwind och de janze Verjangenheit vun dä Sigg us de Daatebank, met all ehr Änderunge un Metmaacher Name, un all dä Opwand, dä do dren stich. Do muss heh jetz bestätije, dat de versteihs, wat dat bedügg, un dat De weiß, wat Do do mähs.\n<strong>Dun et nor, wann dat met de [[{{MediaWiki:Policy-url}}|Rejelle]] wirklich zosamme jeiht!</strong>",
        "actioncomplete": "Jedonn!",
        "actionfailed": "Dat es donevve jejange",
        "delete-edit-reasonlist": "De Jrönde för et Fottschmieße beärbeide",
        "delete-toobig": "Di Sigg hät {{PLURAL:$1|ein Version|$1 Versione|jaa kein Version}}. Dat sinn_er ärsch fill. Domet unsere ẞööver do nit draan en de Kneen jeit, dom_mer esu en Sigg nit fottschmieße.",
        "delete-warning-toobig": "Di Sigg hät {{PLURAL:$1|ein Version|$1 Versione|jakein Version}}. Dat sinn_er ärsch fill. Wann De die all fottschmieße wells, dat kann dem Wiki sing Datenbangk schwer ußbremse.",
-       "deleting-backlinks-warning": "<strong>Opjepaß:</strong> Es jitt Sigge met Lenks noh heh doh, udder Sigge, di heh di Sigg enbenge!",
+       "deleteprotected": "Di Sigg es jeschöz, un dröm kam_mer se nit fott schmiiße.",
+       "deleting-backlinks-warning": "<strong>Opjepaß:</strong> Es jitt Sigge met Lengks noh heh, udder Sigge, di heh di Sigg enbenge!",
        "rollback": "Em Letzte sing Änderunge zeröcknemme",
        "rollback_short": "Zeröcknemme",
        "rollbacklink": "All dem Letzte sing Änderunge zeröckdriehe",
        "protect-locked-blocked": "Do kanns nit der Siggeschotz ändere, esu lang wi Dinge Zojang zom Wiki jesperrt es. Hee es der aktuelle Stand fum Siggeschotz för di Sigg '''„$1“:'''",
        "protect-locked-dblock": "De Datebank es jesperrt. Dröm künne mer der Siggeschotz nit ändere.\nHee es der aktuelle Stand fum Siggeschotz för di Sigg '''„$1“:'''",
        "protect-locked-access": "Do häs nit dat Rääsch, heh em Wiki Sigge ze schötze udder dä Schotz widder opzehevve.\nDi Sigg '''„$1“:''' es jetz jrad:",
-       "protect-cascadeon": "Die Sigg es en enne Schotz-Kaskad. Se es enjebonge en {{PLURAL:$1|die Sigg|$1 Sigge|kein Sigg}}, die per Kaskade-Schotz jeschötz {{PLURAL:$1|es|sin|es}}. Do kanns dä Schotz för die Sigg heh ändere, ävver di Kaskad blief bestonn. Dat heh sin die Sigge en dä Kaskad:",
+       "protect-cascadeon": "Die Sigg es en enne Schotz-Kaskad. Se es enjebonge en {{PLURAL:$1|einSigg|$1 Sigge|kein Sigg}}, die per Kaskade-Schotz jeschötz {{PLURAL:$1|es|sin|es}}. Do kanns dä Schotz för die Sigg heh ändere, ävver di Kaskad blief bestonn.",
        "protect-default": "Jeede Metmaacher eraan lohße",
        "protect-fallback": "Do weet dat Rääsch „$1“ jebruch.",
        "protect-level-autoconfirmed": "Bloß de automattesch beschtääteschte Metmaacher dranlooße",
        "protect-othertime": "En ander Door:",
        "protect-othertime-op": "en ander Door",
        "protect-existing-expiry": "Beß am $2 öm $3 Uhr",
+       "protect-existing-expiry-infinity": "Dä schöz bliev em momang för iewisch beschtonn.",
        "protect-otherreason": "En andere udder zosätzlijje Jrund:",
        "protect-otherreason-op": "Ene andere udder zosätzlijje Jrond",
        "protect-dropdown": "* Jewöhnlijje Jrönd för dä Sigge-Schotz\n** ußerjewöhnlesch fill Kapottmaacherei\n** ußerjewöhnlesch fill SPAMlinks op ander Sigge wäde neu enjedraare\n** Hen- un her-Änderei, woh mer süht, dat nix mieh joods erus kumme weed\n** janz weschtejje Sigg, met ußerjewöhnlesch fill Afroofe",
        "autoblockid": "Automattesche Sperr Nommer $1",
        "block": "Metmaacher udder en <i lang=\"en\">IP</i>-Addräß sperre",
        "unblock": "Don en Sperr för ene Metmaacher udder en <i lang=\"en\">IP</i>-Addräß ophävve",
-       "blockip": "Metmaacher sperre",
+       "blockip": "{{GENDER:$1|Dä Metmaacher|De Metmaacherėn|Dä Metmaacher|De Metmaacherėn|Dä Metmaacher}} schpärre",
        "blockip-legend": "Metmaacher ov IP-Adresse Sperre",
        "blockiptext": "Hee kanns De bestemmte Metmaacher oder IP-Adresse sperre, su dat se hee em Wiki nit mieh schrieve und Sigge ändere künne.\nDat sollt nor jedon wääde om sujenannte Vandaale ze bremse. Un mer müsse uns dobei natörlich aan uns [[{{MediaWiki:Policy-url}}|Rejelle]] för esu en Fäll halde.\nDrag bei „Aanlass“ ene möchlichs jenaue Jrund en, wöröm dat Sperre passeet. Nenn un Link op de Sigge wo Einer kapott jemaat hät, zem Beispill.",
        "ipaddressorusername": "<i lang=\"en\">IP</i>-Adress oder Metmaacher Name:",
        "ipb-unblock-addr": "„$1“ widder zohlohße",
        "ipb-unblock": "En IP-Addräß ov ene Metmaacher widder zohlohße",
        "ipb-blocklist": "All de Sperre för Metmaacher un IP-Adresse aanzeije, die jrad bestonn",
-       "ipb-blocklist-contribs": "De Metmaacher ier Bäjdrähsch för „$1“",
+       "ipb-blocklist-contribs": "{{GENDER:$1|Däm|Däm|Däm Metmaacher|Dä|Däm}} $1 {{GENDER:$1|sing|singe|sing|iere|sing}} Bäjdrähsch",
        "unblockip": "Dä Medmacher widder maache looße",
        "unblockiptext": "Heh kanns De vörher jesperrte IP_Adresse oder Metmaacher widder freijevve, un dänne esu dat Rääch för ze Schrieve heh em Wiki widder jevve.",
        "ipusubmit": "Sperr ophevve!",
        "unblocked": "[[User:$1|$1]] wood widder zojelooße",
        "unblocked-range": "Dä Berett $1 es nit mieh jesperrt.",
        "unblocked-id": "De Sperr met dä Nommer $1 es opjehovve",
+       "unblocked-ip": "{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dä}} [[Special:Contributions/$1|$1]] es jäz nit mieh jeschpächt.",
        "blocklist": "De Leß met jesperrte <i lang=\"en\">IP</i>-Adräße un Metmaacher",
        "ipblocklist": "Leß met jesperrte <i lang=\"en\">IP</i>-Adresse un Metmaacher",
        "ipblocklist-legend": "Ene jesperrte Metmaacher fenge",
        "import": "Sigge Emporteere",
        "importinterwiki": "Trans Wiki Emport",
        "import-interwiki-text": "Wähl en Wiki un en Sigg zem Emporteere us.\nEt Datum vun de Versione un de Metmaacher Name vun de Schriever wääde dobei metjenomme.\nAll de Trans Wiki Emporte wääde em [[Special:Log/import|Emport_Logboch]] fassjehallde.",
-       "import-interwiki-source": "Quelle-Wiki un -Sigg:",
        "import-interwiki-history": "All de Versione vun dä Sigg heh kopeere",
        "import-interwiki-templates": "All Schablone metnämme",
        "import-interwiki-submit": "Huhlade!",
        "import-upload": "En XML-Datei impochteere",
        "import-token-mismatch": "Schadt. Et senn nit alle Date heh aanjekumme.\nBes esu joot, un versök et noch ens.",
        "import-invalid-interwiki": "Us dämm jenannte Wiki künne mer nix Importeere.",
-       "import-error-edit": "Di Sigg „$1“ es nit impoteet woode. Do häs nit et Rääsch, se ze ändre.",
-       "import-error-create": "Di Sigg „$1“ es nit impoteet woode. Do häs nit et Rääsch, se aanzlääje.",
-       "import-error-interwiki": "Di Sigg „$1“ weed nit empoteet, weil dä iehre Name för et Verlengke noh ußerhallef, pä Engerwiki-Lengk, jebruch weed.",
-       "import-error-special": "Di Sigg „$1“ weed nit empoteet, weil dä iehre Name en enem besöndere Appachtemang litt, woh kein Sigge dren zohjelohße sin.",
-       "import-error-invalid": "Di Sigg „$1“ weed nit empoteet, weil dä iehre Name nit jöltesch es.",
+       "import-error-edit": "Di Sigg „$1“ es nit impotehrt woode. Do häs nit et Rääsch, se ze ändere.",
+       "import-error-create": "Di Sigg „$1“ es nit impotehrt woode. Do häs nit et Rääsch, se aanzelähje.",
+       "import-error-interwiki": "Di Sigg „$1“ weed nit empotehrt, weil dä iehre Name för et Verlengke noh ußerhallef, pä Engerwikilengk, jebruch weed.",
+       "import-error-special": "Di Sigg „$1“ weed nit empotehrt, weil dä iehre Name en enem besöndere Appachtemang litt, woh kein Sigge dren zohjelohße sin.",
+       "import-error-invalid": "Di Sigg „$1“ weed nit empotehrt, weil dä Sigg iehre Name, woh se hen empotehrt wääde sull, nit jöltesch es.",
        "import-error-unserialize": "De Väsjohn $2 vun dä Sigg „$1“ kunnt nit von serijäll ußjepack wääde. De Väsjohn sull Daate vun dä Zoot „$3“ änthallde un ußjepack „$4“ jävve.",
        "import-options-wrong": "{{PLURAL:$2|En verkiehrte Aanjab|Verkiehrte Aanjabe|Kein verkiehrte Aanjabe}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Di aanjejovve Aanfangssigg hät keine jölteje Tittel.",
        "importlogpage": "Logboch met emporteerte Sigge",
        "importlogpagetext": "Sigge met ehre Versione vun ander Wikis emporteere.",
        "import-logentry-upload": "„[[$1]]“ emporteet fun enne huhjelade Dattei",
-       "import-logentry-upload-detail": "{{PLURAL:$1|ein Version|$1 Versione|kein Version}} emporteet",
+       "import-logentry-upload-detail": "{{PLURAL:$1|ein Väsjohn|$1 Väsjohne|kein Väsjohn}} woodt emportehrt.",
        "import-logentry-interwiki": "hät tirek vum ander Wiki emporteet: „$1“",
-       "import-logentry-interwiki-detail": "{{PLURAL:$1|ein Version|$1 Versione|kein Version}} vun „$2“",
+       "import-logentry-interwiki-detail": "{{PLURAL:$1|ein Väsjohn|$1 Väsjohne|kein VVäsjohnersion}} woodt empottehrt vun „$2“",
        "javascripttest": " JavaSkrepte ußprobeere.",
        "javascripttest-title": "De Prööfunge „$1“ loufe.",
        "javascripttest-pagetext-noframework": "Heh di Sigg es för JavaSkrepte ußzeprobeere.",
        "timezone-utc": "<i lang=\"en\">UTC</i>",
        "unknown_extension_tag": "„<code>$1</code>“ es en zosäzlejje Kennzeichnung, die kenne mer nit.",
        "duplicate-defaultsort": "'''Opjepaß:'''\nDä Shtanndat-Zoot-Schlößel „$1“ övverschriif dä älldere Zoot-Schlößel „$2“.",
+       "duplicate-displaytitle": "<strong>opjepaß:</strong> Dä Nahme „$2“ övverschriev dä fröjere Nahme „$1“ för zem Aanzeije.",
        "version": "Väsjohn vun de Wiki Soffwär zeije",
        "version-extensions": "Installeete Erjänzunge un Zohsätz",
-       "version-skins": "Ovverflääsche",
+       "version-skins": "De enschtallehrte Bedeenbovverflääsche",
        "version-specialpages": "{{int:nstab-special}}e",
        "version-parserhooks": "De Parser-Hooke",
        "version-variables": "Variable",
        "logentry-rights-rights-legacy": "{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 hät däm Metmaacher $3 sing Räääschte-Jroppe verändert.",
        "logentry-rights-autopromote": "{{GENDER:$1|Dä|Et|Dä Metmaacher|De|Dat}} $1 wood automattesch vum $4 zom $5 jemaat.",
        "rightsnone": "(nix)",
+       "revdelete-summary": "dä Täx en „{{int:summary}}“",
        "feedback-bugornote": "Wann de em Bejreff bes, övver e täschesch Probleem ze schrieve, bes esu jood un donn dat als en [$1 Fählermäldong].\nSöns, nemm dat koote Fommulaa heh dronger.\nWat De doh enjiß, kütt met Dingem Metmaachername un Dingem Brauser op die Sigg „[$3 $2]“ drop.",
        "feedback-subject": "Theema:",
        "feedback-message": "Nohreesch:",
        "pagelang-name": "Sigg",
        "pagelang-language": "De Schprooch",
        "pagelang-use-default": "Nemm de Schtandatt_Schprohch",
-       "pagelang-select-lang": "Söhg_en Schprooch uß"
+       "pagelang-select-lang": "Söhg_en Schprooch uß",
+       "right-pagelang": "Ener Sigg ier Schprohch tuusche",
+       "action-pagelang": "Sigge ier Schprohch zu tuusche",
+       "log-name-pagelang": "Logbooch vum Tuusche vun Sige iehr Schprohche"
 }
index 2761b73..e036a64 100644 (file)
        "pager-older-n": "{{PLURAL:$1|kevintir 1|kevintir $1}}",
        "booksources": "Çavkaniyên pirtûkan",
        "booksources-search-legend": "Li pirtûkan bigere",
-       "booksources-go": "Here",
        "booksources-text": "Li vir listek ji lînkên rûpelên, yê pirtûkên nû ya kevin difiroşin, heye. Hên jî li vir tu dikarî înformasyonan li ser wan pirtûkan tê derxê.",
        "specialloguserlabel": "Bikarhêner:",
        "speciallogtitlelabel": "Sernav:",
index e68969d..1974de5 100644 (file)
        "pager-older-n": "{{PLURAL:$1|эскирээк 1|эскирээк $1}}",
        "booksources": "Китеп тууралуу маалыматтар",
        "booksources-search-legend": "Китеп тууралуу маалыматтарды издөө",
-       "booksources-go": "Алга",
        "specialloguserlabel": "Аткаруучу:",
        "speciallogtitlelabel": "Максаты (аталышы же колдонуучу):",
        "log": "Журналдар",
index 72bc31b..aec980f 100644 (file)
        "querypage-disabled": "Dës Spezialsäit ass aus Performance-Grënn ausgeschalt.",
        "booksources": "Bicherreferenzen",
        "booksources-search-legend": "No Bicherreferenze sichen",
-       "booksources-go": "Sichen",
        "booksources-text": "Hei ass eng Lëscht mat Linken op Internetsäiten, déi nei a gebraucht Bicher verkafen. Do kann et sinn datt Dir méi Informatiounen iwwer déi Bicher fannt déi Dir sicht.",
        "booksources-invalid-isbn": "D'ISBN-Nummer déi Dir uginn hutt schéngt net gëlteg ze sinn. Kuckt w.e.g. no ob beim Kopéiere kee Feeler geschitt ass.",
        "specialloguserlabel": "Aktive Benotzer:",
        "log-description-pagelang": "Dëst ass a Log mat den Ännerunge vun de Sprooche vun de Säiten.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (aktivéiert)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''desaktivéiert''')",
+       "mediastatistics-table-extensions": "Méiglech Erweiderungen",
        "mediastatistics-table-count": "Zuel vun de Fichieren",
        "mediastatistics-header-unknown": "Onbekannt",
        "mediastatistics-header-audio": "Audio",
index 5cb2908..7f08066 100644 (file)
        "booksources": "سرچشمه يل كتاو",
        "booksources-search-legend": "پی جوری سی سرچشمه یا کتاو",
        "booksources-isbn": "آی اس بی ان:",
-       "booksources-go": "رو",
        "booksources-invalid-isbn": "شازک که دئه بیه معتور نئ؛ وارسی خطایا د گات ؤرداشتن د سرچشمه اولی وه کار گرته بوئه.",
        "specialloguserlabel": "انجومکار:",
        "speciallogtitlelabel": "حاستنی(موضوع یا کاریار):",
        "protect-expiring": "گات تموم بیین $1 (یو تی سی)",
        "protect-expiring-local": "گات تموم بیین $1",
        "protect-expiry-indefinite": "بی زمون",
+       "protect-cascade": "پر و پیم بیین تافنمایی- همه بلگه یایی که هان د ای بلگه پر و پیم بوئن.",
        "protect-othertime": "وخت هنی:",
        "protect-othertime-op": "گات هنی",
        "protect-existing-expiry": "گات تموم بیین ایسنی: $2، $3",
        "viewdeletedpage": "دیئن بلگه یا پاکسا بیه",
        "undelete-fieldset-title": "د نو زنه کردن وانئریا",
        "undeleterevisions": "$1 نسقه مال دیاری{{PLURAL:$1|بیه|بینه}}",
+       "undelete-revision": "نسقه پاکسا بیه $1 (د ویرگار$4 ساعت $5) وه دس $3:",
        "undelete-nodiff": "وانئری دماتری پیدا نبیه.",
        "undeletebtn": "د نو زنه کردن",
        "undeletelink": "بوين/دوواره آماده با",
        "undeleteinvert": "انتخاو برعسك بوئه",
        "undeletecomment": "دليل:",
        "undeletedrevisions": "وانئری$1 د نو زنه{{PLURAL:$1|بی}}",
+       "undeletedrevisions-files": "{{PLURAL:$1|1 وانئری|$1 وانئریا}} و{{PLURAL:$2|1 جانیا|$2 جانیا}} د نو زئنه بینه.",
        "undeletedfiles": "{{PLURAL:$1|1 جانیا|$1 جانیایا}} د نو زنه بیه",
        "cannotundelete": "زنه کردن انجوم نبی:$1",
        "undelete-search-title": "بلگه یا پاکسا بیه نه پی جوری کو",
        "undelete-search-box": "پی جوری بلگه یا پاکسا بیه",
        "undelete-search-prefix": "بلگه یایی که وا شرو بیه نشو بیه:",
        "undelete-search-submit": "پی جوری",
+       "undelete-cleanup-error": "خطا د پاکسا کردن ویرگارچه وه کار نگرته بیه د«$1».",
        "undelete-error": "خطا بلگه ای که نبوئه پاکساش بکی",
        "undelete-error-short": "خطا پاک نبیئن جانیا:$1",
        "undelete-show-file-submit": "هری",
        "undelete-revision-row": "$1 $2 ($3) $4 . . $5 $6 $7 $8 $9",
        "namespace": "نوم جا:",
        "invert": "انتخاو برعسك بوئه",
+       "namespace_association": "نوم جایا یکاگرته",
        "blanknamespace": "اصلی",
        "contributions": "{{جنس:$1|کارور}} هومیاریا",
        "contributions-title": "هومياري كارور سي $1",
        "mycontris": "هومياری",
        "contribsub2": "سي {{جنسيت:$3|$1}} ($2)",
+       "contributions-userdoesnotexist": "کاریار \"$1\" ثوت نام نکرده.",
        "uctop": "(تازه باو)",
        "month": "د ما(یا زیتر)",
        "year": "د سال",
index b5245a6..e656ef8 100644 (file)
        "querypage-disabled": "Šī īpašā lapā ir atspējota veiktspējas iemeslu dēļ.",
        "booksources": "Grāmatu avoti",
        "booksources-search-legend": "Meklēt grāmatu avotus",
-       "booksources-go": "Meklēt",
        "specialloguserlabel": "Izpildītājs:",
        "speciallogtitlelabel": "Mērķis (nosaukums vai lietotājs):",
        "log": "Reģistri",
index 53d261c..6c69a45 100644 (file)
        "querypage-disabled": "Tsy ampiasaina ity pejy manokana ity mba hitsitsy ny solosaina",
        "booksources": "boky tsiahy",
        "booksources-search-legend": "hikaroka anatin'ny boky todika",
-       "booksources-go": "Ataovy lisitra",
        "booksources-text": "Ity misy lisitra maneho ny rohy makany amin'ny sehatra mivarotra boky vaovao sy efa vaky ary mety ahitanao fampahalalàna momba ny boky sy soratra notadiavinao :",
        "booksources-invalid-isbn": "Ny ISBN nomena dia mety diso ; marino raha diso ianao teo am-pandikanana ny loharano fotony.",
        "specialloguserlabel": "Mpikambana nanao :",
index 0677569..11bb9a5 100644 (file)
        "create": "Создај",
        "create-local": "Додај локален опис",
        "editthispage": "Уреди ја страницава",
-       "create-this-page": "Создај ја оваа страница",
+       "create-this-page": "Создај ја страницава",
        "delete": "Избриши",
-       "deletethispage": "Избриши ја оваа страница",
-       "undeletethispage": "обнови ја оваа страница",
+       "deletethispage": "Избриши ја страницава",
+       "undeletethispage": "обнови ја страницава",
        "undelete_short": "Врати {{PLURAL:$1|едно уредување|$1 уредувања}}",
        "viewdeleted_short": "Преглед на {{PLURAL:$1|едно избришано уредување|$1 избришани уредувања}}",
        "protect": "Заштити",
        "protect_change": "промена",
-       "protectthispage": "Заштити ја оваа страница",
+       "protectthispage": "Заштити ја страницава",
        "unprotect": "Измени заштита",
        "unprotectthispage": "Измена на заштитата на страницава",
        "newpage": "Нова страница",
        "action-deleterevision": "избриши ја ревизијава",
        "action-deletedhistory": "прегледај ја историјата на бришења за оваа страница",
        "action-browsearchive": "барање на избришани страници",
-       "action-undelete": "обнови ја оваа страница",
+       "action-undelete": "обнови ја страницава",
        "action-suppressrevision": "прегледај ја и обнови ја оваа скриена преработка",
        "action-suppressionlog": "преглед на овој li;en дневник",
        "action-block": "оневозможи го овој корисник да уредува",
        "destfilename": "Целно име на податотеката:",
        "upload-maxfilesize": "Максимална големина на податотеката: $1",
        "upload-description": "Опис на податотека",
-       "upload-options": "Ð\9dагодÑ\83ваÑ\9aа Ð·Ð° Ð¿Ð¾Ð´Ð¸Ð³Ð°Ñ\9aе",
+       "upload-options": "Ð\9dагодÑ\83ваÑ\9aа Ð½Ð° Ð¿Ð¾Ð´Ð¸Ð³Ð°Ñ\9aеÑ\82о",
        "watchthisupload": "Набљудувај ја податотекава",
        "filewasdeleted": "Податотека со ова име претходно била подигната и потоа избришана.\nПроверете во $1 пред да продолжите со повтроно подигање.",
        "filename-bad-prefix": "Името на податотеката која ја подигате започнува со '''„$1“''', типично за неописните називи кои дигиталните фотоапарати автоматски ги создаваат, што впрочем е недоволно описно.\nВе молиме одберете подобро описно име за вашата податотека.",
        "license": "Лиценцирање:",
        "license-header": "Лиценцирање",
        "nolicense": "Нема",
-       "licenses-edit": "Ð\98змени Ð»Ð¸Ñ\86енÑ\86ни можности",
+       "licenses-edit": "Ð\98змени Ð³Ð¸ Ð»Ð¸Ñ\86енÑ\86ниÑ\82е можности",
        "license-nopreview": "(Прегледот не е достапен)",
        "upload_source_url": "(податотеката што сте ја одбрале од важечка, јавно достапна URL-адреса)",
        "upload_source_file": "(податотеката што ја одбирате од вашиот сметач)",
        "newpages-username": "Корисничко име:",
        "ancientpages": "Најстари статии",
        "move": "Премести",
-       "movethispage": "Премести ја оваа страница",
+       "movethispage": "Премести ја страницава",
        "unusedimagestext": "Следниве податотеки постојат, но не се вметнати во ниедна страница.\nИмајте предвид дека други мрежни места може да ставаат врски до неа со директна URL-адреса, и затоа може да е наведена овде и покрај тоа што е во активна употреба.",
        "unusedcategoriestext": "Следните категории постојат и покрај тоа што ниедна статија и категорија не ги користи.",
        "notargettitle": "Нема цел",
        "booksources": "Печатени извори",
        "booksources-search-legend": "Пребарување на извори за книга",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Најди",
+       "booksources-search": "Пребарај",
        "booksources-text": "Ова е список на врски кон други мрежни места кои продаваат нови и користени книги, и тие може\nда имаат повеќе информации за книгите што ги баравте:",
        "booksources-invalid-isbn": "Наведениот ISBN се чини неправилен. Проверете да не настанала некоја грешка при копирањето од изворот.",
        "specialloguserlabel": "Изведувач:",
        "tooltip-ca-addsection": "Започни нов пасус",
        "tooltip-ca-viewsource": "Оваа страница е заштитена. Можете да го видите изворниот код.",
        "tooltip-ca-history": "Претходни верзии на оваа страница.",
-       "tooltip-ca-protect": "Ð\97аÑ\88Ñ\82иÑ\82еÑ\82е Ñ\98а Ð¾Ð²Ð°Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а",
+       "tooltip-ca-protect": "Ð\97аÑ\88Ñ\82иÑ\82и Ñ\98а Ñ\81Ñ\82Ñ\80аниÑ\86ава",
        "tooltip-ca-unprotect": "Измени заштита страницава",
-       "tooltip-ca-delete": "Избриши ја оваа страница",
+       "tooltip-ca-delete": "Избриши ја страницава",
        "tooltip-ca-undelete": "Обнови ги уредувањата направени на оваа страница пред да биде избришана",
-       "tooltip-ca-move": "Премести ја оваа страница",
+       "tooltip-ca-move": "Премести ја страницава",
        "tooltip-ca-watch": "Додај ја страницава во списокот на набљудувања",
        "tooltip-ca-unwatch": "Отстрани ја страницава од списокот на набљудувања",
        "tooltip-search": "Пребарај низ {{SITENAME}}",
        "tooltip-t-emailuser": "Испрати е-пошта на овој корисник",
        "tooltip-t-upload": "Подигни податотеки",
        "tooltip-t-specialpages": "Список на сите службени страници",
-       "tooltip-t-print": "Ð\92еÑ\80зиÑ\98а Ð·Ð° Ð¿ÐµÑ\87аÑ\82еÑ\9aе Ð½Ð° Ð¾Ð²Ð°Ð° Ñ\81Ñ\82Ñ\80аниÑ\86а",
+       "tooltip-t-print": "Ð\92еÑ\80зиÑ\98а Ð½Ð° Ñ\81Ñ\82Ñ\80аниÑ\86ава Ð½Ð°Ð¼ÐµÐ½ÐµÑ\82а Ð·Ð° Ð¿ÐµÑ\87аÑ\82еÑ\9aе",
        "tooltip-t-permalink": "Постојана врска до оваа верзија на страницата",
        "tooltip-ca-nstab-main": "Преглед на содржината",
        "tooltip-ca-nstab-user": "Преглед на корисничката страница",
index 2011179..f462799 100644 (file)
        "booksources": "പുസ്തക സ്രോതസ്സുകൾ",
        "booksources-search-legend": "പുസ്തകസ്രോതസ്സുകൾക്കായി തിരയുക",
        "booksources-isbn": "ഐ.എസ്.ബി.എൻ.:",
-       "booksources-go": "പോകൂ",
        "booksources-text": "പുതിയതും ഉപയോഗിച്ചതുമായ പുസ്തകങ്ങൾ വിൽക്കുന്ന സൈറ്റുകളിലേക്കുള്ള ലിങ്കുകളുടെ പട്ടിക ആണ്‌ താഴെ. താങ്കൾ തിരയുന്ന പുസ്തകത്തെ പറ്റിയുള്ള കൂടുതൽ വിവരങ്ങൾ ഈ പട്ടികയിൽ നിന്നു ലഭിച്ചേക്കാം:",
        "booksources-invalid-isbn": "തന്നിരിക്കുന്ന ഐ.എസ്.ബി.എൻ. സാധുവാണെന്നു തോന്നുന്നില്ല; യഥാർത്ഥ സ്രോതസ്സിൽ നിന്നും പകർത്തിയപ്പോൾ തെറ്റുപറ്റിയോ എന്നു പരിശോധിക്കുക",
        "specialloguserlabel": "നടപ്പിലാക്കിയയാൾ:",
index b830940..0e5b01e 100644 (file)
        "querypage-disabled": "Laman khas ini dilumpuhkan atas sebab-sebab prestasi.",
        "booksources": "Sumber buku",
        "booksources-search-legend": "Cari sumber buku",
-       "booksources-go": "Pergi",
        "booksources-text": "Yang berikut ialah senarai pautan ke tapak web lain yang menjual buku baru dan terpakai,\nserta mungkin mempunyai maklumat lanjut mengenai buku yang anda cari:",
        "booksources-invalid-isbn": "ISBN yang dinyatakan tidak sah. Sila semak sekali lagi.",
        "specialloguserlabel": "Pelaku:",
index 8a5d26e..4f61f4e 100644 (file)
        "booksources": "Sorsi tal-kotba",
        "booksources-search-legend": "Fittex għal sorsi tal-kotba",
        "booksources-isbn": "Kodiċi ISBN:",
-       "booksources-go": "Mur",
        "booksources-text": "Hawn taħt hawn lista ta' ħoloq għal siti oħrajn li jbiegħu kotba ġodda u wżati, u jistgħu jkollhom aktar informazzjoni dwar il-kotba li qiegħed tfittex:",
        "booksources-invalid-isbn": "L-ISBN li ngħata jidher li mhuwiex validu; iċċekkja għal xi żbalji mis-sors oriġinali.",
        "specialloguserlabel": "Azzjoni effettwata minn:",
index 4a7ad95..9e320dd 100644 (file)
        "querypage-disabled": "Sta paggena speciale è stutata pe' mutive 'e prestaziune.",
        "booksources": "Funte libbrarie",
        "booksources-search-legend": "Ascìa 'e fonte ncopp' 'e libbre",
-       "booksources-go": "Vàje",
        "booksources-text": "Ccà abbascio ce sta na lista 'e cullegamiente a l'ati site ca venneno libbre nuove e viecchie, ca putessero pure avé cchiù nfurmaziune ncopp' 'e libbre ca jate ascianno:",
        "booksources-invalid-isbn": "L'ISBN c'avete miso nun pare bbuono; cuntrolla si ce sta cocch'errore quanno stavate cupianno stu nummero d' 'a fonte origginale.",
        "specialloguserlabel": "Mplementatore:",
        "exif-ycbcrpositioning": "Mpizzamento d' Y e C",
        "exif-xresolution": "Resoluzione orizzontale",
        "exif-yresolution": "Resoluzione verticale",
+       "exif-stripoffsets": "Pizzo addò sta l'immaggine",
+       "exif-rowsperstrip": "Nummero 'e righe pe' striscia",
+       "exif-stripbytecounts": "Byte pe' striscia compressa",
+       "exif-jpeginterchangeformat": "Distanza 'a SOI JPEG",
+       "exif-jpeginterchangeformatlength": "Byte 'e date JPEG",
+       "exif-whitepoint": "Cromaticetà d' 'o punto janco",
+       "exif-primarychromaticities": "Cromaticetà d' 'e culore primmarie",
+       "exif-ycbcrcoefficients": "Coefficiente d' 'a matrice 'e trasformazione d' 'o spazio 'e culore",
+       "exif-referenceblackwhite": "Paro 'e riferimento 'e valore janche e nire",
+       "exif-datetime": "Data e ora 'e cagnamiento d' 'o file",
+       "exif-imagedescription": "Titulo 'e l'immaggene",
+       "exif-make": "Frabbeca ca muntaje 'a camera",
+       "exif-model": "Mudello d' 'a camera",
+       "exif-software": "Software ausàto",
+       "exif-artist": "Autore",
+       "exif-copyright": "Titolare d' 'o Copyright",
+       "exif-exifversion": "Verzione d'Exif",
+       "exif-flashpixversion": "Verziona Flashpix suppurtata",
+       "exif-colorspace": "Spazio d' 'e culore",
+       "exif-componentsconfiguration": "Significato d'ogne componente",
+       "exif-compressedbitsperpixel": "Modo 'e compressione 'e l'immaggene",
+       "exif-pixelydimension": "Larghezza 'e l'immaggene",
+       "exif-pixelxdimension": "Autezza 'e l'immaggene",
+       "exif-usercomment": "Note 'e ll'utente",
+       "exif-relatedsoundfile": "File audio cullegato",
+       "exif-datetimeoriginal": "Data e ora d' 'a criazione d' 'e date",
+       "exif-datetimedigitized": "Data e ora 'e digitalizzazziona",
+       "exif-subsectime": "DateTime centeseme",
+       "exif-subsectimeoriginal": "DateTimeOriginal centeseme",
+       "exif-subsectimedigitized": "DateTimeDigitized centeseme",
+       "exif-exposuretime": "Tiempo d'esposizione",
+       "exif-exposuretime-format": "$1 sec ($2)",
+       "exif-fnumber": "Nummero p' 'o F",
+       "exif-exposureprogram": "Prugramma d'esposizione",
+       "exif-spectralsensitivity": "Senzitività spettrale",
+       "exif-isospeedratings": "Senzibbiletà ISO",
+       "exif-shutterspeedvalue": "Velocità d' 'o nchiuretore APEX",
+       "exif-aperturevalue": "Apertura APEX",
+       "exif-brightnessvalue": "Lumenosetà APEX",
+       "exif-exposurebiasvalue": "Correzzione d'esposizione APEX",
+       "exif-maxaperturevalue": "Apiertura massima",
+       "exif-subjectdistance": "Distanza d' 'o soggetto",
+       "exif-meteringmode": "Metodo 'e mmisura",
+       "exif-lightsource": "Sorgente 'e luce",
+       "exif-flash": "Flash",
+       "exif-focallength": "Distanza focale d' 'a lente",
+       "exif-subjectarea": "Area d' 'o soggetto",
+       "exif-flashenergy": "Putenza d' 'o flash",
+       "exif-focalplanexresolution": "Resoluzione X ncopp' 'o piano focale",
+       "exif-focalplaneyresolution": "Resoluzione Y ncopp' 'o piano focale",
+       "exif-focalplaneresolutionunit": "Unità 'e resoluzione d' 'o piano focale",
+       "exif-subjectlocation": "Pizzo addò stà 'o soggetto",
+       "exif-exposureindex": "Innece d'esposizione",
+       "exif-sensingmethod": "Sistema 'e rilevazione",
+       "exif-filesource": "Origgene d' 'o file",
+       "exif-scenetype": "Tipo 'e scena",
+       "exif-customrendered": "Prucesso d' 'a immaggene",
+       "exif-exposuremode": "Modo d'esposizione",
+       "exif-whitebalance": "Valanza 'e janco",
+       "exif-digitalzoomratio": "Rapporto zoom diggitale",
+       "exif-focallengthin35mmfilm": "Focale eguale a 35 mm",
+       "exif-scenecapturetype": "Tipo d'acquisizziona",
+       "exif-gaincontrol": "Cuntrollo d' 'a scena",
+       "exif-contrast": "Contrasto",
+       "exif-saturation": "Saturazione",
+       "exif-sharpness": "Nitidezza",
+       "exif-devicesettingdescription": "Descrizione d' 'e mpustaziune d' 'o dispositivo",
+       "exif-subjectdistancerange": "Scala distanza soggetto",
+       "exif-imageuniqueid": "ID 'e l'immaggine univoco",
+       "exif-gpsversionid": "Verzione d' 'e tag GPS",
+       "exif-gpslatituderef": "Latitudine nord o sud",
+       "exif-gpslatitude": "Latitudine",
+       "exif-gpslongituderef": "Longitudine est o ovest",
+       "exif-gpslongitude": "Longitudine",
+       "exif-gpsaltituderef": "Riferimento pe' l'autezza",
+       "exif-gpsaltitude": "Autezza",
+       "exif-gpstimestamp": "orario d' 'o GPS (rilorgio atomico)",
        "exif-xyresolution-i": "$1 punte pe pollice (dpi)",
        "exif-meteringmode-0": "Scanusciuto",
        "exif-meteringmode-255": "Ato",
index 80dca86..3cf25d4 100644 (file)
        "passwordreset-emailsent": "पासवर्ड परिवर्तनको लागि इमेल पठाइएको छ।",
        "passwordreset-emailsent-capture": "पासवर्ड परिवर्तनको लागि इमेल पठाइयो, जुन तल देखाइएकोछ।",
        "changeemail": "इमेल ठेगाना परिवर्तन गर्नुहोस",
-       "changeemail-header": "खाताको इमेल ठेगाना परिवर्तन गर्नुहोस",
        "changeemail-text": "आफ्नो इमेल ठेगाना परिवर्तन गर्न यो फारम भर्नुहोस। यसलाई पुष्टि गर्न तपाईले आफ्नो पासवर्ड हाल्नु पर्नेछ।",
        "changeemail-no-info": "यस पृष्ठमा सिधै जानको लागि प्रवेश गर्नु पर्ने हुन्छ ।",
        "changeemail-oldemail": "हालको इमेल-ठेगाना:",
        "changeemail-newemail": "नयाँ इमेल-ठेगाना:",
        "changeemail-none": "(कुनै पनि हैन)",
        "changeemail-submit": "इमेल परिवर्तन गर्ने",
-       "changeemail-cancel": "रद्द गर्ने",
        "resettokens": "टोकन पूर्वरुपमा फर्काउने",
        "resettokens-no-tokens": "पूर्वरुपमा फर्काउन कुनै पनि टोकन छैन ।",
        "resettokens-legend": "टोकनहरू पूर्वरुपमा फर्काउने",
        "searchrelated": "सम्बन्धित",
        "searchall": "सबै",
        "showingresults": "देखाउँदै  {{PLURAL:$1|'''१''' नतिजा|'''$1''' नतिजाहरू }} , #'''$2''' बाट सुरुहुने ।",
-       "showingresultsheader": "{{PLURAL:$5|नतिजा '''$1''' को '''$3'''|नतिजाहरु '''$1 - $2''' को'''$3'''}}  ,'''$4''' को लागि",
        "search-nonefound": "तपाईँको क्वेरीसँग मेल खाने नतिजाहरू भेटिएनन्",
        "powersearch-legend": "उन्नत खोज",
        "powersearch-ns": "नेमस्पेसेजहरुमा खोज्ने :",
        "unusedtemplateswlh": "अन्य कड़ीहरु",
        "randompage": "कुनै एक लेख",
        "randompage-nopages": "{{PLURAL:$2| $1 नाम भएको कुनै पृष्ट छैन|$1 नाम भएका कुनै पृष्टहरु छैनन्}}",
-       "randomincategory-selectcategory-submit": "जाने",
        "randomredirect": "कुनै एउटा अनुप्रेषितमा जाने",
        "randomredirect-nopages": "\"$1\" नामस्थानमा अनुप्रेषित छैन।",
        "statistics": "तथ्यांक",
        "suppress": "अतिदृष्टि",
        "booksources": "किताबका श्रोतहरु",
        "booksources-search-legend": "किताबका श्रोतहरु खोज्ने",
-       "booksources-go": "जाउ",
        "specialloguserlabel": "निष्पादक:",
        "speciallogtitlelabel": "लक्ष्य (शीर्षक वा प्रयोगकर्ता)",
        "log": "लगहरु",
        "thumbnail_image-missing": "फाइल हराएको भान भइरहेछ: $1",
        "import": "पृष्ठहरू आयात गर्नुहोस्",
        "importinterwiki": "Transwiki आयात",
-       "import-interwiki-source": "स्रोत विकि/ पृष्ठ :",
        "import-interwiki-history": "यो पृष्ठकोलागि सबै इतिहास संशोधनहरु प्रतिलिपि गर्ने",
        "import-interwiki-templates": "सबै टेम्प्लेटहरु(नमुना) समेट्ने",
        "import-interwiki-submit": "आयात",
        "revdelete-unrestricted": "प्रवन्धककोलागि निषेधहरु हटाइयो ।",
        "logentry-move-move": "$1 द्वारा $3 पृष्ठलाई $4 मा सारियो",
        "rightsnone": "(कुनैपनि होइन)",
+       "revdelete-summary": "सम्पादन सारांश",
        "feedback-subject": "विषय:",
        "feedback-message": "सन्देश:",
        "feedback-cancel": "रद्द गर्ने",
index 8ab7be7..230e7c0 100644 (file)
        "querypage-disabled": "Deze speciale pagina is uitgeschakeld om performanceredenen.",
        "booksources": "Boekinformatie",
        "booksources-search-legend": "Bronnen en gegevens over een boek zoeken",
-       "booksources-go": "OK",
        "booksources-text": "Hieronder staat een lijst met koppelingen naar andere websites die nieuwe of gebruikte boeken verkopen, en die wellicht meer informatie over het boek dat u zoekt hebben:",
        "booksources-invalid-isbn": "Het opgegeven ISBN lijkt niet geldig te zijn.\nControleer of u wellicht een fout hebt gemaakt bij de invoer.",
        "specialloguserlabel": "Uitvoerende gebruiker:",
index 962ad53..536c37e 100644 (file)
        "querypage-disabled": "Ta strona specjalna została wyłączona ze względu na ograniczenia wydajności.",
        "booksources": "Książki",
        "booksources-search-legend": "Szukaj informacji o książkach",
-       "booksources-go": "Pokaż",
        "booksources-text": "Poniżej znajduje się lista odnośników do innych witryn, które pośredniczą w sprzedaży nowych i używanych książek, a także mogą posiadać dalsze informacje na temat poszukiwanej przez Ciebie książki.",
        "booksources-invalid-isbn": "Podany numer ISBN został rozpoznany jako nieprawidłowy. Sprawdź czy podany numer zgadza się z numerem zaczerpniętym ze źródła.",
        "specialloguserlabel": "Kto",
index 88e6b4b..51bbf46 100644 (file)
        "querypage-disabled": "Sta pàgina special a l'é disabilità për dle rason ëd prestassion.",
        "booksources": "Andoa trové dij lìber",
        "booksources-search-legend": "Sërché antra ij lìber d'arferiment",
-       "booksources-go": "Andé",
        "booksources-text": "Ambelessì sota a-i é na lista d'àotri sit che a vendo dij lìber neuv e dë sconda man, e che a peulo ëdcò smon-e dj'anformassion rësgoard ai test che a l'é antramentr che a sërca:",
        "booksources-invalid-isbn": "L'ISBN dàit a smija che a sia pa vàlid; ch'a contròla s'a-i é n'eror an copiand da la sorgiss original.",
        "specialloguserlabel": "Esecutor:",
index a8cb673..01ad2a0 100644 (file)
        "suppress": "څارن",
        "booksources": "د کتاب سرچينې",
        "booksources-search-legend": "د کتابي سرچينو پلټنه",
-       "booksources-go": "ورځه",
        "booksources-text": "دا لاندې د هغه وېبځايونو د تړنو لړليک دی چېرته چې نوي او زاړه کتابونه پلورل کېږي، او يا هم کېدای شي چې د هغه کتاب په هکله مالومات ولري کوم چې تاسو ورپسې لټېږۍ:",
        "specialloguserlabel": "ترسره کوونکی:",
        "speciallogtitlelabel": "موخه (سرليک يا کارن):",
index 58c555e..3a9a972 100644 (file)
        "querypage-disabled": "Esta página especial está desativada para não prejudicar o desempenho.",
        "booksources": "Fontes bibliográficas",
        "booksources-search-legend": "Pesquisar referências bibliográficas",
-       "booksources-go": "Ir",
        "booksources-text": "É exibida a seguir uma listagem de links para outros sites que vendem livros novos e usados e que possam possuir informações adicionais sobre os livros que você está pesquisando:",
        "booksources-invalid-isbn": "O número ISBN fornecido não parece ser válido; verifique se houve erros ao copiar da fonte original.",
        "specialloguserlabel": "Executor:",
index 9cec0e8..e9a9476 100644 (file)
        "querypage-disabled": "Esta página especial está desativada para não prejudicar o desempenho.",
        "booksources": "Fontes bibliográficas",
        "booksources-search-legend": "Pesquisar referências bibliográficas",
-       "booksources-go": "Ir",
+       "booksources-search": "Pesquisar",
        "booksources-text": "É apresentada abaixo uma lista de ligações para outros sítios na Internet que vendem livros novos e usados e talvez possuam informações adicionais sobre os livros que procura:",
        "booksources-invalid-isbn": "O número ISBN fornecido não parece ser válido; verifique a existência de erros ao copiar da fonte original.",
        "specialloguserlabel": "Executante:",
index 941bb91..d480e2d 100644 (file)
        "blocked-mailpassword": "Used as error message in password recovery.",
        "eauthentsent": "This message appears after entering an email address in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}, then clicking on \"{{int:saveprefs}}\".",
        "throttled-mailpassword": "Used in [[Special:PasswordReset]]. Parameters:\n* $1 - password reset email resend time (in hours)",
-       "loginstart": "{{notranslate}}",
-       "loginend": "{{notranslate}}",
-       "loginend-https": "{{notranslate}}",
-       "signupstart": "{{notranslate}}\nDefault:\n* {{msg-mw|Loginstart}}",
-       "signupend": "{{notranslate}}\nDefault:\n* {{msg-mw|Loginend}}",
+       "signupstart": "{{notranslate}}",
+       "signupend": "{{notranslate}}",
        "signupend-https": "{{notranslate}}",
        "mailerror": "Used as error message in sending confirmation mail to user. Parameters:\n* $1 - new mail address",
        "acct_creation_throttle_hit": "Error message at [[Special:CreateAccount]].\n\n\"in the last day\" precisely means: during the lasts 86400 seconds (24 hours) ending right now.\n\nParameters:\n* $1 - number of accounts",
        "booksources-summary": "{{doc-specialpagesummary|booksources}}",
        "booksources-search-legend": "Box heading on [[Special:BookSources|book sources]] special page. The box is for searching for places where a particular book can be bought or viewed.",
        "booksources-isbn": "{{optional}}\nThis is a label that appears before a text input field on the Special:BookSources page.\n{{Identical|ISBN}}",
-       "booksources-go": "Name of button in [[Special:BookSources]]\n\n{{Identical|Go}}",
+       "booksources-search": "Search button in [[Special:BookSources]]\n\n{{Identical|Go}}",
        "booksources-text": "Used in [[Special:BookSources/1]].\n\nThis message is followed by a list of links to other sites.\n\nSee also:\n* {{msg-mw|Booksources|title}}\n* {{msg-mw|Booksources-text|text}}",
        "booksources-invalid-isbn": "This message is displayed after an invalid ISBN is entered on [[Special:Booksources]].",
        "rfcurl": "{{notranslate}}\nParameters:\n* $1 - RFC number\nSee also:\n* {{msg-mw|Pubmedurl}}",
index ff3a457..e6a3cd5 100644 (file)
        "querypage-disabled": "Această pagină specială este dezactivată din motive de performanță.",
        "booksources": "Surse de cărți",
        "booksources-search-legend": "Căutare surse pentru cărți",
-       "booksources-go": "Salt",
+       "booksources-search": "Caută",
        "booksources-text": "Mai jos se află o listă de legături înspre alte situri care vând cărți noi sau vechi și care pot oferi informații suplimentare despre cărțile pe care le căutați:",
        "booksources-invalid-isbn": "Codul ISBN oferit nu este valid; verificați dacă a fost copiat corect de la sursa originală.",
        "specialloguserlabel": "Executant:",
index 04db67b..1913460 100644 (file)
        "booksources": "Источники книг",
        "booksources-search-legend": "Поиск информации о книге",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Найти",
        "booksources-text": "На этой странице приведён список ссылок на сайты, где вы, возможно, найдёте дополнительную информацию о книге. Это интернет-магазины и системы поиска в библиотечных каталогах.",
        "booksources-invalid-isbn": "Указанный номер ISBN, судя по всему, содержит ошибку. Пожалуйста, проверьте, что при переносе номера из первоисточника не возникло искажений.",
        "specialloguserlabel": "Исполнитель:",
index 294cb91..6ec90a2 100644 (file)
        "booksources": "Fontes libràrias",
        "booksources-search-legend": "Chirca fontes libràrias",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Bae",
        "specialloguserlabel": "Atzione fata dae:",
        "speciallogtitlelabel": "Atzione fata subra:",
        "log": "Registros",
index 7edaae6..19e84c9 100644 (file)
        "prefs-tokenwatchlist": "Žeton",
        "prefs-diffs": "Primerjave",
        "prefs-help-prefershttps": "Nastavitev bo začela veljati ob vaši naslednji prijavi.",
+       "prefswarning-warning": "V svojih nastavitvah ste naredili spremembe, ki jih še niste shranili. Če odidete s strani brez da bi kliknili »$1«, vaših nastavitev ne bomo posodobili.",
        "prefs-tabs-navigation-hint": "Namig: Za krmarjenje med zavihki na seznamu zavihkov lahko uporabite levo in desno smerno tipko.",
        "email-address-validity-valid": "E-poštni naslov je videti veljaven",
        "email-address-validity-invalid": "Vnesite veljaven e-poštni naslov",
        "querypage-disabled": "Ta posebna stran je onemogočena iz zmogljivostnih razlogov.",
        "booksources": "Viri knjig",
        "booksources-search-legend": "Išči knjižne vire",
-       "booksources-go": "Pojdi",
+       "booksources-search": "Išči",
        "booksources-text": "Sledi seznam povezav do drugi spletnih strani, ki prodajajo nove in rabljene knjige, in imajo morda nadaljnje informacije o knjigah, ki jih iščete:",
        "booksources-invalid-isbn": "Za dani ISBN se ne zdi, da je veljaven; preverite za morebitne napake pri kopiranju iz prvotnega vira.",
        "specialloguserlabel": "Izvajalec:",
        "default-skin-not-found": "Ups! Privzeta koža vašega wikija, določena v <code dir=\"ltr\">$wgDefaultSkin</code> kot <code>$1</code>, ni na voljo.\n\nKot kaže, vaša namestitev vsebuje kože, navedene spodaj. Oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priročnik: Konfiguracija kož] za več informacij, kako jih omogočiti in nastaviti kot privzete.\n\n$2\n\n; Če ste MediaWiki pravkar namestili:\n: Verjetno ste ga namestili z git ali neposredno iz izvorne kode na kakšen drug način. To je pričakovano. Poskusite namestiti nekaj kož z [https://www.mediawiki.org/wiki/Category:All_skins imenika kož mediawiki.org] tako:\n:* Prenesite [https://www.mediawiki.org/wiki/Download namestitveni program tarball], ki vsebuje nekaj kož in razširitev. Iz njega lahko kopirate in prilepite mapo <code>skins/</code>.\n:* Klonirajte enega od repozitorijev <code>mediawiki/skins/*</code> z git v mapo <code dir=\"ltr\">skins/</code> vaše namestitve MediaWiki.\n: Če ste razvijalec MediaWiki, to ne sme poseči v vaš repozitorij git.\n\n; Če ste MediaWiki pravkar posodobili:\n: MediaWiki 1.24 in novejši nameščenih kož več ne omogočijo samodejno (oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Priročnik: Samodejno odkrivanje kož]). V <code>LocalSettings.php</code> lahko prilepite naslednje vrstice, da omogočite trenutno nameščene kože:\n\n<pre dir=\"ltr\">$3</pre>\n\n; Če ste pravkar spremenili <code>LocalSettings.php</code>:\n: Ponovno preverite imena kož, če ste se morda zatipkali.",
        "default-skin-not-found-no-skins": "Ups! Privzeta koža vašega wikija, določena v <code dir=\"ltr\">$wgDefaultSkin</code> kot <code>$1</code>, ni na voljo.\n\nNimate nameščenih kož.\n\n; Če ste MediaWiki pravkar namestili ali posodobili:\n: Verjetno ste ga namestili z git ali neposredno iz izvorne kode na kakšen drug način. To je pričakovano. MediaWiki 1.24 in novejši nimajo vključene nobene kože v glavnem repozitoriju. Poskusite namestiti nekaj kož z [https://www.mediawiki.org/wiki/Category:All_skins imenika kož mediawiki.org] tako:\n:* Prenesite [https://www.mediawiki.org/wiki/Download namestitveni program tarball], ki vsebuje nekaj kož in razširitev. Iz njega lahko kopirate in prilepite mapo <code dir=\"ltr\">skins/</code>.\n:* Klonirajte enega od repozitorijev <code>mediawiki/skins/*</code> z git v mapo <code>skins/</code> vaše namestitve MediaWiki.\n: Če ste razvijalec MediaWiki, to ne sme poseči v vaš repozitorij git. Oglejte si [https://www.mediawiki.org/wiki/Manual:Skin_configuration Priročnik: Konfiguracija kož] za več informacij, kako jih omogočiti in nastaviti kot privzete.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (omogočeno)",
-       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''onemogočeno''')"
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''onemogočeno''')",
+       "mediastatistics": "Statistika predstavnosti",
+       "mediastatistics-summary": "Statistika o naloženih vrstah datotek. To vključuje samo najnovejše različice datotek. Stare in izbrisane različice niso vključene.",
+       "mediastatistics-nbytes": "{{PLURAL:$1|$1 bajt|$1 bajta|$1 bajti|$1 bajtov}} ($2; $3 %)",
+       "mediastatistics-table-mimetype": "Vrsta MIME",
+       "mediastatistics-table-extensions": "Možne razširitve",
+       "mediastatistics-table-count": "Število datotek",
+       "mediastatistics-table-totalbytes": "Skupna velikost",
+       "mediastatistics-header-unknown": "Neznano",
+       "mediastatistics-header-bitmap": "Bitne slike",
+       "mediastatistics-header-drawing": "Risbe (vektorske slike)",
+       "mediastatistics-header-audio": "Zvok",
+       "mediastatistics-header-video": "Videoposnetki",
+       "mediastatistics-header-multimedia": "Obogatena predstavnost",
+       "mediastatistics-header-office": "Pisarna",
+       "mediastatistics-header-text": "Besedilno",
+       "mediastatistics-header-executable": "Izvedljive datoteke",
+       "mediastatistics-header-archive": "Stisnjene oblike"
 }
index 470a699..fe4c75d 100644 (file)
        "booksources": "Штампани извори",
        "booksources-search-legend": "Тражење извора књиге",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Иди",
        "booksources-text": "Испод се налази списак веза ка сајтовима који се баве продајом нових и половних књига, а који би могли имати додатне податке о књигама које тражите:",
        "booksources-invalid-isbn": "Наведени ISBN број није исправан. Проверите да није дошло до грешке при умножавању из првобитног извора.",
        "specialloguserlabel": "Извршилац:",
index 97f9137..5282f83 100644 (file)
        "booksources": "Štampani izvori",
        "booksources-search-legend": "Traženje izvora knjige",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Idi",
        "booksources-text": "Ispod se nalazi spisak veza ka sajtovima koji se bave prodajom novih i polovnih knjiga, a koji bi mogli imati dodatne podatke o knjigama koje tražite:",
        "booksources-invalid-isbn": "Navedeni ISBN broj nije ispravan. Proverite da nije došlo do greške pri umnožavanju iz prvobitnog izvora.",
        "specialloguserlabel": "Izvršilac:",
index 3d006ec..1ae4330 100644 (file)
@@ -18,7 +18,7 @@
        "tog-hidepatrolled": "Sumputkeun anu geus diroris ti béréndélan nu anyar robah",
        "tog-newpageshidepatrolled": "Sumputkeun nu geus diroris tina béréndélan kaca anyar",
        "tog-extendwatchlist": "Legaan béréndélan ngarah sakabéh parobahanana kaawaskeun",
-       "tog-usenewrc": "Parobahan grup dumasar kaca dina béréndélan anyar robah jeung awaskeuneun (maké JavaScript)",
+       "tog-usenewrc": "Parobahan grup dumasar kaca dina béréndélan anu anyar robah jeung awaskeuneun",
        "tog-numberheadings": "Nomeran lulugu sacara otomatis",
        "tog-showtoolbar": "Témbongkeun tulbar édit",
        "tog-editondblclick": "Édit kaca ku klik ganda",
@@ -27,6 +27,7 @@
        "tog-watchdefault": "Tambahkeun kaca jeung berkas anu diédit ku kuring kana awaskeuneun",
        "tog-watchmoves": "Tambahkeun kaca jeung berkas anu dipindahkeun ka awaskeuneun",
        "tog-watchdeletion": "Tambahkeun kaca jeung berkas anu dihapus kana awaskeuneun",
+       "tog-watchrollback": "Tambahkeun kaca anu jujutanana kungsi dibalikkeun kana awaskeuneun",
        "tog-minordefault": "Tandaan sadaya éditan salaku minor luyu jeung ti dituna",
        "tog-previewontop": "Témbongkeun sawangan méméh kotak édit (lain sanggeusna)",
        "tog-previewonfirst": "Témbongkeun sawangan dina éditan munggaran",
@@ -53,7 +54,7 @@
        "tog-prefershttps": "Salawasna paké sambungan aman nalika asup log",
        "underline-always": "Salawasna",
        "underline-never": "Ulah",
-       "underline-default": "Luyu jeung buhunna panyungsi",
+       "underline-default": "Buhunna kulit atawa panyungsi",
        "editfont-style": "Gaya aksara dina kotak éditan:",
        "editfont-default": "Luyu jeung buhunna panyungsi",
        "editfont-monospace": "Aksara monospasi",
        "jumptonavigation": "pituduh",
        "jumptosearch": "sungsi",
        "view-pool-error": "Punten, serverna keur pinuh.\nLoba teuing nu nyoba muka ieu kaca.\nMangga cobian sanés waktos.\n\n$1",
+       "generic-pool-error": "Hampura, serverna keur pinuh.\nLoba teuing nu nyoba muka ieu sumberdaya.\nAntosan sakedap, engké cobaan deui.",
        "pool-timeout": "Béakeun waktu nungguan konci",
        "pool-queuefull": "Antrian geus pinuh",
        "pool-errorunknown": "Éror teu dipikawanoh",
+       "pool-servererror": "Palayanan ''pool counter'' teu disadiakeun ($1).",
        "aboutsite": "Ngeunaan {{SITENAME}}",
        "aboutpage": "Project:Ngeunaan",
-       "copyright": "Sadaya kandungan ieu loka ditangtayungan ku $1",
+       "copyright": "Eusina ditangtayungan ku $1 iwal lamun disebutkeun béda.",
        "copyrightpage": "{{ns:project}}:Hak cipta",
        "currentevents": "Keur lumangsung",
        "currentevents-url": "Project:Keur lumangsung",
        "filereadonlyerror": "Berkas \"$1\" teu bisa dirobah kusabab répositori \"$2\" keur dina mode ukur-maca.\n\nKuncén anu ngonci méré alesan: \"$3\".",
        "exception-nologin": "Henteu asup log",
        "exception-nologin-text": "Mangga asup log pikeun bisa asup atawa ngarobah ieu kaca.",
+       "exception-nologin-text-manual": "Mangga $1 pikeun bisa asup atawa ngarobah ieu kaca.",
        "virus-badscanner": "Kasalahan konfigurasi: panyekén virus teu dipikawanoh: ''$1''",
        "virus-scanfailed": "nyekén gagal (kode $1)",
        "virus-unknownscanner": "antivirus teu dipikawanoh:",
-       "logouttext": "'''Anjeun ayeuna geus kaluar log.'''\n\nAnjeun bisa tetep migunakeun {{SITENAME}} bari anonim, atawa bisa <span class='plainlinks'>[$1 asup log deui]</span> salaku pamaké nu sarua atawa nu séjén deui.\nMangkahadé, sababaraha kaca bakal tetep némbongkeun saolah-olah anjeun asup log kénéh nepi ka anjeun ngosongkeun ''cache'' panyungsi anjeun.",
+       "logouttext": "<strong>Anjeun ayeuna geus kaluar log.<strong>\n\nMangkahadé, sababaraha kaca bakal tetep némbongkeun saolah-olah asup kénéh log nepi ka anjeun ngosongkeun ''cache'' dina panyungsi.",
        "welcomeuser": "Bagéa, $1!",
        "welcomecreation-msg": "Akun anjeun geus dijieun.\nLamun minat, Anjeun bisa ngarobah [[Special:Preferences|préferénsi]] {{SITENAME}}.",
        "yourname": "Sandiasma:",
        "createacct-yourpasswordagain": "Konfirmasi kecap sandi",
        "createacct-yourpasswordagain-ph": "Asupkeun deui kecap sandi",
        "remembermypassword": "Apalkeun login kuring dina ieu komputer (pikeun paling lila $1 {{PLURAL:$1|poé|poé}})",
+       "userlogin-remembermypassword": "Jaga ngarah angger asup log",
        "userlogin-signwithsecure": "Paké sambungan aman",
        "yourdomainname": "Domain anjeun",
        "password-change-forbidden": "Anjeun teu bisa ngarobah kecap sandi dina ieu wiki.",
        "userlogin-resetlink": "Poho akun sorangan?",
        "userlogin-resetpassword-link": "Poho kecap sandi?",
        "userlogin-helplink2": "Pitulung asup log",
+       "userlogin-loggedin": "Anjeun geus asup log salaku {{GENDER:$1|$1}}.\nPaké pormulir di handap pikeun asup log salaku pamaké séjén.",
+       "userlogin-createanother": "Jieun akun séjén",
        "createacct-emailrequired": "Alamat surélék:",
        "createacct-emailoptional": "Alamat surélék (teu wajib)",
        "createacct-email-ph": "Asupkeun alamat surélék anjeun",
        "badretype": "Sandi nu diasupkeun teu cocog.",
        "userexists": "Sandiasma nu diasupkeun geus aya nu maké.\nMangga pilih sandiasma nu séjén.",
        "loginerror": "Kasalahan asup log",
+       "createacct-error": "Nyieun akun éror",
        "createaccounterror": "Teu bisa nyieun rekening: $1",
        "nocookiesnew": "Rekening pamaké geus dijieun, tapi anjeun can asup log. {{SITENAME}} maké ''cookies'' pikeun ngasupkeun log pamaké. Anjeun boga ''cookies'' nu ditumpurkeun. Mangga fungsikeun, teras asup log migunakeun ngaran pamaké sarta sandi nu anyar.",
        "nocookieslogin": "{{SITENAME}} migunakeun ''cookies'' pikeun ngasupkeun pamaké kana log. Anjeun boga ''cookies'' nu ditumpurkeun. Mangga pungsikeun sarta cobian deui.",
        "passwordsent": "Sandi anyar geus dikirim ka alamat surélék nu kadaptar pikeun \"$1\". Mangga asup log deui satutasna katarima.",
        "blocked-mailpassword": "Alamat IP anjeun dipeungpeuk, moal bisa ngédit, and so\nis not allowed to use the password recovery function to prevent abuse.",
        "eauthentsent": "Surélék konfirmasi geus dikirim ka alamat bieu.\nMéméh aya surat séjén asup ka akunna, anjeun kudu nuturkeun pituduh dina surélékna pikeun mastikeun yén akun éta téh bener boga anjeun.",
-       "throttled-mailpassword": "Hiji panginget kecap sandi geus dikirimkeun dina {{PLURAL:$1|jam|$1 jam}} pamungkas.\nPikeun ngahindar disalahgunakeun, ngan hiji kecap sandi anu baris dikirimkeun saban {{PLURAL:$1|jam|$1 jam}}.",
+       "throttled-mailpassword": "Surélék pikeun ngarobah kecap sandi geus dikirim {{PLURAL:$1|jam|$1 jam}} kaliwat.\nNgarah hanteu disalahgunakeun, ngan hiji surélék anu bakal dikirim saban {{PLURAL:$1|jam|$1 jam}}.",
        "mailerror": "Kasalahan ngirim surat: $1",
        "acct_creation_throttle_hit": "Punten,pamaké alamat IP anjeun geus nyieun {{PLURAL:$1|1 rekening|$1 rekening}} dina sapoé ieu. mangrupa jumlah nu di idinan dina sapoé.\nanjeun teu bisa nyieun deui samentara waktu.",
        "emailauthenticated": "Alamat surélék anjeun geus dikonfirmasi $2 tabuh $3.",
        "cannotchangeemail": "Alamat surat-é akun hanteu bisa dirobah di ieu wiki.",
        "emaildisabled": "Ieu loka teu bisa ngirim surélék.",
        "accountcreated": "Rekening geus dijieun.",
-       "accountcreatedtext": "Rekening pamaké pikeun $1 geus dijieun.",
+       "accountcreatedtext": "Akun pamaké [[{{ns:Pamaké}}:$1|$1]] ([[{{ns:Obrolan pamaké}}:$1|obrolan]]) geus dijieun.",
        "createaccount-title": "Nyieun rekening keur {{SITENAME}}",
        "createaccount-text": "Aya nu nyieun rekening pikeun alamat surélék anjeun di {{SITENAME}} ($4) maké landihan \"$2\" sarta sandi \"$3\". Anjeun kudu asup log sarta ngaganti sandina ayeuna kénéh.\n\nMun ieu rekening balukar ayana éror, teu kudu diwaro.",
-       "login-throttled": "Anjeun geus loba teuing nyobaan asup log.\nTungguan heula sakeudeung, laju cobaan deui.",
+       "login-throttled": "Anjeun geus loba teuing nyobaan asup log.\nTungguan $1, laju cobaan deui.",
        "login-abort-generic": "Login gagal - Dibolaykeun",
+       "login-migrated-generic": "Akun anjeun geus pindah, ku kituna sandiasma anjeun geus leungit ti ieu wiki.",
        "loginlanguagelabel": "Basa: $1",
        "suspicious-userlogout": "Pamundut anjeun pikeun kaluar log ditolak ku sabab sigana dikirim ku pangaprak buntu atawa ''cache'' proxi.",
+       "createacct-another-realname-tip": "Ngaran asli hanteu diwajibkeun.\nLamun anjeun milih ngeusian, ieu ngaran bakal dipaké pikeun nandaan kontribusi anjeun.",
        "pt-login": "Asup log",
        "pt-login-button": "Asup log",
        "pt-createaccount": "Jieun akun",
        "php-mail-error-unknown": "Kasalahan nu teu kanyahoan dina fungsi PHP surélék().",
        "user-mail-no-addy": "Nyobaan ngirim surélék tanpa alamat.",
        "changepassword": "Robah sandi",
-       "resetpass_announce": "Anjeun asup log migunakeun sandi samentara. Salajengna, mangga gentos ku sandi anyar di dieu:",
+       "resetpass_announce": "Pikeun nganggeuskeun asup log, anjeun kudu nyieun kecap sandi anyar.",
        "resetpass_text": "<!-- Tambahkeun téks di dieu -->",
        "resetpass_header": "Ganti sandi rekening",
        "oldpassword": "Sandi heubeul",
        "newpassword": "Sandi anyar:",
        "retypenew": "Ketik ulang sandi",
        "resetpass_submit": "Setél log asup katut sandina",
-       "changepassword-success": "Kecap sandi Anjeun geus junun dirobah! Ayeuna proses asup log Anjeun...",
+       "changepassword-success": "Kecap sandi Anjeun geus laksana dirobah!",
+       "changepassword-throttled": "Anjeun geus loba teuing nyobaan asup log.\nTungguan $1 méméh nyobaan deui.",
        "resetpass_forbidden": "Sandi henteu bisa dirobah",
        "resetpass-no-info": "Anjeun kudu asup log pkeun bisa muka ieu kaca sacara langsung.",
        "resetpass-submit-loggedin": "Ganti kecap sandi rekening",
        "resetpass-submit-cancel": "Bolay",
        "resetpass-wrong-oldpass": "Salah sandi.\nBisa jadi anjeun geus ngaganti sandina atawa ménta sandi saheulaanan anu anyar.",
+       "resetpass-recycled": "Mangga ganti kecap sandi anjeun ku nu anyar.",
+       "resetpass-temp-emailed": "Anjeun asup log migunakeun sandi témporér. Pikeun nganggeuskeun asup log, anjeun kudu nyieun kecap sandi anyar di dieu:",
        "resetpass-temp-password": "Sandi samentara:",
+       "resetpass-expired": "Kecap sandi anjeun geus kadaluwarsa. Mangga jieun anu anyar pikeun asup log.",
        "passwordreset": "Setél ulang sandi",
        "passwordreset-legend": "Setél ulang sandi",
        "passwordreset-disabled": "Dina ieu wiki, sandi teu bisa disetél ulang.",
        "copyrightwarning": "Perhatikeun yén sadaya kontribusi ka MediaWiki dianggap medal dina panangtayungan lisénsi $2 (tempo $1 pikeun jéntréna). Mun anjeun teu miharep tulisan anjeun dirobah sarta disebarkeun deui, ulah dilebetkeun ka dieu.<br />\nAnjeun ogé jangji yén tulisan ieu dijieun ku sorangan, atawa disalin ti ''domain'' umum atawa sumberdaya bébas séjénna. '''ULAH NGASUPKEUN KARYA NU MIBANDA HAK CIPTA TANPA IDIN!'''",
        "copyrightwarning2": "Catet yén sadaya kontribusi ka {{SITENAME}} bisa diédit, dirobah, atawa dihapus ku kontributor séjén. Mun anjeun teu miharep tulisan anjeun dirobah, ulah ngintunkeun ka dieu.<br />\nAnjeun ogé mastikeun yén ieu téh pituin tulisan anjeun, atawa salinan ti domain umum atawa sumberdaya bébas séjénna (tempo $1 pikeun écésna).\n'''ULAH NGINTUNKEUN KARYA NU MIBANDA HAK CIPTA TANPA WIDI!'''",
        "longpageerror": "'''SALAH: Téks anu dikirimkeun gedéna $1 kb, leuwih ti maksimum $2 kb. Téks teu bisa disimpen.'''",
-       "readonlywarning": "'''PERHATOSAN''': pangkalan data dikonci pikeun diropéa, anjeun moal bisa nyimpen éditan anjeun ayeuna. Cobi ''cut-n-paste'' téksna ka na koropak téks sarta simpen dina waktu séjén.\n\nkuncén nu ngonci pangkalan data mikeun kajelasan : $1",
+       "readonlywarning": "<strong>Awas: pangkalan data dikonci pikeun diropéa, anjeun moal bisa nyimpen éditan anjeun ayeuna.</strong>\nMun perlu, simpen heula téksna kana berkas téks pikeun diasupkeun deui séjén mangsa.\n\nKuncén anu ngonci pangkalan data méré katerangan: $1",
        "protectedpagewarning": "'''AWAS: ieu kaca dikonci sarta ngan bisa dirobah ku pamaké nu statusna kuncén.'''\nÉntri log panungtungan ditémbongkeun di handap:",
        "semiprotectedpagewarning": "'''Catetan''': ieu kaca dikonci sarta ukur bisa dirobah ku pamaké nu geus kadaptar.\nÉntri log panungtung dibéréndélkeun di handap:",
        "cascadeprotectedwarning": "'''Awas''': ieu kaca dikonci sahingga ukur bisa dirobah ku kuncén, sabab kaasup {{PLURAL:$1|kaca|kaca}} dina panyalindungan-ngaruntuy di handap ieu:",
        "revdelete-nooldid-title": "Udagan révisi salah",
        "revdelete-nooldid-text": "Anjeun can nangtukeun atawa méré révisi pikeun ngajalankeun ieu fungsi, révisi nu di tangtukeun can aya, atawa anjeun nyoba nyumputkeun  révisi kiwari.",
        "revdelete-no-file": "Berkas anu ditujul teu kapanggih.",
-       "revdelete-show-file-confirm": "Anjeun yakin rék nempo révisi anu geus dihapus dina koropak \"<nowiki>$1</nowiki>\" ti $2 nepi ka $3?",
+       "revdelete-show-file-confirm": "Anjeun yakin rék nempo révisi anu geus dihapus dina berkas \"<nowiki>$1</nowiki>\" ti $2 nepi ka $3?",
        "revdelete-show-file-submit": "Enya",
        "logdelete-selected": "{{PLURAL:$1|pilihan keur log|pilihan keur log}}:",
        "revdelete-confirm": "Mangga geura konfirmasi yen Anjeun gaduh maksad pikeun ngalakukeun hal ieu, paham kana konsekwensina, tur nu dilakukeun ieu teh luyu sareng [[{{MediaWiki:Policy-url}}|kawijakanana]]",
        "searchprofile-everything": "Sagala",
        "searchprofile-advanced": "Lengkep",
        "searchprofile-articles-tooltip": "Pilari di $1",
-       "searchprofile-images-tooltip": "Pilari koropak/file",
+       "searchprofile-images-tooltip": "Pilari berkas",
        "searchprofile-everything-tooltip": "Pilari di sakabéh eusi (kaasup kaca obrolan)",
        "searchprofile-advanced-tooltip": "Paluruh di rohang ngaran anu tangtu",
        "search-result-size": "$1 ({{PLURAL:$2|1 kecap|$2 kecap}})",
        "listfiles-delete": "hapus",
        "listfiles-summary": "Ieu kaca husus némbongkeun sakabéh berkas anu geus diunggah.",
        "listfiles_search_for": "Sungsi ngaran média:",
-       "imgfile": "koropak",
+       "imgfile": "Berkas",
        "listfiles": "Daptar gambar",
        "listfiles_date": "Titimangsa",
        "listfiles_name": "Ngaran",
        "querypage-disabled": "Ieu kaca husus ditumpurkeun ku alesan kinerja.",
        "booksources": "Sumber pustaka",
        "booksources-search-legend": "Sungsi sumber buku",
-       "booksources-go": "Jung",
        "booksources-text": "Di handap ieu ngabéréndélkeun tumbu ka loka-loka nu ngical buku, boh nu anyar atawa loakan, nu sugan uninga kana buku anu nuju dipilari:",
        "booksources-invalid-isbn": "ISBN-na sigana henteu bener; pariksa deui bisi aya salah salin ti sumber aslina.",
        "specialloguserlabel": "Pamaké:",
        "undeleteviewlink": "tempo",
        "undeletecomment": "Alesan:",
        "undeletedrevisions": "$1 {{PLURAL:$1|révisi|révisi}} disimpen deui",
-       "undeletedrevisions-files": "{{PLURAL:$1|1 révisi|$1 révisi}} jeung {{PLURAL:$2|1 koropak|$2 koropak}} geus dipulangkeun",
-       "undeletedfiles": "$1 {{PLURAL:$1|koropak}} dibalikeun",
+       "undeletedrevisions-files": "{{PLURAL:$1|1 révisi|$1 révisi}} jeung {{PLURAL:$2|1 berkas|$2 berkas}} geus dibalikkeun",
+       "undeletedfiles": "{{PLURAL:$1|1 berkas|$1 berkas}} dibalikkeun",
        "cannotundelete": "Gagal ngabolaykeun hapusan; sigana kapiheulaan ngabolaykeun hapusan ku nu séjén.",
        "undeletedpage": "'''$1 hasil dibalikeun'''\n\nTempo [[Special:Log/delete|log hapusan]] keur data ngahapus jeung malikeun.",
        "undelete-header": "Tempo [[Special:Log/delete|log hapusan]] pikeun béréndélan kaca nu anyar dihapus.",
        "undelete-search-prefix": "Témbongkeun kaca dimimitian ku",
        "undelete-search-submit": "Téang",
        "undelete-no-results": "Euweuh kaca nu cocog dina arsip hapusan.",
-       "undelete-filename-mismatch": "Teu bisa ngabolaykeun hapusan révisi koropak nu titimangsana $1: ngaran teu cocog.",
-       "undelete-bad-store-key": "Teu bisa ngabolaykeun hapusan révisi koropak nu titimangsana $1: leungit méméh dihapus.",
-       "undelete-cleanup-error": "Éror ngahapus koropak arsip \"$1\" nu teu kapaké.",
-       "undelete-missing-filearchive": "Gagal mulangkeun arsip koropak ID $1 kusabab teu kapanggih dina pangkalan data. Bisa jadi éta koropak bolay dihapus.",
+       "undelete-filename-mismatch": "Hanteu bisa ngabolaykeun hapusan révisi berkas titimangsa $1: ngaran berkas teu cocog.",
+       "undelete-bad-store-key": "Hanteu bisa ngabolaykeun hapusan révisi berkas titimangsa $1: Berkas leungit méméh dihapus.",
+       "undelete-cleanup-error": "Éror ngahapus berkas arsip \"$1\" anu teu kapaké.",
+       "undelete-missing-filearchive": "Hanteu bisa mulangkeun arsip berkas ID $1 kusabab teu kapanggih dina pangkalan data. Bisa jadi éta koropak bolay dihapus.",
        "undelete-error-short": "Éror ngabolaykeun hapusan: $1",
        "undelete-error-long": "Aya éror nalika ngabolaykeun hapusan:\n\n$1",
        "undelete-show-file-submit": "Enya",
        "immobile-source-page": "Ieu kaca teu bisa dipindahkeun.",
        "immobile-target-page": "Teu bisa mindahkeun ka judul nu ditujul.",
        "imagenocrossnamespace": "Teu bisa mindahkeun gambar ka rohangan ngaran nu lain gambar",
-       "imagetypemismatch": "Éksténsi koropak anyar teu cocog jeung tipena",
-       "imageinvalidfilename": "Ngaran koropak tujuan teu sah",
+       "imagetypemismatch": "Éksténsi berkas anyar teu cocog jeung tipena",
+       "imageinvalidfilename": "Ngaran berkas tujuan teu sah",
        "fix-double-redirects": "Hadéan sakabéh alihan ganda nu mungkin kajadian",
        "protectedpagemovewarning": "'''Awas:''' ieu kaca geus dikonci sarta ngan bisa dipindahkeun ku pamaké nu boga kawenangan kuncén.\nPikeun rujukan, éntri log panungtung dipidangkeun di handap:",
        "semiprotectedpagemovewarning": "'''Awas:''' ieu kaca geus dikonci sarta ukur bisa dipindahkeun ku pamaké nu geus asup log.\nPikeun rujukan, éntri log panungtung dipidangkeun di handap:",
        "export-addcattext": "Tambahkeun kaca tina kategori:",
        "export-addcat": "Tambahkeun",
        "export-addns": "Tambahkeun",
-       "export-download": "Simpen dina koropak",
+       "export-download": "Simpen salaku berkas",
        "export-templates": "Kaasup citakan",
        "allmessages": "Talatah sistim",
        "allmessagesname": "Ngaran",
        "allmessages-language": "Basa:",
        "allmessages-filter-submit": "Jung",
        "thumbnail-more": "Gedéan",
-       "filemissing": "Koropak leungit",
+       "filemissing": "Berkas leungit",
        "thumbnail_error": "Kasalahan sawaktu nyieun gambar leutik (thumbnail): $1",
        "djvu_page_error": "Kaca DjVu teu kawadahan",
-       "djvu_no_xml": "XML keur koropak DjVu teu bisa dicokot",
+       "djvu_no_xml": "Hanteu bisa nyokot XML pikeun berkas DjVu",
        "thumbnail_invalid_params": "Kasalahan paraméter miniatur",
        "thumbnail_dest_directory": "Diréktori nu dituju teu bisa dijieun",
        "thumbnail_image-type": "Jenis gambar teu dirojong",
index 526cddf..385bd2d 100644 (file)
        "querypage-disabled": "Den här specialsidan är inaktiverad av prestandaskäl.",
        "booksources": "Bokkällor",
        "booksources-search-legend": "Sök efter bokkällor",
-       "booksources-go": "Visa",
        "booksources-text": "Nedan följer en lista över länkar till webbplatser som säljer nya och begagnade böcker, och som kanske har ytterligare information om de böcker du söker.",
        "booksources-invalid-isbn": "Det angivna ISBN-numret verkar inte vara giltigt. Kontrollera källan för eventuella fel.",
        "specialloguserlabel": "Utförare:",
index a4f87fa..65946f9 100644 (file)
        "passwordreset-emailsent-capture": "پارولنى قايتا بېكىتىش ئېلخېتى يوللاندى، تۆۋەندە كۆرسىتىلىدۇ.",
        "passwordreset-emailerror-capture": "ھاسىل قىلىنغان پارولنى قايتا بېكىتىش ئېلخېتى تۆۋەندە كۆرسىتىلگەندەك ئەمما ئۇنى {{GENDER:$2|ئىشلەتكۈچى}}گە يوللىيالمىدى: $1",
        "changeemail": "ئېلخەت ئادرېس ئۆزگەرت",
-       "changeemail-header": "ھېساباتنىڭ ئېلخەت ئادرېسىنى ئۆزگەرت",
        "changeemail-text": "بۇ جەدۋەل تاماملانسا ئېلخەت ئادرېسىڭىزنى ئۆزگەرتىدۇ. سىز ئىم كىرگۈزۈپ بۇ ئۆزگەرتىشنى جەزملەيسىز.",
        "changeemail-no-info": "سىز تىزىمغا كىرگەندىن كېيىن بىۋاسىتە بۇ بەتكە كىرىشىڭىز لازىم.",
        "changeemail-oldemail": "نۆۋەتتىكى ئېلخەت ئادرېسى:",
        "changeemail-none": "(يوق)",
        "changeemail-password": "{{SITENAME}} دىكى پارولىڭىز:",
        "changeemail-submit": "ئېلخەت ئۆزگەرت",
-       "changeemail-cancel": "ۋاز كەچ",
        "changeemail-throttled": "سىز بۇ ھېساباتتا تىزىمغا كىرىشنى كۆپ قېتىم سىنىدىڭىز.\n$1 ساقلاپ، ئاندىن قايتا سىناڭ.",
        "resettokens": "ئاچقۇچلۇق بەلگىلەرنى قايتا بېكىتمەك",
        "resettokens-text": "سىز بۇ يەردە سىزنىڭ ھىساۋاتىڭىزگە مۇناسۋەتلىك شەخسى ئۇچۇر مەخپىيەتلىكىنى قايتا كۆرەلەيسىز.\n\nئۇ ئۇچۇرلار ھەمبەھرلىنىپ كەتسە ياكى باشقىلار ئىشلىتۋالغان بولسا، ئۇ ئۇچۇرلارنى ئەسلىگە قايتۇرۇڭ.",
        "searchrelated": "ئالاقىدار",
        "searchall": "ھەممىسى",
        "showingresults": "تۆۋەندە '''$2''' - نەتىجىدىن باشلانغان {{PLURAL:$1|'''1''' نەتىجە|'''$1''' نەتىجە}} كۆرسىتىدۇ:",
-       "showingresultsheader": "'''$4''' نىڭ {{PLURAL:$5|'''$1''' دىن '''$3'''غىچە نەتىجە | '''$1 - $2''' غىچە جەمئى '''$3''' نەتىجە}}",
        "search-nonefound": "سۈرۈشتۈرۈشكە ماس نەتىجە تېپىلمىدى.",
        "powersearch-legend": "ئالىي ئىزدەش",
        "powersearch-ns": "ئات بوشلۇقىدىن ئىزدە:",
        "booksources": "كىتاب مەنبەسى",
        "booksources-search-legend": "كىتاب مەنبەسى ئىزدە",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "يۆتكەل",
        "booksources-text": "تۆۋەندىكىسى بىر قىسىم تور كىتابخانىلىرىنىڭ تىزىملىكى، ئىچىدە سىز ئىزدىمەكچى بولغان كىتابلارنىڭ تېخىمۇ كۆپ ئۇچۇرى بولۇشى مۇمكىن:",
        "booksources-invalid-isbn": "تەمىنلىگەن ISBN نومۇرى توغرا ئەمەس. ئەسلى كۆچۈرگەن مەنبەدىكى نومۇردا خاتالىق بار يوقلۇقىنى تەكشۈرۈڭ.",
        "specialloguserlabel": "ئىشلەتكۈچى:",
        "import": "بەت ئەكىر",
        "importinterwiki": "wiki ھالقىپ ئەكىر",
        "import-interwiki-text": "wiki دىن بىرنى ۋە بەت ماۋزۇسىنى تاللاپ ئەكىرىڭ.\nتۈزىتىلگەن ۋاقىت ۋە تەھرىرلىگۈچى ئاتى بىرلا ۋاقىتتا ساقلىنىدۇ.\nبارلىق wiki ھالقىغان ئەكىرىش مەشغۇلاتى  [[Special:Log/import|ئەكىرىش خاتىرىسى]]غا خاتىرىلىنىدۇ.",
-       "import-interwiki-source": "مەنبە wiki /بەت:",
        "import-interwiki-history": "بۇ بەتنىڭ ھەممە تارىخى تۈزىتىلگەن نەشرىنى كۆچۈر.",
        "import-interwiki-templates": "ھەممە قېلىپىنى ئۆز ئىچىگە ئالىدۇ",
        "import-interwiki-submit": "ئەكىر",
        "logentry-rights-rights-legacy": "$3 نىڭ ئىشلەتكۈچى گۇرۇپپىسىنى $1 ئۆزگەرتتى",
        "logentry-rights-autopromote": "$1 نىڭ ئىشلەتكۈچى گۇرۇپپىسى ئۆزلۈكىدىن $4 دىن $5 غا يۈكسەلدى",
        "rightsnone": "(يوق)",
+       "revdelete-summary": "ئۈزۈندە تەھرىرلە",
        "feedback-bugornote": "ئەگەر بىر تېخنىكىلىق مەسىلىنى تەپسىلىي بايان قىلىشقا تەييارلانماقچى بولسىڭىز، [$1 خاتالىق دوكلات]ى يوللاڭ. ياكى تۆۋەندىكى ئاددىي جەدۋەلنى ئىشلىتىڭ. ئىنكاسىڭىز \"[$3 $2]\" بەتكە قوشۇلىدۇ، ئىشلەتكۈچى ئاتىڭىز ۋە ئىشلەتكەن توركۆرگۈڭىز قوشۇپ قويۇلىدۇ.",
        "feedback-subject": "تېما:",
        "feedback-message": "ئۇچۇر:",
index 3acfc3f..59144f3 100644 (file)
        "booksources": "Джерела книг",
        "booksources-search-legend": "Пошук інформації про книгу",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "Знайти",
        "booksources-text": "На цій сторінці наведено список посилань на сайти, де ви, можливо, знайдете додаткову інформацію про книгу. Це інтернет-магазини й системи пошуку в бібліотечних каталогах.",
        "booksources-invalid-isbn": "Вказаний номер ISBN, судячи з усього, містить помилку. Будь ласка, перевірте, що при перенесенні номера з першоджерела не виникло спотворень.",
        "specialloguserlabel": "Виконавець:",
index 8d7153b..0184d50 100644 (file)
        "querypage-disabled": "Trang đặc biệt này bị tắt vì lý do hiệu suất.",
        "booksources": "Nguồn sách",
        "booksources-search-legend": "Tìm kiếm nguồn sách",
-       "booksources-go": "Tìm kiếm",
        "booksources-text": "Dưới đây là danh sách những trang bán sách mới và cũ, đồng thời có thể có thêm thông tin về những cuốn sách bạn đang tìm:",
        "booksources-invalid-isbn": "ISBN mà bạn cung cấp dường như không đúng; xin hãy kiểm tra lại xem có lỗi gì khi sao chép từ nội dung gốc hay không.",
        "specialloguserlabel": "Người thực hiện:",
index b01f36e..bff2ec5 100644 (file)
        "pager-older-n": "{{PLURAL:$1|$1 pus vî|$1 pus vîs}}",
        "booksources": "Sourdants po les lives",
        "booksources-search-legend": "Cweri des sourdants po des lives",
-       "booksources-go": "I va",
        "specialloguserlabel": "Fwait pa:",
        "speciallogtitlelabel": "Såme (tite ou uzeu):",
        "log": "Djournås",
index 447126c..7873d7a 100644 (file)
        "querypage-disabled": "דער באַזונדער־בלאַט איז אומאַקטיווירט צוליב אויספֿירונג סיבות.",
        "booksources": "דרויסנדיגע ליטעראַטור ISBN",
        "booksources-search-legend": "זוכן פאר דרויסנדע ביכער מקורות",
-       "booksources-go": "גיין",
        "booksources-text": "אונטן איז א ליסטע פון סייטס וואס פֿארקויפֿן נייע און גענוצטע ביכער און האבן אויך נאך אינפֿארמאציע וועגן די ביכער וואס איר זוכט:",
        "booksources-invalid-isbn": "דאָס געגעבענע ISBN זעט נישט אויס צו זיין גילטיק; קאנטראלירט פֿאַר גרײַזן בײַם קאפּירן פון דעם ערשטיקן מקור.",
        "specialloguserlabel": "אויספֿירער:",
index d84868d..88be376 100644 (file)
        "category-file-count": "{{PLURAL:$2|本分类只包含以下一个文件。|本分类包含以下$1个文件,共$2个文件。}}",
        "category-file-count-limited": "当前分类包含以下$1个文件。",
        "listingcontinuesabbrev": "续",
-       "index-category": "å\8f¯索引页面",
+       "index-category": "å·²索引页面",
        "noindex-category": "不可索引页面",
        "broken-file-category": "有受损文件链接的页面",
        "categoryviewer-pagedlinks": "($1)($2)",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "expensive-parserfunction-warning": "<strong>警告:</strong>这个页面有太多高昂的语法功能调用。\n\n它应该少过$2次呼叫,现在有$1次呼叫。",
-       "expensive-parserfunction-category": "页面中有太多耗费的语法功能呼叫",
+       "expensive-parserfunction-category": "有过多高开销解析器函数调用的页面",
        "post-expand-template-inclusion-warning": "'''警告:'''包含模板大小过大。\n一些模板将不会包含。",
-       "post-expand-template-inclusion-category": "模板包含上限已经超过的页面",
+       "post-expand-template-inclusion-category": "模板包含大小超限的页面",
        "post-expand-template-argument-warning": "<strong>警告:</strong>本页面包含至少一个模板参数有过大扩展大小。这些参数会被略过。",
        "post-expand-template-argument-category": "含有略过模板参数的页面",
        "parser-template-loop-warning": "检查到模板循环:[[$1]]",
        "parser-template-recursion-depth-warning": "模板递归深度越限($1)",
        "language-converter-depth-warning": "字词转换器深度越限($1)",
-       "node-count-exceeded-category": "页面的节点数超出限制",
-       "node-count-exceeded-category-desc": "超出最高节点数的页面。",
-       "node-count-exceeded-warning": "页面超出了节点数",
-       "expansion-depth-exceeded-category": "扩展深度超出限制的页面",
-       "expansion-depth-exceeded-category-desc": "页面超出最大扩展深度。",
-       "expansion-depth-exceeded-warning": "页面超过了扩展深度",
+       "node-count-exceeded-category": "节点数超限的页面",
+       "node-count-exceeded-category-desc": "页面超出最大节点数限制。",
+       "node-count-exceeded-warning": "页面超出节点数限制",
+       "expansion-depth-exceeded-category": "展开深度超限的页面",
+       "expansion-depth-exceeded-category-desc": "页面超出了最大的展开深度。",
+       "expansion-depth-exceeded-warning": "页面超出展开深度限制",
        "parser-unstrip-loop-warning": "检测到回圈",
        "parser-unstrip-recursion-limit": "递归超过限制 ($1)",
        "converter-manual-rule-error": "在手动语言转换规则中检测到错误",
        "booksources": "网络书源",
        "booksources-search-legend": "搜索图书来源",
        "booksources-isbn": "ISBN:",
-       "booksources-go": "提交",
+       "booksources-search": "搜索",
        "booksources-text": "下面是销售新书和二手书的其他网站的链接的列表,也可能有关于你正在寻找的图书的更多信息:",
        "booksources-invalid-isbn": "提供的ISBN号码并不正确,请检查原始复制来源号码是否有误。",
        "specialloguserlabel": "执行者:",
        "trackingcategories-msg": "追踪分类",
        "trackingcategories-name": "信息名",
        "trackingcategories-desc": "分类收录标准",
-       "noindex-category-desc": "页面中有<code><nowiki>__NOINDEX__</nowiki></code>魔术字(并且在标记允许的名字空间)且因此未被机器人索引的。",
-       "index-category-desc": "页é\9d¢ä¸\8aæ\9c\89é­\94æ\9c¯å­\97<code><nowiki>__INDEX__</nowiki></code>ï¼\88并ä½\8däº\8eå\85\81许è¿\99ç§\8dæ \87è®°ç\9a\84å\90\8då­\97空é\97´ï¼\89ï¼\8c并å\9b æ­¤è¢«ç½\91ç»\9cç\88¬è\99«ç´¢å¼\95ï¼\8cä½\86é\80\9a常ä¸\8dä¼\9a被索å¼\95。",
-       "post-expand-template-inclusion-category-desc": "在展开了所有模板后,页面大小大于<code>$wgMaxArticleSize</code>,所以一些模板未展开。",
-       "post-expand-template-argument-category-desc": "å±\95å¼\80äº\86模æ\9d¿å\8f\82æ\95°ï¼\88ä¸\89对è\8a±æ\8b¬å\8f·å\86\85ï¼\8cä¾\8bå¦\82<code>{{{Foo}}}</code>ï¼\89ä¹\8b后,页面大于<code>$wgMaxArticleSize</code>。",
-       "expensive-parserfunction-category-desc": "页面包含了太多的高级解析器函数(例如<code>#ifexist</code>)。参见[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit Manual:$wgExpensiveParserFunctionLimit]。",
-       "broken-file-category-desc": "页é\9d¢å\8c\85å\90«æ\8d\9få\9d\8fç\9a\84æ\96\87件è¿\9eæ\8e¥ï¼\88è¿\9eæ\8e¥è\87³åµ\8cå\85¥ç\9a\84ä¸\80个ä¸\8då­\98å\9c¨æ\96\87件)。",
-       "hidden-category-category-desc": "页面中包含<code><nowiki>__HIDDENCAT__</nowiki></code>的分类,它阻止分类默认在页面上的分类链接框中显示。",
+       "noindex-category-desc": "因为页面上有魔术字<code><nowiki>__NOINDEX__</nowiki></code>并位于允许该旗标的名字空间,而不被网络爬虫索引的页面。",
+       "index-category-desc": "页é\9d¢ä¸\8aæ\9c\89é­\94æ\9c¯å­\97<code><nowiki>__INDEX__</nowiki></code>ï¼\88并ä½\8däº\8eå\85\81许该æ\97\97æ \87ç\9a\84å\90\8då­\97空é\97´ï¼\89ï¼\8c并å\9b æ­¤è¢«ç½\91ç»\9cç\88¬è\99«ç´¢å¼\95ï¼\88è¿\99äº\9b页é\9d¢é\80\9a常ä¸\8dä¼\9a被索å¼\95ï¼\89。",
+       "post-expand-template-inclusion-category-desc": "在展开所有模板后,页面大小大于<code>$wgMaxArticleSize</code>,所以某些模板未展开。",
+       "post-expand-template-argument-category-desc": "å\9c¨å±\95å¼\80模æ\9d¿å\8f\82æ\95°ï¼\88以ä¸\89对è\8a±æ\8b¬å\8f·å\8c\85å\90«ç\9a\84ä¸\9c西ï¼\8cå¦\82<code>{{{Foo}}}</code>ï¼\89后,页面大于<code>$wgMaxArticleSize</code>。",
+       "expensive-parserfunction-category-desc": "页面使用过多高开销解析器函数(如<code>#ifexist</code>)。请见[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgExpensiveParserFunctionLimit MediaWiki官网手册]。",
+       "broken-file-category-desc": "页é\9d¢å\90«æ\9c\89å\8f\97æ\8d\9fæ\96\87件é\93¾æ\8e¥ï¼\88æ\96\87件ä¸\8då­\98å\9c¨æ\97¶ç\9a\84åµ\8cå\85¥æ\96\87件é\93¾æ\8e¥)。",
+       "hidden-category-category-desc": "分类的页面内容中含有<code><nowiki>__HIDDENCAT__</nowiki></code>,它会阻止分类默认在页面的分类链接框中显示。",
        "trackingcategories-nodesc": "没有说明。",
        "trackingcategories-disabled": "分类被禁用",
        "mailnologin": "无电子邮件地址",
        "import-interwiki-templates": "包含所有模板",
        "import-interwiki-submit": "导入",
        "import-interwiki-namespace": "目标名字空间:",
-       "import-interwiki-rootpage": "目的根页(可选):",
+       "import-interwiki-rootpage": "目标根页面(可选):",
        "import-upload-filename": "文件名:",
        "import-comment": "注释:",
        "importtext": "请使用[[Special:Export|导出功能]]从源 wiki 导出文件,\n保存到您的电脑并上传到这里。",
        "importlogpage": "导入日志",
        "importlogpagetext": "管理性导入在其他wiki上有编辑历史的页面。",
        "import-logentry-upload": "通过文件上传导入[[$1]]",
-       "import-logentry-upload-detail": "已导å\85¥$1个{{PLURAL:$1|ç\89\88æ\9c¬}}",
+       "import-logentry-upload-detail": "导入$1个{{PLURAL:$1|版本}}",
        "import-logentry-interwiki": "跨wiki页面$1",
-       "import-logentry-interwiki-detail": "已从$2导入$1个{{PLURAL:$1|版本}}",
+       "import-logentry-interwiki-detail": "来自$2的$1个{{PLURAL:$1|版本}}已导入",
        "javascripttest": "JavaScript测试",
        "javascripttest-title": "运行$1测试",
        "javascripttest-pagetext-noframework": "本页面被保留进行JavaScript测试。",
        "logentry-rights-rights": "$1{{GENDER:$2|更改}}$3的用户组自$4至$5",
        "logentry-rights-rights-legacy": "$1更改$3的用户组",
        "logentry-rights-autopromote": "$1被自动地{{GENDER:$2|提升}}自$4至$5",
-       "logentry-upload-upload": "$1{{GENDER:$2|上传}}$3",
-       "logentry-upload-overwrite": "$1{{GENDER:$2|上传}}$3的新版本",
-       "logentry-upload-revert": "$1{{GENDER:$2|上传}}$3",
+       "logentry-upload-upload": "$1{{GENDER:$2|上传}}$3",
+       "logentry-upload-overwrite": "$1{{GENDER:$2|上传}}$3的新版本",
+       "logentry-upload-revert": "$1{{GENDER:$2|上传}}$3",
        "rightsnone": "(无)",
        "revdelete-summary": "编辑摘要",
        "feedback-bugornote": "如果你准备好详细描述一个技术问题,请[$1 报告bug]。或者你可以使用下面的简单表格。你的评论将被添加至页面“[$3 $2]”,附有你的用户名。",
index 5dfec01..7119917 100644 (file)
        "userpage-userdoesnotexist": "使用者帳號 \"$1\" 尚未註冊。\n若您要建立/編輯此頁面,請先檢查是否正確。",
        "userpage-userdoesnotexist-view": "使用者帳號 \"$1\" 尚未註冊。",
        "blocked-notice-logextract": "此使用者目前已被封鎖。\n以下為最近的封鎖紀錄以供參考:",
-       "clearyourcache": "<strong>注意:</strong> 在您儲存之後您必須清除瀏覽器快取才可看到最新的變動。\n* <strong>Firefox / Safari:</strong> 按住 <em>Shift</em> 時點選 <em>重新整理</em>,或按 <em>Ctrl-F5</em> 或 <em>Ctrl-R</em> (Mac 為 <em>⌘-R</em>)\n* <strong>Google Chrome:</strong> 按 <em>Ctrl-Shift-R</em> (Mac 為 <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong> 按住 <em>Ctrl</em> 時點選 <em>重新整理</em>,或按 <em>Ctrl-F5</em>\n* <strong>Opera:</strong> 進入 <em>工具 → 偏好設定</em> 中清除快取。",
+       "clearyourcache": "<strong>注意:</strong>在您儲存之後您必須清除瀏覽器快取才可看到最新的變動。\n* <strong>Firefox / Safari:</strong>按住 <em>Shift</em> 時點選 <em>重新整理</em>,或按 <em>Ctrl-F5</em> 或 <em>Ctrl-R</em>(Mac 則為 <em>⌘-R</em>)\n* <strong>Google Chrome:</strong>按 <em>Ctrl-Shift-R</em>(Mac 則為 <em>⌘-Shift-R</em>)\n* <strong>Internet Explorer:</strong>按住 <em>Ctrl</em> 時點選 <em>重新整理</em>,或按 <em>Ctrl-F5</em>\n* <strong>Opera:</strong>進入 <em>工具 → 偏好設定</em> 中清除快取。",
        "usercssyoucanpreview": "<strong>提示:</strong>在儲存之前使用 \"{{int:showpreview}}\" 按鈕來測試您的新 CSS。",
        "userjsyoucanpreview": "<strong>提示:</strong>在儲存之前使用 \"{{int:showpreview}}\" 按鈕來測試您的新 JavaScript。",
        "usercsspreview": "<strong>您目前正預覽您的使用者 CSS,CSS 還尚未儲存!</strong>",
        "booksources": "圖書資源",
        "booksources-search-legend": "尋找圖書資源",
        "booksources-isbn": "國際標準書號:",
-       "booksources-go": "執行",
        "booksources-text": "下列清單包含其他銷售新書籍或二手書籍的網站連結,可會有你想尋找書籍的進一部資訊:",
        "booksources-invalid-isbn": "您提供的 ISBN 不正確,請檢查複製的來源是否有誤。",
        "specialloguserlabel": "執行者:",
index df8a34c..99f43ff 100644 (file)
@@ -2248,7 +2248,6 @@ logextract
 loggedin
 logid
 login
-loginend
 loginerror
 loginfo
 loginlanguagelinks
@@ -2259,7 +2258,6 @@ loginreqlink
 loginreqpagetext
 loginreqtitle
 logins
-loginstart
 logitem
 loglink
 loglist
index c80981b..0cc7bde 100644 (file)
@@ -16,8 +16,33 @@ if ( PHP_SAPI != 'cli' ) {
 }
 
 $source = file_get_contents( $argv[1] );
-$regexp = '#\@var\s+([^\s]+)([^/]+)/\s+(var|public|protected|private)\s+(\$[^\s;=]+)#';
-$replac = '${2} */ ${3} ${1} ${4}';
+$regexp = '#'
+       . '\@var'
+       . '\s+'
+       // Type hint
+       . '([^\s]+)'
+       . '\s+'
+       // Any text or line(s) between type hint and '/' closing the comment
+       // (includes the star of "*/"). Descriptions containing a slash
+       // are not supported. Those will have to to be rewritten to have their
+       // description *before* the @var:
+       // /**
+       //  * Description with / in it.
+       //  * @var array
+       //  */
+       // instead of:
+       // /**
+       //  * @var array Description with / in it.
+       //  */
+       . '([^/]+)'
+       . '/'
+       . '\s+'
+       . '(var|public|protected|private)'
+       . '\s+'
+       // Variable name
+       . '(\$[^\s;=]+)'
+       . '#';
+$replac = '${2}/ ${3} ${1} ${4}';
 $source = preg_replace( $regexp, $replac, $source );
 
 echo $source;
index 889b0f6..382317e 100644 (file)
@@ -4,10 +4,13 @@
                        "Milicevic01"
                ]
        },
-       "ooui-dialog-action-close": "Zatvori",
        "ooui-outline-control-move-down": "Premesti stavku na dole",
        "ooui-outline-control-move-up": "Premesti stavku na gore",
        "ooui-outline-control-remove": "Ukloni stavku",
        "ooui-toolbar-more": "Više",
-       "ooui-dialog-confirm-default-prompt": "Jeste li sigurni?"
+       "ooui-dialog-message-accept": "U redu",
+       "ooui-dialog-message-reject": "Otkaži",
+       "ooui-dialog-process-error": "Nešto je pošlo naopako",
+       "ooui-dialog-process-dismiss": "Odbaci",
+       "ooui-dialog-process-retry": "Pokušaj ponovo"
 }
index 05fb20d..cde5ffe 100644 (file)
@@ -23,6 +23,6 @@
        "ooui-dialog-message-accept": "確定",
        "ooui-dialog-message-reject": "取消",
        "ooui-dialog-process-error": "發生不明錯誤",
-       "ooui-dialog-process-dismiss": "放棄",
+       "ooui-dialog-process-dismiss": "關閉",
        "ooui-dialog-process-retry": "再試一次"
 }
index fdf41ae..0ee8ff6 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f2c3f12959)
+ * OOjs UI v0.1.0-pre (880100c45e)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-18T23:22:20Z
+ * Date: 2014-09-23T22:28:43Z
  */
 /*
  * Blank theme mixins.
index 36492c0..465f087 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f2c3f12959)
+ * OOjs UI v0.1.0-pre (880100c45e)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-18T23:22:20Z
+ * Date: 2014-09-23T22:28:43Z
  */
 /*
  * Blank theme mixins.
index 33c8238..7dd3735 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f2c3f12959)
+ * OOjs UI v0.1.0-pre (880100c45e)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-18T23:22:20Z
+ * Date: 2014-09-23T22:28:43Z
  */
 ( function ( OO ) {
 
@@ -8218,6 +8218,7 @@ OO.ui.ButtonWidget.prototype.setTarget = function ( target ) {
  * @param {Object} [config] Configuration options
  * @cfg {string} [action] Symbolic action name
  * @cfg {string[]} [modes] Symbolic mode names
+ * @cfg {boolean} [framed=false] Render button with a frame
  */
 OO.ui.ActionWidget = function OoUiActionWidget( config ) {
        // Config intialization
@@ -8661,6 +8662,7 @@ OO.ui.InlineMenuWidget.prototype.onClick = function ( e ) {
  * @abstract
  * @class
  * @extends OO.ui.Widget
+ * @mixins OO.ui.FlaggedElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -8676,6 +8678,9 @@ OO.ui.InputWidget = function OoUiInputWidget( config ) {
        // Parent constructor
        OO.ui.InputWidget.super.call( this, config );
 
+       // Mixin constructors
+       OO.ui.FlaggedElement.call( this, config );
+
        // Properties
        this.$input = this.getInputElement( config );
        this.value = '';
@@ -8697,6 +8702,7 @@ OO.ui.InputWidget = function OoUiInputWidget( config ) {
 /* Setup */
 
 OO.inheritClass( OO.ui.InputWidget, OO.ui.Widget );
+OO.mixinClass( OO.ui.InputWidget, OO.ui.FlaggedElement );
 
 /* Events */
 
@@ -8945,6 +8951,8 @@ OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
  * @cfg {boolean} [multiline=false] Allow multiple lines of text
  * @cfg {boolean} [autosize=false] Automatically resize to fit content
  * @cfg {boolean} [maxRows=10] Maximum number of rows to make visible when autosizing
+ * @cfg {RegExp|string} [validate] Regular expression (or symbolic name referencing
+ *  one, see #static-validationPatterns)
  */
 OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        // Configuration initialization
@@ -8962,9 +8970,13 @@ OO.ui.TextInputWidget = function OoUiTextInputWidget( config ) {
        this.multiline = !!config.multiline;
        this.autosize = !!config.autosize;
        this.maxRows = config.maxRows !== undefined ? config.maxRows : 10;
+       this.validate = config.validate || null;
 
        // Events
-       this.$input.on( 'keypress', OO.ui.bind( this.onKeyPress, this ) );
+       this.$input.on( {
+               keypress: OO.ui.bind( this.onKeyPress, this ),
+               blur: OO.ui.bind( this.setValidityFlag, this )
+       } );
        this.$element.on( 'DOMNodeInsertedIntoDocument', OO.ui.bind( this.onElementAttach, this ) );
        this.$icon.on( 'mousedown', OO.ui.bind( this.onIconMouseDown, this ) );
        this.$indicator.on( 'mousedown', OO.ui.bind( this.onIndicatorMouseDown, this ) );
@@ -8986,6 +8998,13 @@ OO.mixinClass( OO.ui.TextInputWidget, OO.ui.IconElement );
 OO.mixinClass( OO.ui.TextInputWidget, OO.ui.IndicatorElement );
 OO.mixinClass( OO.ui.TextInputWidget, OO.ui.PendingElement );
 
+/* Static properties */
+
+OO.ui.TextInputWidget.static.validationPatterns = {
+       'non-empty': /.+/,
+       integer: /^\d+$/
+};
+
 /* Events */
 
 /**
@@ -9076,6 +9095,7 @@ OO.ui.TextInputWidget.prototype.setValue = function ( value ) {
        // Parent method
        OO.ui.TextInputWidget.super.prototype.setValue.call( this, value );
 
+       this.setValidityFlag();
        this.adjustSize();
        return this;
 };
@@ -9157,6 +9177,31 @@ OO.ui.TextInputWidget.prototype.select = function () {
        return this;
 };
 
+/**
+ * Sets the 'invalid' flag appropriately.
+ */
+OO.ui.TextInputWidget.prototype.setValidityFlag = function () {
+       this.isValid().done( OO.ui.bind( function ( valid ) {
+               this.setFlags( { invalid: !valid } );
+       }, this ) );
+};
+
+/**
+ * Returns whether or not the current value is considered valid, according to the
+ * supplied validation pattern.
+ *
+ * @return {jQuery.Deferred}
+ */
+OO.ui.TextInputWidget.prototype.isValid = function () {
+       var validationRegexp;
+       if ( this.validate instanceof RegExp ) {
+               validationRegexp = this.validate;
+       } else {
+               validationRegexp = this.constructor.static.validationPatterns[this.validate];
+       }
+       return $.Deferred().resolve( !!this.getValue().match( validationRegexp ) ).promise();
+};
+
 /**
  * Text input with a menu of optional values.
  *
@@ -10082,6 +10127,9 @@ OO.ui.PopupWidget.prototype.updateDimensions = function ( transition ) {
                this.$element.removeClass( 'oo-ui-popupWidget-transitioning' );
        }
 
+       // Reevaluate clipping state since we've relocated and resized the popup
+       this.clip();
+
        return this;
 };
 
index aafdff3..9f4c035 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (f2c3f12959)
+ * OOjs UI v0.1.0-pre (880100c45e)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: 2014-09-18T23:22:20Z
+ * Date: 2014-09-23T22:28:43Z
  */
 /*
  * Blank theme mixins.
index 51b3238..e5c85df 100644 (file)
                                ajaxOptions = undefined;
                        }
 
-                       return api.getToken( tokenType ).then( function ( token ) {
+                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
                                params.token = token;
                                return api.post( params, ajaxOptions ).then(
                                        // If no error, return to caller as-is
                                                                params.token = undefined;
 
                                                        // Try again, once
-                                                       return api.getToken( tokenType ).then( function ( token ) {
+                                                       return api.getToken( tokenType, params.assert ).then( function ( token ) {
                                                                params.token = token;
                                                                return api.post( params, ajaxOptions );
                                                        } );
                /**
                 * Get a token for a certain action from the API.
                 *
+                * The assert parameter is only for internal use by postWithToken.
+                *
                 * @param {string} type Token type
                 * @return {jQuery.Promise}
                 * @return {Function} return.done
                 * @return {string} return.done.token Received token.
                 * @since 1.22
                 */
-               getToken: function ( type ) {
+               getToken: function ( type, assert ) {
                        var apiPromise,
                                promiseGroup = promises[ this.defaults.ajax.url ],
                                d = promiseGroup && promiseGroup[ type + 'Token' ];
 
                        if ( !d ) {
-                               apiPromise = this.get( { action: 'tokens', type: type } );
+                               apiPromise = this.get( { action: 'tokens', type: type, assert: assert } );
 
                                d = apiPromise
                                        .then( function ( data ) {
index c360e1f..4a87b74 100644 (file)
        background-image: e('/* @embed */') url(@url);
 }
 
+.background-size(@width, @height) {
+       // Vendor prefix for certain older opera browsers e.g. nintendo ds
+       -o-background-size: @width @height;
+       // Vendor prefix is added to support Android 2
+       -webkit-background-size: @width @height;
+       background-size: @width @height;
+}
+
+
 .vertical-gradient(@startColor: gray, @endColor: white, @startPos: 0, @endPos: 100%) {
        background-color: @endColor;
        background-image: -moz-linear-gradient( top, @startColor @startPos, @endColor @endPos ); // Firefox 3.6+
index e39646b..1997c1b 100644 (file)
@@ -23,7 +23,7 @@
        vertical-align: middle;
 }
 
-@checkboxSize: 24px;
+@checkboxSize: 1.6em;
 
 // We use the not selector to cancel out styling on IE 8 and below
 .mw-ui-checkbox:not(#noop) {
@@ -46,6 +46,7 @@
                // the pseudo before element of the label after the checkbox now looks like a checkbox
                & + label {
                        cursor: pointer;
+                       margin: 0 .4em;
 
                        &::before {
                                                content: '';
@@ -66,6 +67,7 @@
                        + label {
                                &::before {
                                        .background-image-svg('images/checked.svg', 'images/checked.png');
+                                       .background-size( @checkboxSize, @checkboxSize );
                                        background-repeat: no-repeat;
                                        background-position: center top;
                                }
index 078d8f0..2ee805e 100644 (file)
@@ -2207,13 +2207,6 @@ Log in
 &lt;/td&gt;&lt;td&gt;
 <template lineStart="1"><title>int:Login</title></template>
 &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
-[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginend&amp;action=edit loginend]&lt;br&gt;
-[[MediaWiki_talk:Loginend|Talk]]
-&lt;/td&gt;&lt;td&gt;
-&amp;amp;nbsp;
-&lt;/td&gt;&lt;td&gt;
-<template lineStart="1"><title>int:Loginend</title></template>
-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
 [http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginerror&amp;action=edit loginerror]&lt;br&gt;
 [[MediaWiki_talk:Loginerror|Talk]]
 &lt;/td&gt;&lt;td&gt;
index 3c30da9..4a30f56 100644 (file)
@@ -2207,13 +2207,6 @@ Log in
 </td><td>
 {{int:Login}}
 </td></tr><tr><td>
-[http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginend&action=edit loginend]<br>
-[[MediaWiki_talk:Loginend|Talk]]
-</td><td>
-&amp;nbsp;
-</td><td>
-{{int:Loginend}}
-</td></tr><tr><td>
 [http://tl.wiktionary.org/w/wiki.phtml?title=MediaWiki:Loginerror&action=edit loginerror]<br>
 [[MediaWiki_talk:Loginerror|Talk]]
 </td><td>
index 9965c43..5d21319 100644 (file)
@@ -70,10 +70,6 @@ if ( $wgDBtype == 'sqlite' ) {
        }
 }
 
-# There is a convention that the parser should never
-# refer to $wgTitle directly, but instead use the title
-# passed to it.
-$wgTitle = Title::newFromText( 'Parser test script do not use' );
 $tester = new ParserTest( $options );
 
 if ( isset( $options['file'] ) ) {
index 995853e..4abb4e5 100644 (file)
@@ -428,6 +428,34 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                return false;
        }
 
+       /**
+        * Insert a new page.
+        *
+        * Should be called from addDBData().
+        *
+        * @since 1.25
+        * @param string $pageName Page name
+        * @param string $text Page's content
+        * @return array Title object and page id
+        */
+       protected function insertPage( $pageName, $text = 'Sample page for unit test.' ) {
+               $title = Title::newFromText( $pageName, 0 );
+
+               $user = User::newFromName( 'WikiSysop' );
+               $comment = __METHOD__ . ': Sample page for unit test.';
+
+               // Avoid memory leak...?
+               LinkCache::singleton()->clear();
+
+               $page = WikiPage::factory( $title );
+               $page->doEditContent( ContentHandler::makeContent( $text, $title ), $comment, 0, false, $user );
+
+               return array(
+                       'title' => $title,
+                       'id' => $page->getId(),
+               );
+       }
+
        /**
         * Stub. If a test needs to add additional data to the database, it should
         * implement this method and do so
@@ -464,7 +492,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                User::resetIdByNameCache();
 
-               //Make sysop user
+               // Make sysop user
                $user = User::newFromName( 'UTSysop' );
 
                if ( $user->idForName() == 0 ) {
@@ -476,7 +504,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                        $user->saveSettings();
                }
 
-               //Make 1 page with 1 revision
+               // Make 1 page with 1 revision
                $page = WikiPage::factory( Title::newFromText( 'UTPage' ) );
                if ( $page->getId() == 0 ) {
                        $page->doEditContent(
@@ -484,7 +512,8 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                                'UTPageSummary',
                                EDIT_NEW,
                                false,
-                               User::newFromName( 'UTSysop' ) );
+                               User::newFromName( 'UTSysop' )
+                       );
                }
        }
 
index e7454af..b78780a 100644 (file)
@@ -1,3 +1,4 @@
+/* @noflip */
 .unit-tests {
   color: green;
   border: 2px solid #eeeeee;
index 9b53381..59ffb90 100644 (file)
@@ -1,6 +1,7 @@
 <?php
+
 /**
- * @group Broken
+ * @group Http
  */
 class HttpTest extends MediaWikiTestCase {
        /**
@@ -92,8 +93,10 @@ class HttpTest extends MediaWikiTestCase {
                        array( true, 'http://user:pass@host', 'Username and password provided' ),
 
                        # (\S+) - host part is made of anything not whitespaces
-                       array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ),
-                       array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ),
+                       // commented these out in order to remove @group Broken
+                       // @todo are these valid tests? if so, fix Http::isValidURI so it can handle them
+                       //array( false, 'http://!"èèè¿¿¿~~\'', 'hostname is made of any non whitespace' ),
+                       //array( false, 'http://exam:ple.org/', 'hostname can not use colons!' ),
 
                        # (:[0-9]+)? - port number
                        array( true, 'http://example.org:80/' ),
@@ -171,6 +174,298 @@ class HttpTest extends MediaWikiTestCase {
                        $h->getFinalUrl( "Relative file path Location: should keep the latest host and scheme!" )
                );
        }
+
+       /**
+        * Constant values are from PHP 5.3.28 using cURL 7.24.0
+        * @see http://php.net/manual/en/curl.constants.php
+        *
+        * @covers CurlHttpRequest::execute
+        */
+       public function provideCurlConstants() {
+               return array(
+                       array( 'CURLAUTH_ANY' ),
+                       array( 'CURLAUTH_ANYSAFE' ),
+                       array( 'CURLAUTH_BASIC' ),
+                       array( 'CURLAUTH_DIGEST' ),
+                       array( 'CURLAUTH_GSSNEGOTIATE' ),
+                       array( 'CURLAUTH_NTLM' ),
+                       array( 'CURLCLOSEPOLICY_CALLBACK' ),
+                       array( 'CURLCLOSEPOLICY_LEAST_RECENTLY_USED' ),
+                       array( 'CURLCLOSEPOLICY_LEAST_TRAFFIC' ),
+                       array( 'CURLCLOSEPOLICY_OLDEST' ),
+                       array( 'CURLCLOSEPOLICY_SLOWEST' ),
+                       array( 'CURLE_ABORTED_BY_CALLBACK' ),
+                       array( 'CURLE_BAD_CALLING_ORDER' ),
+                       array( 'CURLE_BAD_CONTENT_ENCODING' ),
+                       array( 'CURLE_BAD_FUNCTION_ARGUMENT' ),
+                       array( 'CURLE_BAD_PASSWORD_ENTERED' ),
+                       array( 'CURLE_COULDNT_CONNECT' ),
+                       array( 'CURLE_COULDNT_RESOLVE_HOST' ),
+                       array( 'CURLE_COULDNT_RESOLVE_PROXY' ),
+                       array( 'CURLE_FAILED_INIT' ),
+                       array( 'CURLE_FILESIZE_EXCEEDED' ),
+                       array( 'CURLE_FILE_COULDNT_READ_FILE' ),
+                       array( 'CURLE_FTP_ACCESS_DENIED' ),
+                       array( 'CURLE_FTP_BAD_DOWNLOAD_RESUME' ),
+                       array( 'CURLE_FTP_CANT_GET_HOST' ),
+                       array( 'CURLE_FTP_CANT_RECONNECT' ),
+                       array( 'CURLE_FTP_COULDNT_GET_SIZE' ),
+                       array( 'CURLE_FTP_COULDNT_RETR_FILE' ),
+                       array( 'CURLE_FTP_COULDNT_SET_ASCII' ),
+                       array( 'CURLE_FTP_COULDNT_SET_BINARY' ),
+                       array( 'CURLE_FTP_COULDNT_STOR_FILE' ),
+                       array( 'CURLE_FTP_COULDNT_USE_REST' ),
+                       array( 'CURLE_FTP_PORT_FAILED' ),
+                       array( 'CURLE_FTP_QUOTE_ERROR' ),
+                       array( 'CURLE_FTP_SSL_FAILED' ),
+                       array( 'CURLE_FTP_USER_PASSWORD_INCORRECT' ),
+                       array( 'CURLE_FTP_WEIRD_227_FORMAT' ),
+                       array( 'CURLE_FTP_WEIRD_PASS_REPLY' ),
+                       array( 'CURLE_FTP_WEIRD_PASV_REPLY' ),
+                       array( 'CURLE_FTP_WEIRD_SERVER_REPLY' ),
+                       array( 'CURLE_FTP_WEIRD_USER_REPLY' ),
+                       array( 'CURLE_FTP_WRITE_ERROR' ),
+                       array( 'CURLE_FUNCTION_NOT_FOUND' ),
+                       array( 'CURLE_GOT_NOTHING' ),
+                       array( 'CURLE_HTTP_NOT_FOUND' ),
+                       array( 'CURLE_HTTP_PORT_FAILED' ),
+                       array( 'CURLE_HTTP_POST_ERROR' ),
+                       array( 'CURLE_HTTP_RANGE_ERROR' ),
+                       array( 'CURLE_LDAP_CANNOT_BIND' ),
+                       array( 'CURLE_LDAP_INVALID_URL' ),
+                       array( 'CURLE_LDAP_SEARCH_FAILED' ),
+                       array( 'CURLE_LIBRARY_NOT_FOUND' ),
+                       array( 'CURLE_MALFORMAT_USER' ),
+                       array( 'CURLE_OBSOLETE' ),
+                       array( 'CURLE_OK' ),
+                       array( 'CURLE_OPERATION_TIMEOUTED' ),
+                       array( 'CURLE_OUT_OF_MEMORY' ),
+                       array( 'CURLE_PARTIAL_FILE' ),
+                       array( 'CURLE_READ_ERROR' ),
+                       array( 'CURLE_RECV_ERROR' ),
+                       array( 'CURLE_SEND_ERROR' ),
+                       array( 'CURLE_SHARE_IN_USE' ),
+                       array( 'CURLE_SSH' ),
+                       array( 'CURLE_SSL_CACERT' ),
+                       array( 'CURLE_SSL_CERTPROBLEM' ),
+                       array( 'CURLE_SSL_CIPHER' ),
+                       array( 'CURLE_SSL_CONNECT_ERROR' ),
+                       array( 'CURLE_SSL_ENGINE_NOTFOUND' ),
+                       array( 'CURLE_SSL_ENGINE_SETFAILED' ),
+                       array( 'CURLE_SSL_PEER_CERTIFICATE' ),
+                       array( 'CURLE_TELNET_OPTION_SYNTAX' ),
+                       array( 'CURLE_TOO_MANY_REDIRECTS' ),
+                       array( 'CURLE_UNKNOWN_TELNET_OPTION' ),
+                       array( 'CURLE_UNSUPPORTED_PROTOCOL' ),
+                       array( 'CURLE_URL_MALFORMAT' ),
+                       array( 'CURLE_URL_MALFORMAT_USER' ),
+                       array( 'CURLE_WRITE_ERROR' ),
+                       array( 'CURLFTPAUTH_DEFAULT' ),
+                       array( 'CURLFTPAUTH_SSL' ),
+                       array( 'CURLFTPAUTH_TLS' ),
+                       array( 'CURLFTPMETHOD_MULTICWD' ),
+                       array( 'CURLFTPMETHOD_NOCWD' ),
+                       array( 'CURLFTPMETHOD_SINGLECWD' ),
+                       array( 'CURLFTPSSL_ALL' ),
+                       array( 'CURLFTPSSL_CONTROL' ),
+                       array( 'CURLFTPSSL_NONE' ),
+                       array( 'CURLFTPSSL_TRY' ),
+                       array( 'CURLINFO_CERTINFO' ),
+                       array( 'CURLINFO_CONNECT_TIME' ),
+                       array( 'CURLINFO_CONTENT_LENGTH_DOWNLOAD' ),
+                       array( 'CURLINFO_CONTENT_LENGTH_UPLOAD' ),
+                       array( 'CURLINFO_CONTENT_TYPE' ),
+                       array( 'CURLINFO_EFFECTIVE_URL' ),
+                       array( 'CURLINFO_FILETIME' ),
+                       array( 'CURLINFO_HEADER_OUT' ),
+                       array( 'CURLINFO_HEADER_SIZE' ),
+                       array( 'CURLINFO_HTTP_CODE' ),
+                       array( 'CURLINFO_NAMELOOKUP_TIME' ),
+                       array( 'CURLINFO_PRETRANSFER_TIME' ),
+                       array( 'CURLINFO_PRIVATE' ),
+                       array( 'CURLINFO_REDIRECT_COUNT' ),
+                       array( 'CURLINFO_REDIRECT_TIME' ),
+                       array( 'CURLINFO_REDIRECT_URL' ),
+                       array( 'CURLINFO_REQUEST_SIZE' ),
+                       array( 'CURLINFO_SIZE_DOWNLOAD' ),
+                       array( 'CURLINFO_SIZE_UPLOAD' ),
+                       array( 'CURLINFO_SPEED_DOWNLOAD' ),
+                       array( 'CURLINFO_SPEED_UPLOAD' ),
+                       array( 'CURLINFO_SSL_VERIFYRESULT' ),
+                       array( 'CURLINFO_STARTTRANSFER_TIME' ),
+                       array( 'CURLINFO_TOTAL_TIME' ),
+                       array( 'CURLMSG_DONE' ),
+                       array( 'CURLM_BAD_EASY_HANDLE' ),
+                       array( 'CURLM_BAD_HANDLE' ),
+                       array( 'CURLM_CALL_MULTI_PERFORM' ),
+                       array( 'CURLM_INTERNAL_ERROR' ),
+                       array( 'CURLM_OK' ),
+                       array( 'CURLM_OUT_OF_MEMORY' ),
+                       array( 'CURLOPT_AUTOREFERER' ),
+                       array( 'CURLOPT_BINARYTRANSFER' ),
+                       array( 'CURLOPT_BUFFERSIZE' ),
+                       array( 'CURLOPT_CAINFO' ),
+                       array( 'CURLOPT_CAPATH' ),
+                       array( 'CURLOPT_CERTINFO' ),
+                       array( 'CURLOPT_CLOSEPOLICY' ),
+                       array( 'CURLOPT_CONNECTTIMEOUT' ),
+                       array( 'CURLOPT_CONNECTTIMEOUT_MS' ),
+                       array( 'CURLOPT_COOKIE' ),
+                       array( 'CURLOPT_COOKIEFILE' ),
+                       array( 'CURLOPT_COOKIEJAR' ),
+                       array( 'CURLOPT_COOKIESESSION' ),
+                       array( 'CURLOPT_CRLF' ),
+                       array( 'CURLOPT_CUSTOMREQUEST' ),
+                       array( 'CURLOPT_DNS_CACHE_TIMEOUT' ),
+                       array( 'CURLOPT_DNS_USE_GLOBAL_CACHE' ),
+                       array( 'CURLOPT_EGDSOCKET' ),
+                       array( 'CURLOPT_ENCODING' ),
+                       array( 'CURLOPT_FAILONERROR' ),
+                       array( 'CURLOPT_FILE' ),
+                       array( 'CURLOPT_FILETIME' ),
+                       array( 'CURLOPT_FOLLOWLOCATION' ),
+                       array( 'CURLOPT_FORBID_REUSE' ),
+                       array( 'CURLOPT_FRESH_CONNECT' ),
+                       array( 'CURLOPT_FTPAPPEND' ),
+                       array( 'CURLOPT_FTPLISTONLY' ),
+                       array( 'CURLOPT_FTPPORT' ),
+                       array( 'CURLOPT_FTPSSLAUTH' ),
+                       array( 'CURLOPT_FTP_CREATE_MISSING_DIRS' ),
+                       array( 'CURLOPT_FTP_FILEMETHOD' ),
+                       array( 'CURLOPT_FTP_SKIP_PASV_IP' ),
+                       array( 'CURLOPT_FTP_SSL' ),
+                       array( 'CURLOPT_FTP_USE_EPRT' ),
+                       array( 'CURLOPT_FTP_USE_EPSV' ),
+                       array( 'CURLOPT_HEADER' ),
+                       array( 'CURLOPT_HEADERFUNCTION' ),
+                       array( 'CURLOPT_HTTP200ALIASES' ),
+                       array( 'CURLOPT_HTTPAUTH' ),
+                       array( 'CURLOPT_HTTPGET' ),
+                       array( 'CURLOPT_HTTPHEADER' ),
+                       array( 'CURLOPT_HTTPPROXYTUNNEL' ),
+                       array( 'CURLOPT_HTTP_VERSION' ),
+                       array( 'CURLOPT_INFILE' ),
+                       array( 'CURLOPT_INFILESIZE' ),
+                       array( 'CURLOPT_INTERFACE' ),
+                       array( 'CURLOPT_IPRESOLVE' ),
+                       array( 'CURLOPT_KEYPASSWD' ),
+                       array( 'CURLOPT_KRB4LEVEL' ),
+                       array( 'CURLOPT_LOW_SPEED_LIMIT' ),
+                       array( 'CURLOPT_LOW_SPEED_TIME' ),
+                       array( 'CURLOPT_MAXCONNECTS' ),
+                       array( 'CURLOPT_MAXREDIRS' ),
+                       array( 'CURLOPT_MAX_RECV_SPEED_LARGE' ),
+                       array( 'CURLOPT_MAX_SEND_SPEED_LARGE' ),
+                       array( 'CURLOPT_NETRC' ),
+                       array( 'CURLOPT_NOBODY' ),
+                       array( 'CURLOPT_NOPROGRESS' ),
+                       array( 'CURLOPT_NOSIGNAL' ),
+                       array( 'CURLOPT_PORT' ),
+                       array( 'CURLOPT_POST' ),
+                       array( 'CURLOPT_POSTFIELDS' ),
+                       array( 'CURLOPT_POSTQUOTE' ),
+                       array( 'CURLOPT_POSTREDIR' ),
+                       array( 'CURLOPT_PRIVATE' ),
+                       array( 'CURLOPT_PROGRESSFUNCTION' ),
+                       array( 'CURLOPT_PROTOCOLS' ),
+                       array( 'CURLOPT_PROXY' ),
+                       array( 'CURLOPT_PROXYAUTH' ),
+                       array( 'CURLOPT_PROXYPORT' ),
+                       array( 'CURLOPT_PROXYTYPE' ),
+                       array( 'CURLOPT_PROXYUSERPWD' ),
+                       array( 'CURLOPT_PUT' ),
+                       array( 'CURLOPT_QUOTE' ),
+                       array( 'CURLOPT_RANDOM_FILE' ),
+                       array( 'CURLOPT_RANGE' ),
+                       array( 'CURLOPT_READDATA' ),
+                       array( 'CURLOPT_READFUNCTION' ),
+                       array( 'CURLOPT_REDIR_PROTOCOLS' ),
+                       array( 'CURLOPT_REFERER' ),
+                       array( 'CURLOPT_RESUME_FROM' ),
+                       array( 'CURLOPT_RETURNTRANSFER' ),
+                       array( 'CURLOPT_SSH_AUTH_TYPES' ),
+                       array( 'CURLOPT_SSH_HOST_PUBLIC_KEY_MD5' ),
+                       array( 'CURLOPT_SSH_PRIVATE_KEYFILE' ),
+                       array( 'CURLOPT_SSH_PUBLIC_KEYFILE' ),
+                       array( 'CURLOPT_SSLCERT' ),
+                       array( 'CURLOPT_SSLCERTPASSWD' ),
+                       array( 'CURLOPT_SSLCERTTYPE' ),
+                       array( 'CURLOPT_SSLENGINE' ),
+                       array( 'CURLOPT_SSLENGINE_DEFAULT' ),
+                       array( 'CURLOPT_SSLKEY' ),
+                       array( 'CURLOPT_SSLKEYPASSWD' ),
+                       array( 'CURLOPT_SSLKEYTYPE' ),
+                       array( 'CURLOPT_SSLVERSION' ),
+                       array( 'CURLOPT_SSL_CIPHER_LIST' ),
+                       array( 'CURLOPT_SSL_VERIFYHOST' ),
+                       array( 'CURLOPT_SSL_VERIFYPEER' ),
+                       array( 'CURLOPT_STDERR' ),
+                       array( 'CURLOPT_TCP_NODELAY' ),
+                       array( 'CURLOPT_TIMECONDITION' ),
+                       array( 'CURLOPT_TIMEOUT' ),
+                       array( 'CURLOPT_TIMEOUT_MS' ),
+                       array( 'CURLOPT_TIMEVALUE' ),
+                       array( 'CURLOPT_TRANSFERTEXT' ),
+                       array( 'CURLOPT_UNRESTRICTED_AUTH' ),
+                       array( 'CURLOPT_UPLOAD' ),
+                       array( 'CURLOPT_URL' ),
+                       array( 'CURLOPT_USERAGENT' ),
+                       array( 'CURLOPT_USERPWD' ),
+                       array( 'CURLOPT_VERBOSE' ),
+                       array( 'CURLOPT_WRITEFUNCTION' ),
+                       array( 'CURLOPT_WRITEHEADER' ),
+                       array( 'CURLPROTO_ALL' ),
+                       array( 'CURLPROTO_DICT' ),
+                       array( 'CURLPROTO_FILE' ),
+                       array( 'CURLPROTO_FTP' ),
+                       array( 'CURLPROTO_FTPS' ),
+                       array( 'CURLPROTO_HTTP' ),
+                       array( 'CURLPROTO_HTTPS' ),
+                       array( 'CURLPROTO_LDAP' ),
+                       array( 'CURLPROTO_LDAPS' ),
+                       array( 'CURLPROTO_SCP' ),
+                       array( 'CURLPROTO_SFTP' ),
+                       array( 'CURLPROTO_TELNET' ),
+                       array( 'CURLPROTO_TFTP' ),
+                       array( 'CURLPROXY_HTTP' ),
+                       array( 'CURLPROXY_SOCKS4' ),
+                       array( 'CURLPROXY_SOCKS5' ),
+                       array( 'CURLSSH_AUTH_DEFAULT' ),
+                       array( 'CURLSSH_AUTH_HOST' ),
+                       array( 'CURLSSH_AUTH_KEYBOARD' ),
+                       array( 'CURLSSH_AUTH_NONE' ),
+                       array( 'CURLSSH_AUTH_PASSWORD' ),
+                       array( 'CURLSSH_AUTH_PUBLICKEY' ),
+                       array( 'CURLVERSION_NOW' ),
+                       array( 'CURL_HTTP_VERSION_1_0' ),
+                       array( 'CURL_HTTP_VERSION_1_1' ),
+                       array( 'CURL_HTTP_VERSION_NONE' ),
+                       array( 'CURL_IPRESOLVE_V4' ),
+                       array( 'CURL_IPRESOLVE_V6' ),
+                       array( 'CURL_IPRESOLVE_WHATEVER' ),
+                       array( 'CURL_NETRC_IGNORED' ),
+                       array( 'CURL_NETRC_OPTIONAL' ),
+                       array( 'CURL_NETRC_REQUIRED' ),
+                       array( 'CURL_TIMECOND_IFMODSINCE' ),
+                       array( 'CURL_TIMECOND_IFUNMODSINCE' ),
+                       array( 'CURL_TIMECOND_LASTMOD' ),
+                       array( 'CURL_VERSION_IPV6' ),
+                       array( 'CURL_VERSION_KERBEROS4' ),
+                       array( 'CURL_VERSION_LIBZ' ),
+                       array( 'CURL_VERSION_SSL' ),
+               );
+       }
+
+       /**
+        * Added this test based on an issue experienced with hhvm where it did
+        * not define a cURL constant.
+        *
+        * @bug 70570
+        * @dataProvider provideCurlConstants
+        */
+       public function testCurlConstants( $value ) {
+               $this->assertTrue( defined( $value ), $value . ' not defined' );
+       }
 }
 
 /**
index f3d2a84..47560e6 100644 (file)
@@ -109,9 +109,15 @@ class MessageTest extends MediaWikiLangTestCase {
                $this->assertInstanceOf( 'Message', wfMessage( 'mainpage' ) );
                $this->assertInstanceOf( 'Message', wfMessage( 'i-dont-exist-evar' ) );
                $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() );
-               $this->assertEquals( '&lt;i-dont-exist-evar&gt;', wfMessage( 'i-dont-exist-evar' )->text() );
+               $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->text() );
+               $this->assertEquals( '<i<dont>exist-evar>', wfMessage( 'i<dont>exist-evar' )->text() );
                $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->plain() );
+               $this->assertEquals( '<i<dont>exist-evar>', wfMessage( 'i<dont>exist-evar' )->plain() );
                $this->assertEquals( '&lt;i-dont-exist-evar&gt;', wfMessage( 'i-dont-exist-evar' )->escaped() );
+               $this->assertEquals(
+                       '&lt;i&lt;dont&gt;exist-evar&gt;',
+                       wfMessage( 'i<dont>exist-evar' )->escaped()
+               );
        }
 
        /**
diff --git a/tests/phpunit/includes/MovePageTest.php b/tests/phpunit/includes/MovePageTest.php
new file mode 100644 (file)
index 0000000..027b877
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+class MovePageTest extends MediaWikiTestCase {
+
+       /**
+        * @dataProvider provideIsValidMove
+        * @covers MovePage::isValidMove
+        * @covers MovePage::isValidFileMove
+        */
+       public function testIsValidMove( $old, $new, $error ) {
+               $this->setMwGlobals( 'wgContentHandlerUseDB', false );
+               $mp = new MovePage(
+                       Title::newFromText( $old ),
+                       Title::newFromText( $new )
+               );
+               $status = $mp->isValidMove();
+               if ( $error === true ) {
+                       $this->assertTrue( $status->isGood() );
+               } else {
+                       $this->assertTrue( $status->hasMessage( $error ) );
+               }
+       }
+
+       /**
+        * This should be kept in sync with TitleTest::provideTestIsValidMoveOperation
+        */
+       public static function provideIsValidMove() {
+               return array(
+                       // for MovePage::isValidMove
+                       array( 'Test', 'Test', 'selfmove' ),
+                       array( 'Special:FooBar', 'Test', 'immobile-source-namespace' ),
+                       array( 'Test', 'Special:FooBar', 'immobile-target-namespace' ),
+                       array( 'MediaWiki:Common.js', 'Help:Some wikitext page', 'bad-target-model' ),
+                       array( 'Page', 'File:Test.jpg', 'nonfile-cannot-move-to-file' ),
+                       // for MovePage::isValidFileMove
+                       array( 'File:Test.jpg', 'Page', 'imagenocrossnamespace' ),
+               );
+       }
+}
diff --git a/tests/phpunit/includes/jobqueue/JobTest.php b/tests/phpunit/includes/jobqueue/JobTest.php
new file mode 100644 (file)
index 0000000..93069d2
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @author Adam Shorland
+ */
+class JobTest extends MediaWikiTestCase {
+
+       /**
+        * @dataProvider provideTestToString
+        *
+        * @param Job $job
+        * @param string $expected
+        *
+        * @covers Job::toString
+        */
+       public function testToString( $job, $expected ) {
+               $this->assertEquals( $expected, $job->toString() );
+       }
+
+       public function provideTestToString() {
+               $mockToStringObj = $this->getMock( 'stdClass', array( '__toString' ) );
+               $mockToStringObj->expects( $this->any() )
+                       ->method( '__toString' )
+                       ->will( $this->returnValue( '{STRING_OBJ_VAL}' ) );
+
+               return array(
+                       array(
+                               $this->getMockJob( false ),
+                               'someCommand '
+                       ),
+                       array(
+                               $this->getMockJob( array( 'key' => 'val' ) ),
+                               'someCommand  key=val'
+                       ),
+                       array(
+                               $this->getMockJob( array( 'key' => array( 'inkey' => 'inval' ) ) ),
+                               'someCommand  key={"inkey":"inval"}'
+                       ),
+                       array(
+                               $this->getMockJob( array( 'val1' ) ),
+                               'someCommand  0=val1'
+                       ),
+                       array(
+                               $this->getMockJob( array( 'val1', 'val2' ) ),
+                               'someCommand  0=val1 1=val2'
+                       ),
+                       array(
+                               $this->getMockJob( array( new stdClass() ) ),
+                               'someCommand  0=object(stdClass)'
+                       ),
+                       array(
+                               $this->getMockJob( array( $mockToStringObj ) ),
+                               'someCommand  0={STRING_OBJ_VAL}'
+                       ),
+               );
+       }
+
+       public function getMockJob( $params ) {
+               $mock = $this->getMockForAbstractClass(
+                       'Job',
+                       array( 'someCommand', new Title(), $params ),
+                       'SomeJob'
+               );
+               return $mock;
+       }
+
+}
index e4283b0..8d0224c 100644 (file)
@@ -15,27 +15,15 @@ class CSSJanusTest extends MediaWikiTestCase {
 
                if ( $cssB ) {
                        $transformedA = CSSJanus::transform( $cssA );
-                       $this->assertEquals(
-                               $transformedA,
-                               str_replace( '/* @noflip */ ', '', $cssB ),
-                               'Test A-B transformation'
-                       );
+                       $this->assertEquals( $transformedA, $cssB, 'Test A-B transformation' );
 
                        $transformedB = CSSJanus::transform( $cssB );
-                       $this->assertEquals(
-                               $transformedB,
-                               str_replace( '/* @noflip */ ', '', $cssA ),
-                               'Test B-A transformation'
-                       );
+                       $this->assertEquals( $transformedB, $cssA, 'Test B-A transformation' );
                } else {
                        // If no B version is provided, it means
                        // the output should equal the input (modulo @noflip annotations).
                        $transformedA = CSSJanus::transform( $cssA );
-                       $this->assertEquals(
-                               $transformedA,
-                               str_replace( '/* @noflip */ ', '', $cssA ),
-                               'Nothing was flipped'
-                       );
+                       $this->assertEquals( $transformedA, $cssA, 'Nothing was flipped' );
                }
        }
 
index 2b4d60d..43c5086 100644 (file)
@@ -202,6 +202,11 @@ class CSSMinTest extends MediaWikiTestCase {
                                'foo { /* @embed */ background: url(red.gif); }',
                                "foo { background: url($red); background: url(http://localhost/w/red.gif?timestamp)!ie; }",
                        ),
+                       array(
+                               'Embedded file, other comments before the rule',
+                               "foo { /* Bar. */ /* @embed */ background: url(red.gif); }",
+                               "foo { /* Bar. */ background: url($red); /* Bar. */ background: url(http://localhost/w/red.gif?timestamp)!ie; }",
+                       ),
                        array(
                                'Can not re-embed data: URIs',
                                "foo { /* @embed */ background: url($red); }",
index d2e118c..7664d5b 100644 (file)
@@ -90,6 +90,15 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                $this->assertStringEqualsFile( $basePath . '/styles.css', $styles['all'] );
        }
 
+       /**
+        * Strip @noflip annotations from CSS code.
+        * @param string $css
+        * @return string
+        */
+       private function stripNoflip( $css ) {
+               return str_replace( '/*@noflip*/ ', '', $css );
+       }
+
        /**
         * What happens when you mix @embed and @noflip?
         * This really is an integration test, but oh well.
@@ -108,14 +117,16 @@ class ResourceLoaderTest extends ResourceLoaderTestCase {
                $contextLtr = self::getResourceLoaderContext( 'en' );
                $contextRtl = self::getResourceLoaderContext( 'he' );
 
+               // Since we want to compare the effect of @noflip+@embed against the effect of just @embed, and
+               // the @noflip annotations are always preserved, we need to strip them first.
                $this->assertEquals(
                        $expectedModule->getStyles( $contextLtr ),
-                       $testModule->getStyles( $contextLtr ),
+                       $this->stripNoflip( $testModule->getStyles( $contextLtr ) ),
                        "/*@noflip*/ with /*@embed*/ gives correct results in LTR mode"
                );
                $this->assertEquals(
                        $expectedModule->getStyles( $contextLtr ),
-                       $testModule->getStyles( $contextRtl ),
+                       $this->stripNoflip( $testModule->getStyles( $contextRtl ) ),
                        "/*@noflip*/ with /*@embed*/ gives correct results in RTL mode"
                );
        }
index 3da1361..d0cbfa0 100644 (file)
@@ -14,8 +14,6 @@ class SearchEngineTest extends MediaWikiLangTestCase {
         */
        protected $search;
 
-       protected $pageList;
-
        /**
         * Checks for database type & version.
         * Will skip current test if DB does not support search.
@@ -37,10 +35,6 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                        'wgSearchType' => $searchType
                ) );
 
-               if ( !isset( self::$pageList ) ) {
-                       $this->addPages();
-               }
-
                $this->search = new $searchType( $this->db );
        }
 
@@ -50,33 +44,32 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                parent::tearDown();
        }
 
-       protected function addPages() {
+       public function addDBData() {
                if ( !$this->isWikitextNS( NS_MAIN ) ) {
                        // @todo cover the case of non-wikitext content in the main namespace
                        return;
                }
 
-               $this->insertPage( "Not_Main_Page", "This is not a main page", 0 );
+               $this->insertPage( 'Not_Main_Page', 'This is not a main page' );
                $this->insertPage(
                        'Talk:Not_Main_Page',
-                       'This is not a talk page to the main page, see [[smithee]]',
-                       1
+                       'This is not a talk page to the main page, see [[smithee]]'
                );
-               $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 );
-               $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 );
-               $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 );
-               $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 );
-               $this->insertPage( 'Help:Help', 'Help me!', 4 );
-               $this->insertPage( 'Thppt', 'Blah blah', 0 );
-               $this->insertPage( 'Alan_Smithee', 'yum', 0 );
-               $this->insertPage( 'Pages', 'are\'food', 0 );
-               $this->insertPage( 'HalfOneUp', 'AZ', 0 );
-               $this->insertPage( 'FullOneUp', 'AZ', 0 );
-               $this->insertPage( 'HalfTwoLow', 'az', 0 );
-               $this->insertPage( 'FullTwoLow', 'az', 0 );
-               $this->insertPage( 'HalfNumbers', '1234567890', 0 );
-               $this->insertPage( 'FullNumbers', '1234567890', 0 );
-               $this->insertPage( 'DomainName', 'example.com', 0 );
+               $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]' );
+               $this->insertPage( 'Talk:Smithee', 'This article sucks.' );
+               $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.' );
+               $this->insertPage( 'Another_page', 'This page also is unrelated.' );
+               $this->insertPage( 'Help:Help', 'Help me!' );
+               $this->insertPage( 'Thppt', 'Blah blah' );
+               $this->insertPage( 'Alan_Smithee', 'yum' );
+               $this->insertPage( 'Pages', 'are\'food' );
+               $this->insertPage( 'HalfOneUp', 'AZ' );
+               $this->insertPage( 'FullOneUp', 'AZ' );
+               $this->insertPage( 'HalfTwoLow', 'az' );
+               $this->insertPage( 'FullTwoLow', 'az' );
+               $this->insertPage( 'HalfNumbers', '1234567890' );
+               $this->insertPage( 'FullNumbers', '1234567890' );
+               $this->insertPage( 'DomainName', 'example.com' );
        }
 
        protected function fetchIds( $results ) {
@@ -101,30 +94,6 @@ class SearchEngineTest extends MediaWikiLangTestCase {
                return $matches;
        }
 
-       /**
-        * Insert a new page
-        *
-        * @param string $pageName Page name
-        * @param string $text Page's content
-        * @param int $ns Unused
-        */
-       protected function insertPage( $pageName, $text, $ns ) {
-               $title = Title::newFromText( $pageName, $ns );
-
-               $user = User::newFromName( 'WikiSysop' );
-               $comment = 'Search Test';
-
-               // avoid memory leak...?
-               LinkCache::singleton()->clear();
-
-               $page = WikiPage::factory( $title );
-               $page->doEditContent( ContentHandler::makeContent( $text, $title ), $comment, 0, false, $user );
-
-               $this->pageList[] = array( $title, $page->getId() );
-
-               return true;
-       }
-
        public function testFullWidth() {
                $this->assertEquals(
                        array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ),
index 4f17601..41d8dee 100644 (file)
@@ -129,6 +129,230 @@ class UploadBaseTest extends MediaWikiTestCase {
 
                $wgMaxUploadSize = $savedGlobal; // restore global
        }
+
+
+       /**
+        * @dataProvider provideCheckSvgScriptCallback
+        */
+       public function testCheckSvgScriptCallback( $svg, $wellFormed, $filterMatch, $message ) {
+               list( $formed, $match ) = $this->upload->checkSvgString( $svg );
+               $this->assertSame( $wellFormed, $formed, $message );
+               $this->assertSame( $filterMatch, $match, $message );
+       }
+
+       public static function provideCheckSvgScriptCallback() {
+               return array(
+                       // html5sec SVG vectors
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"><script>alert(1)</script></svg>',
+                               true,
+                               true,
+                               'Script tag in svg (http://html5sec.org/#47)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"><g onload="javascript:alert(1)"></g></svg>',
+                               true,
+                               true,
+                               'SVG with onload property (http://html5sec.org/#11)'
+                       ),
+                       array(
+                               '<svg onload="javascript:alert(1)" xmlns="http://www.w3.org/2000/svg"></svg>',
+                               true,
+                               true,
+                               'SVG with onload property (http://html5sec.org/#65)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="javascript:alert(1)"><rect width="1000" height="1000" fill="white"/></a> </svg>',
+                               true,
+                               true,
+                               'SVG with javascript xlink (http://html5sec.org/#87)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">  <animation xlink:href="javascript:alert(1)"/> </svg>',
+                               true,
+                               true,
+                               'SVG with Opera animation xlink (http://html5sec.org/#88 - a)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">  <animation xlink:href="data:text/xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' onload=\'alert(1)\'%3E%3C/svg%3E"/> </svg>',
+                               true,
+                               true,
+                               'SVG with Opera animation xlink (http://html5sec.org/#88 - b)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">  <image xlink:href="data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' onload=\'alert(1)\'%3E%3C/svg%3E"/> </svg>',
+                               true,
+                               true,
+                               'SVG with Opera image xlink (http://html5sec.org/#88 - c)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">  <foreignObject xlink:href="javascript:alert(1)"/> </svg>',
+                               true,
+                               true,
+                               'SVG with Opera foreignObject xlink (http://html5sec.org/#88 - d)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">  <foreignObject xlink:href="data:text/xml,%3Cscript xmlns=\'http://www.w3.org/1999/xhtml\'%3Ealert(1)%3C/script%3E"/> </svg>',
+                               true,
+                               true,
+                               'SVG with Opera foreignObject xlink (http://html5sec.org/#88 - e)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <set attributeName="onmouseover" to="alert(1)"/> </svg>',
+                               true,
+                               true,
+                               'SVG with event handler set (http://html5sec.org/#89 - a)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <animate attributeName="onunload" to="alert(1)"/> </svg>',
+                               true,
+                               true,
+                               'SVG with event handler animate (http://html5sec.org/#89 - a)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <handler xmlns:ev="http://www.w3.org/2001/xml-events" ev:event="load">alert(1)</handler> </svg>',
+                               true,
+                               true,
+                               'SVG with element handler (http://html5sec.org/#94)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <feImage> <set attributeName="xlink:href" to="data:image/svg+xml;charset=utf-8;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxzY3JpcHQ%2BYWxlcnQoMSk8L3NjcmlwdD48L3N2Zz4NCg%3D%3D"/> </feImage> </svg>',
+                               true,
+                               true,
+                               'SVG with href to data: url (http://html5sec.org/#95)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" id="foo"> <x xmlns="http://www.w3.org/2001/xml-events" event="load" observer="foo" handler="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%3Chandler%20xml%3Aid%3D%22bar%22%20type%3D%22application%2Fecmascript%22%3E alert(1) %3C%2Fhandler%3E%0A%3C%2Fsvg%3E%0A#bar"/> </svg>',
+                               true,
+                               true,
+                               'SVG with Tiny handler (http://html5sec.org/#104)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <a id="x"><rect fill="white" width="1000" height="1000"/></a> <rect fill="white" style="clip-path:url(test3.svg#a);fill:url(#b);filter:url(#c);marker:url(#d);mask:url(#e);stroke:url(#f);"/> </svg>',
+                               true,
+                               true,
+                               'SVG with new CSS styles properties (http://html5sec.org/#109)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <a id="x"><rect fill="white" width="1000" height="1000"/></a> <rect clip-path="url(test3.svg#a)" /> </svg>',
+                               true,
+                               true,
+                               'SVG with new CSS styles properties as attributes'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <a id="x"> <rect fill="white" width="1000" height="1000"/> </a> <rect fill="url(http://html5sec.org/test3.svg#a)" /> </svg>',
+                               true,
+                               true,
+                               'SVG with new CSS styles properties as attributes (2)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <path d="M0,0" style="marker-start:url(test4.svg#a)"/> </svg>',
+                               true,
+                               true,
+                               'SVG with path marker-start (http://html5sec.org/#110)'
+                       ),
+                       array(
+                               '<?xml version="1.0"?> <?xml-stylesheet type="text/xml" href="#stylesheet"?> <!DOCTYPE doc [ <!ATTLIST xsl:stylesheet id ID #REQUIRED>]> <svg xmlns="http://www.w3.org/2000/svg"> <xsl:stylesheet id="stylesheet" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <iframe xmlns="http://www.w3.org/1999/xhtml" src="javascript:alert(1)"></iframe> </xsl:template> </xsl:stylesheet> <circle fill="red" r="40"></circle> </svg>',
+                               true,
+                               true,
+                               'SVG with embedded stylesheet (http://html5sec.org/#125)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" id="x"> <listener event="load" handler="#y" xmlns="http://www.w3.org/2001/xml-events" observer="x"/> <handler id="y">alert(1)</handler> </svg>',
+                               true,
+                               true,
+                               'SVG with handler attribute (http://html5sec.org/#127)'
+                       ),
+                       array(
+                               // Haven't found a browser that accepts this particular example, but we
+                               // don't want to allow embeded svgs, ever
+                               '<svg> <image style=\'filter:url("data:image/svg+xml;charset=utf-8;base64, PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxzY3JpcHQ/YWxlcnQoMSk8L3NjcmlwdD48L3N2Zz4NCg==")\' /> </svg>',
+                               true,
+                               true,
+                               'SVG with image filter via style (http://html5sec.org/#129)'
+                       ),
+                       array(
+                               // This doesn't seem possible without embedding the svg, but just in case
+                               '<svg> <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="?"> <circle r="400"></circle> <animate attributeName="xlink:href" begin="0" from="javascript:alert(1)" to="" /> </a></svg>',
+                               true,
+                               true,
+                               'SVG with animate from (http://html5sec.org/#137)'
+                       ),
+
+                       // Other hostile SVG's
+                       array(
+                               '<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg xmlns:xlink="http://www.w3.org/1999/xlink"> <image xlink:href="https://upload.wikimedia.org/wikipedia/commons/3/34/Bahnstrecke_Zeitz-Camburg_1930.png" /> </svg>',
+                               true,
+                               true,
+                               'SVG with non-local image href (bug 65839)'
+                       ),
+                       array(
+                               '<?xml version="1.0" ?> <?xml-stylesheet type="text/xsl" href="/w/index.php?title=User:Jeeves/test.xsl&amp;action=raw&amp;format=xml" ?> <svg> <height>50</height> <width>100</width> </svg>',
+                               true,
+                               true,
+                               'SVG with remote stylesheet (bug 57550)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" viewbox="-1 -1 15 15"> <rect y="0" height="13" width="12" stroke="#179" rx="1" fill="#2ac"/> <text x="1.5" y="11" font-family="courier" stroke="white" font-size="16"><![CDATA[B]]></text> <iframe xmlns="http://www.w3.org/1999/xhtml" srcdoc="&#x3C;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3E;&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x45;&#x44;&#x20;&#x3D;&#x3E;&#x20;&#x44;&#x6F;&#x6D;&#x61;&#x69;&#x6E;&#x28;&#x27;&#x2B;&#x74;&#x6F;&#x70;&#x2E;&#x64;&#x6F;&#x63;&#x75;&#x6D;&#x65;&#x6E;&#x74;&#x2E;&#x64;&#x6F;&#x6D;&#x61;&#x69;&#x6E;&#x2B;&#x27;&#x29;&#x27;&#x29;&#x3B;&#x3C;&#x2F;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3E;"></iframe> </svg>',
+                               true,
+                               true,
+                               'SVG with rembeded iframe (bug 60771)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" viewBox="6 3 177 153" xmlns:xlink="http://www.w3.org/1999/xlink"> <style>@import url("https://fonts.googleapis.com/css?family=Bitter:700&amp;text=WebPlatform.org");</style> <g transform="translate(-.5,-.5)"> <text fill="#474747" x="95" y="150" text-anchor="middle" font-family="Bitter" font-size="20" font-weight="bold">WebPlatform.org</text> </g> </svg>',
+                               true,
+                               true,
+                               'SVG with @import in style element (bug 69008)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" viewBox="6 3 177 153" xmlns:xlink="http://www.w3.org/1999/xlink"> <style>@import url("https://fonts.googleapis.com/css?family=Bitter:700&amp;text=WebPlatform.org");<foo/></style> <g transform="translate(-.5,-.5)"> <text fill="#474747" x="95" y="150" text-anchor="middle" font-family="Bitter" font-size="20" font-weight="bold">WebPlatform.org</text> </g> </svg>',
+                               true,
+                               true,
+                               'SVG with @import in style element and child element (bug 69008#c11)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <rect width="100" height="100" style="background-image:url(https://www.google.com/images/srpr/logo11w.png)"/> </svg>',
+                               true,
+                               true,
+                               'SVG with remote background image (bug 69008)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <rect width="100" height="100" style="background-image:\55rl(https://www.google.com/images/srpr/logo11w.png)"/> </svg>',
+                               true,
+                               true,
+                               'SVG with remote background image, encoded (bug 69008)'
+                       ),
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <style> #a { background-image:\55rl(\'https://www.google.com/images/srpr/logo11w.png\'); } </style> <rect width="100" height="100" id="a"/> </svg>',
+                               true,
+                               true,
+                               'SVG with remote background image, in style element (bug 69008)'
+                       ),
+                       array(
+                               // This currently doesn't seem to work in any browsers, but in case
+                               // http://www.w3.org/TR/css3-images/ is implemented for SVG files
+                               '<svg xmlns="http://www.w3.org/2000/svg"> <rect width="100" height="100" style="background-image:image(\'sprites.svg#xywh=40,0,20,20\')"/> </svg>',
+                               true,
+                               true,
+                               'SVG with remote background image using image() (bug 69008)'
+                       ),
+
+                       // Test good, but strange files that we want to allow
+                       array(
+                               '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <g> <a xlink:href="http://en.wikipedia.org/wiki/Main_Page"> <path transform="translate(0,496)" id="path6706" d="m 112.09375,107.6875 -5.0625,3.625 -4.3125,5.03125 -0.46875,0.5 -4.09375,3.34375 -9.125,5.28125 -8.625,-3.375 z" style="fill:#cccccc;fill-opacity:1;stroke:#6e6e6e;stroke-width:0.69999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;display:inline" /> </a> </g> </svg>',
+                               true,
+                               false,
+                               'SVG with <a> link to a remote site'
+                       ),
+                       array(
+                               '<svg> <defs> <filter id="filter6226" x="-0.93243687" width="2.8648737" y="-0.24250539" height="1.4850108"> <feGaussianBlur stdDeviation="3.2344681" id="feGaussianBlur6228" /> </filter> <clipPath id="clipPath2436"> <path d="M 0,0 L 0,0 L 0,0 L 0,0 z" id="path2438" /> </clipPath> </defs> <g clip-path="url(#clipPath2436)" id="g2460"> <text id="text2466"> <tspan>12345</tspan> </text> </g> <path style="fill:#346733;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:1, 1;stroke-dashoffset:0;filter:url(\'#filter6226\');fill-opacity:1;opacity:0.79807692" d="M 236.82371,332.63732 C 236.92217,332.63732 z" id="path5618" /> </svg>',
+                               true,
+                               false,
+                               'SVG with local urls, including filter: in style'
+                       ),
+
+               );
+       }
 }
 
 class UploadTestHandler extends UploadBase {
@@ -143,4 +367,19 @@ class UploadTestHandler extends UploadBase {
 
                return $this->mTitleError;
        }
+
+       /**
+        * Almost the same as UploadBase::detectScriptInSvg, except it's
+        * public, works on an xml string instead of filename, and returns
+        * the result instead of interpreting them.
+        */
+       public function checkSvgString( $svg ) {
+               $check = new XmlTypeCheck(
+                       $svg,
+                       array( $this, 'checkSvgScriptCallback' ),
+                       false,
+                       array( 'processing_instruction_handler' => 'UploadBase::checkSvgPICallback' )
+               );
+               return array( $check->wellFormed, $check->filterMatch );
+       }
 }
index f156c72..76fa6be 100644 (file)
                );
        } );
 
+       QUnit.test( 'postWithToken( tokenType, params with assert )', function ( assert ) {
+               QUnit.expect( 2 );
+
+               var api = new mw.Api( { ajax: { url: '/postWithToken/api.php' } } );
+
+               api.postWithToken( 'testasserttoken', { action: 'example', key: 'foo', assert: 'user' } )
+                       .fail( function ( errorCode ) {
+                               assert.equal( errorCode, 'assertuserfailed', 'getToken fails assert' );
+                       } );
+
+               assert.equal( this.server.requests.length, 1, 'Request for token made' );
+               this.server.respondWith( /assert=user/, function ( request ) {
+                       request.respond(
+                               200,
+                               { 'Content-Type': 'application/json' },
+                               '{ "error": { "code": "assertuserfailed", "info": "Assertion failed" } }'
+                       );
+               } );
+
+               this.server.respond();
+       } );
+
        QUnit.test( 'postWithToken( tokenType, params, ajaxOptions )', function ( assert ) {
                QUnit.expect( 3 );
 
index d8ed246..3d8612d 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -32,7 +32,7 @@ if ( defined( 'THUMB_HANDLER' ) ) {
        wfThumbHandle404();
 } else {
        // Called directly, use $_GET params
-       wfThumbHandleRequest();
+       wfStreamThumb( $_GET );
 }
 
 wfLogProfilingData();
@@ -43,19 +43,6 @@ $factory->shutdown();
 
 //--------------------------------------------------------------------------
 
-/**
- * Handle a thumbnail request via query parameters
- *
- * @return void
- */
-function wfThumbHandleRequest() {
-       $params = get_magic_quotes_gpc()
-               ? array_map( 'stripslashes', $_GET )
-               : $_GET;
-
-       wfStreamThumb( $params ); // stream the thumbnail
-}
-
 /**
  * Handle a thumbnail request via thumbnail file URL
  *