Merge "Removed READ_LATEST default from Revision::newFromTitle()."
authorDemon <chadh@wikimedia.org>
Mon, 15 Oct 2012 14:57:02 +0000 (14:57 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 15 Oct 2012 14:57:02 +0000 (14:57 +0000)
271 files changed:
.gitignore
RELEASE-NOTES-1.20
RELEASE-NOTES-1.21
docs/contenthandler.txt
docs/hooks.txt
includes/Article.php
includes/AutoLoader.php
includes/Cdb_PHP.php
includes/Collation.php
includes/CryptRand.php
includes/DefaultSettings.php
includes/Defines.php
includes/EditPage.php
includes/ExternalUser.php
includes/FeedUtils.php
includes/FormOptions.php
includes/Html.php
includes/Import.php
includes/Linker.php
includes/MessageBlobStore.php
includes/OutputHandler.php
includes/OutputPage.php
includes/Preferences.php
includes/ProtectionForm.php
includes/Revision.php
includes/SquidPurgeClient.php
includes/Status.php
includes/StringUtils.php
includes/Title.php
includes/User.php
includes/WebRequest.php
includes/WikiPage.php
includes/Xml.php
includes/actions/CreditsAction.php
includes/actions/HistoryAction.php
includes/actions/InfoAction.php
includes/actions/RawAction.php
includes/actions/RevertAction.php
includes/api/ApiDelete.php
includes/api/ApiMain.php
includes/api/ApiParse.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllCategories.php
includes/api/ApiQueryFilearchive.php
includes/api/ApiUpload.php
includes/cache/FileCacheBase.php
includes/cache/SquidUpdate.php
includes/conf/DatabaseConf.php
includes/content/ContentHandler.php
includes/content/TextContent.php
includes/content/WikitextContent.php
includes/context/ContextSource.php
includes/context/RequestContext.php
includes/db/CloneDatabase.php
includes/db/IORMTable.php
includes/db/ORMTable.php
includes/diff/DifferenceEngine.php
includes/filerepo/file/ArchivedFile.php
includes/filerepo/file/LocalFile.php
includes/installer/DatabaseUpdater.php
includes/installer/Ibm_db2Updater.php
includes/installer/MysqlUpdater.php
includes/installer/OracleInstaller.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/logging/LogEntry.php
includes/logging/LogPage.php
includes/media/MediaTransformOutput.php
includes/parser/DateFormatter.php
includes/parser/LinkHolderArray.php
includes/parser/ParserCache.php
includes/parser/ParserOptions.php
includes/parser/Parser_LinkHooks.php
includes/parser/Preprocessor_DOM.php
includes/parser/StripState.php
includes/site/MediaWikiSite.php [new file with mode: 0644]
includes/site/Site.php [new file with mode: 0644]
includes/site/SiteArray.php [new file with mode: 0644]
includes/site/SiteList.php [new file with mode: 0644]
includes/site/SiteObject.php [new file with mode: 0644]
includes/site/Sites.php [new file with mode: 0644]
includes/site/SitesTable.php [new file with mode: 0644]
includes/specials/SpecialBlockList.php
includes/specials/SpecialContributions.php
includes/specials/SpecialExport.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUndelete.php
includes/specials/SpecialUpload.php
includes/specials/SpecialUploadStash.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialWantedfiles.php
includes/specials/SpecialWantedpages.php
includes/upload/UploadFromFile.php
languages/Language.php
languages/LanguageConverter.php
languages/classes/LanguageGan.php
languages/classes/LanguageIu.php
languages/classes/LanguageKk.php
languages/classes/LanguageKu.php
languages/classes/LanguageShi.php
languages/classes/LanguageSr.php
languages/classes/LanguageUz.php
languages/classes/LanguageZh.php
languages/messages/MessagesArc.php
languages/messages/MessagesAst.php
languages/messages/MessagesAz.php
languages/messages/MessagesBs.php
languages/messages/MessagesCa.php
languages/messages/MessagesCkb.php
languages/messages/MessagesCs.php
languages/messages/MessagesDa.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesDsb.php
languages/messages/MessagesEn.php
languages/messages/MessagesEs.php
languages/messages/MessagesFa.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesGl.php
languages/messages/MessagesGsw.php
languages/messages/MessagesGu.php
languages/messages/MessagesHe.php
languages/messages/MessagesHif_latn.php
languages/messages/MessagesHsb.php
languages/messages/MessagesHu.php
languages/messages/MessagesIa.php
languages/messages/MessagesIlo.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesKa.php
languages/messages/MessagesKab.php
languages/messages/MessagesKo.php
languages/messages/MessagesLb.php
languages/messages/MessagesMdf.php
languages/messages/MessagesMg.php
languages/messages/MessagesMk.php
languages/messages/MessagesMl.php
languages/messages/MessagesMs.php
languages/messages/MessagesNb.php
languages/messages/MessagesNl.php
languages/messages/MessagesNn.php
languages/messages/MessagesNso.php
languages/messages/MessagesOs.php
languages/messages/MessagesPcd.php
languages/messages/MessagesPfl.php
languages/messages/MessagesPms.php
languages/messages/MessagesQqq.php
languages/messages/MessagesRo.php
languages/messages/MessagesSa.php
languages/messages/MessagesSi.php
languages/messages/MessagesSk.php
languages/messages/MessagesSl.php
languages/messages/MessagesSv.php
languages/messages/MessagesTe.php
languages/messages/MessagesTg_cyrl.php
languages/messages/MessagesTr.php
languages/messages/MessagesUg_arab.php
languages/messages/MessagesUk.php
languages/messages/MessagesUz.php
languages/messages/MessagesVi.php
languages/messages/MessagesWar.php
languages/messages/MessagesYi.php
languages/messages/MessagesZh_hans.php
languages/messages/MessagesZh_hant.php
maintenance/archives/patch-fa_sha1.sql [new file with mode: 0644]
maintenance/archives/patch-sites.sql [new file with mode: 0644]
maintenance/deleteArchivedFiles.inc
maintenance/dev/install.sh [changed mode: 0644->0755]
maintenance/dev/installmw.sh [changed mode: 0644->0755]
maintenance/dev/installphp.sh [changed mode: 0644->0755]
maintenance/dev/start.sh [changed mode: 0644->0755]
maintenance/eval.php
maintenance/findHooks.php
maintenance/language/messages.inc
maintenance/oracle/archives/patch-archive-ar_content_format.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-archive-ar_content_model.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-cat_hidden.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-page-page_content_model.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-rc_moved.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-revision-rev_content_format.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-revision-rev_content_model.sql [new file with mode: 0644]
maintenance/oracle/archives/patch-ss_admins.sql [new file with mode: 0644]
maintenance/oracle/tables.sql
maintenance/populateFilearchiveSha1.php [new file with mode: 0644]
maintenance/postgres/tables.sql
maintenance/sqlite/archives/patch-sites.sql [new file with mode: 0644]
maintenance/tables.sql
maintenance/update.php
opensearch_desc.php5
resources/Resources.php
resources/jquery.effects/jquery.effects.blind.js
resources/jquery.effects/jquery.effects.bounce.js
resources/jquery.effects/jquery.effects.clip.js
resources/jquery.effects/jquery.effects.core.js
resources/jquery.effects/jquery.effects.drop.js
resources/jquery.effects/jquery.effects.explode.js
resources/jquery.effects/jquery.effects.fade.js
resources/jquery.effects/jquery.effects.fold.js
resources/jquery.effects/jquery.effects.highlight.js
resources/jquery.effects/jquery.effects.pulsate.js
resources/jquery.effects/jquery.effects.scale.js
resources/jquery.effects/jquery.effects.shake.js
resources/jquery.effects/jquery.effects.slide.js
resources/jquery.effects/jquery.effects.transfer.js
resources/jquery.ui/i18n/jquery.ui.datepicker-zh-CN.js
resources/jquery.ui/i18n/jquery.ui.datepicker-zh-HK.js
resources/jquery.ui/i18n/jquery.ui.datepicker-zh-TW.js
resources/jquery.ui/jquery.ui.accordion.js
resources/jquery.ui/jquery.ui.autocomplete.js
resources/jquery.ui/jquery.ui.button.js
resources/jquery.ui/jquery.ui.core.js
resources/jquery.ui/jquery.ui.datepicker.js
resources/jquery.ui/jquery.ui.dialog.js
resources/jquery.ui/jquery.ui.draggable.js
resources/jquery.ui/jquery.ui.droppable.js
resources/jquery.ui/jquery.ui.mouse.js
resources/jquery.ui/jquery.ui.position.js
resources/jquery.ui/jquery.ui.progressbar.js
resources/jquery.ui/jquery.ui.resizable.js
resources/jquery.ui/jquery.ui.selectable.js
resources/jquery.ui/jquery.ui.slider.js
resources/jquery.ui/jquery.ui.sortable.js
resources/jquery.ui/jquery.ui.tabs.js
resources/jquery.ui/jquery.ui.widget.js
resources/jquery.ui/themes/default/jquery.ui.accordion.css
resources/jquery.ui/themes/default/jquery.ui.autocomplete.css
resources/jquery.ui/themes/default/jquery.ui.button.css
resources/jquery.ui/themes/default/jquery.ui.core.css
resources/jquery.ui/themes/default/jquery.ui.datepicker.css
resources/jquery.ui/themes/default/jquery.ui.dialog.css
resources/jquery.ui/themes/default/jquery.ui.progressbar.css
resources/jquery.ui/themes/default/jquery.ui.resizable.css
resources/jquery.ui/themes/default/jquery.ui.selectable.css
resources/jquery.ui/themes/default/jquery.ui.slider.css
resources/jquery.ui/themes/default/jquery.ui.tabs.css
resources/jquery.ui/themes/default/jquery.ui.theme.css
resources/jquery/jquery.hidpi.js [new file with mode: 0644]
resources/jquery/jquery.js
resources/mediawiki/mediawiki.hidpi.js [new file with mode: 0644]
resources/mediawiki/mediawiki.js
skins/CologneBlue.php
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/CssContentTest.php
tests/phpunit/includes/GlobalFunctions/GlobalTest.php
tests/phpunit/includes/JavascriptContentTest.php
tests/phpunit/includes/TextContentTest.php [new file with mode: 0644]
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/WikiPageTest.php
tests/phpunit/includes/WikitextContentTest.php
tests/phpunit/includes/api/ApiGeneratorTest.php [new file with mode: 0644]
tests/phpunit/includes/libs/GenericArrayObjectTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/search/SearchEngineTest.php
tests/phpunit/includes/site/MediaWikiSiteTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SiteArrayTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SiteListTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SiteObjectTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SitesTest.php [new file with mode: 0644]
tests/phpunit/includes/site/TestSites.php [new file with mode: 0644]
tests/phpunit/includes/specials/SpecialSearchTest.php
tests/phpunit/resources/ResourcesTest.php [new file with mode: 0644]
tests/qunit/QUnitTestResources.php
tests/qunit/suites/resources/jquery/jquery.hidpi.test.js [new file with mode: 0644]
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.test.js
thumb.php
thumb.php5

index 0be75c5..319f196 100644 (file)
@@ -17,6 +17,7 @@ cache
 images/[0-9a-f]
 images/archive
 images/deleted
+images/lockdir
 images/temp
 images/thumb
 ## Extension:EasyTimeline
index c168f77..52c4e86 100644 (file)
@@ -67,7 +67,7 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * (bug 35685) api.php URL and other entry point URLs are now listed on
   Special:Version
 * Edit notices can now be translated.
-* jQuery upgraded to 1.8.1
+* jQuery upgraded to 1.8.2.
 * jQuery UI upgraded to 1.8.23.
 * QUnit upgraded from v1.2.0 to v1.10.0.
 * (bug 37604) jquery.cookie upgraded to 2011 version.
@@ -298,8 +298,8 @@ upgrade PHP if you have not done so prior to upgrading MediaWiki.
 * (bug 38904) prop=revisions&rvstart=... no longer blows up when continuing.
 * (bug 39032) ApiQuery generates help in constructor.
 * (bug 11142) Improve file extension blacklist error reporting in API upload.
-* (bug 39665) Cache AllowedGenerator array so it doesn't autoload all query classes
-  on every request.
+* (bug 39665) List of query generators is now not built using reflection, instead it is
+  defined in code.
 
 === Languages updated in 1.20 ===
 
index a1fa4ca..d8f6506 100644 (file)
@@ -19,6 +19,13 @@ production.
 * (bug 34876) jquery.makeCollapsible has been improved in performance.
 * Added ContentHandler facility to allow extensions to support other content than wikitext.
   See docs/contenthandler.txt for details.
+* New feature was developed for showing high-DPI thumbnails for high-DPI mobile
+  and desktop displays (configurable with $wgResponsiveImages).
+* Added new backend to represent and store information about sites and site
+  specific configuration.
+* jQuery UI upgraded from 1.8.23 to 1.8.24.
+* Added separate fa_sha1 field to filearchive table. This allows sha1
+  searches with the api in miser mode for deleted files.
 
 === Bug fixes in 1.21 ===
 * (bug 40353) SpecialDoubleRedirect should support interwiki redirects.
@@ -28,12 +35,18 @@ production.
   recentchanges table.
 * (bug 32951) Do not register internal externals with absolute protocol,
   when server has relative protocol.
+* (bug 39005) When purging proxies listed in $wgSquidServers using HTTP PURGE 
+  method requests, we now send a Host header by default, for Varnish 
+  compatibility. This also works with Squid in reverse-proxy mode. If you wish 
+  to support Squid configured in forward-proxy mode, set 
+  $wgSquidPurgeUseHostHeader to false.
 
 === API changes in 1.21 ===
 * prop=revisions can now report the contentmodel and contentformat, see docs/contenthandler.txt
 * action=edit and action=parse now support contentmodel and contentformat parameters to control the interpretation of
   page content; See docs/contenthandler.txt for details.
 * (bug 35693) ApiQueryImageInfo now suppresses errors when unserializing metadata.
+* (bug 40111) Disable minor edit for page/section creation by API
 
 === Languages updated in 1.21 ===
 
index 3561432..5a63460 100644 (file)
@@ -115,9 +115,9 @@ Besides some functions, some hooks have also been replaced by new versions (see
 These hooks will now trigger a warning when used:
 
 * ArticleAfterFetchContent was replaced by ArticleAfterFetchContentObject
-* ArticleInsertComplete was replaced by ArticleContentInsertComplete
-* ArticleSave was replaced by ArticleContentSave
-* ArticleSaveComplete was replaced by ArticleContentSaveComplete
+* ArticleInsertComplete was replaced by PageContentInsertComplete
+* ArticleSave was replaced by PageContentSave
+* ArticleSaveComplete was replaced by PageContentSaveComplete
 * ArticleViewCustom was replaced by ArticleContentViewCustom (also consider a custom implementation of the view action)
 * EditFilterMerged was replaced by EditFilterMergedContent
 * EditPageGetDiffText was replaced by EditPageGetDiffContent
index a4b4e57..10a341d 100644 (file)
@@ -491,7 +491,7 @@ Wiki::articleFromTitle()
 $title: title (object) used to create the article object
 $article: article (object) that will be returned
 
-'ArticleInsertComplete': After a new article is created. DEPRECATED, use ArticleContentInsertComplete
+'ArticleInsertComplete': After a new article is created. DEPRECATED, use PageContentInsertComplete
 $article: WikiPage created
 $user: User creating the article
 $text: New content
@@ -502,7 +502,7 @@ $section: (No longer used)
 $flags: Flags passed to WikiPage::doEditContent()
 $revision: New Revision of the article
 
-'ArticleContentInsertComplete': After a new article is created
+'PageContentInsertComplete': After a new article is created
 $article: WikiPage created
 $user: User creating the article
 $content: New content as a Content object
@@ -561,7 +561,7 @@ $user: the user who did the rollback
 $revision: the revision the page was reverted back to
 $current: the reverted revision
 
-'ArticleSave': before an article is saved. DEPRECATED, use ArticleContentSave instead
+'ArticleSave': before an article is saved. DEPRECATED, use PageContentSave instead
 $article: the WikiPage (object) being saved
 $user: the user (object) saving the article
 $text: the new article text
@@ -570,7 +570,7 @@ $isminor: minor flag
 $iswatch: watch flag
 $section: section #
 
-'ArticleContentSave': before an article is saved.
+'PageContentSave': before an article is saved.
 $article: the WikiPage (object) being saved
 $user: the user (object) saving the article
 $content: the new article content, as a Content object
@@ -579,7 +579,7 @@ $isminor: minor flag
 $iswatch: watch flag
 $section: section #
 
-'ArticleSaveComplete': After an article has been updated. DEPRECATED, use ArticleContentSaveComplete instead.
+'ArticleSaveComplete': After an article has been updated. DEPRECATED, use PageContentSaveComplete instead.
 $article: WikiPage modified
 $user: User performing the modification
 $text: New content
@@ -592,7 +592,7 @@ $revision: New Revision of the article
 $status: Status object about to be returned by doEditContent()
 $baseRevId: the rev ID (or false) this edit was based on
 
-'ArticleContentSaveComplete': After an article has been updated
+'PageContentSaveComplete': After an article has been updated
 $article: WikiPage modified
 $user: User performing the modification
 $content: New content, as a Content object
@@ -1223,6 +1223,10 @@ $reader: XMLReader object
 $revisionInfo: Array of information
 Return false to stop further processing of the tag
 
+'InfoAction': When building information to display on the action=info page
+$context: IContextSource object
+&$pageInfo: Array of information
+
 'InitializeArticleMaybeRedirect': MediaWiki check to see if title is a redirect
 $title: Title object ($wgTitle)
 $request: WebRequest
index 7367812..0eb0c68 100644 (file)
@@ -243,7 +243,7 @@ class Article extends Page {
         * @return string Return the text of this revision
         */
        public function getContent() {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
                $content = $this->getContentObject();
                return ContentHandler::getContentText( $content );
        }
@@ -377,7 +377,7 @@ class Article extends Page {
         * @deprecated in 1.21, use WikiPage::getContent() instead
         */
        function fetchContent() { #BC cruft!
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                if ( $this->mContentLoaded && $this->mContent ) {
                        return $this->mContent;
index 7deeec0..3ae5a68 100644 (file)
@@ -301,7 +301,7 @@ $wgAutoloadLocalClasses = array(
        'MessageContent' => 'includes/content/MessageContent.php',
        'TextContentHandler' => 'includes/content/ContentHandler.php',
        'TextContent' => 'includes/content/TextContent.php',
-       'WikitextContentHandler' => 'includes/ContentHandler.php',
+       'WikitextContentHandler' => 'includes/content/ContentHandler.php',
        'WikitextContent' => 'includes/content/WikitextContent.php',
 
        # includes/actions
@@ -874,6 +874,15 @@ $wgAutoloadLocalClasses = array(
        'SqliteSearchResultSet' => 'includes/search/SearchSqlite.php',
        'SqlSearchResultSet' => 'includes/search/SearchEngine.php',
 
+       # includes/site
+       'MediaWikiSite' => 'includes/site/MediaWikiSite.php',
+       'Site' => 'includes/site/Site.php',
+       'SiteArray' => 'includes/site/SiteArray.php',
+       'SiteList' => 'includes/site/SiteList.php',
+       'SiteObject' => 'includes/site/SiteObject.php',
+       'Sites' => 'includes/site/Sites.php',
+       'SitesTable' => 'includes/site/SitesTable.php',
+
        # includes/specials
        'ActiveUsersPager' => 'includes/specials/SpecialActiveusers.php',
        'AllmessagesTablePager' => 'includes/specials/SpecialAllmessages.php',
@@ -1042,6 +1051,7 @@ $wgAutoloadLocalClasses = array(
        'FixExtLinksProtocolRelative' => 'maintenance/fixExtLinksProtocolRelative.php',
        'PopulateCategory' => 'maintenance/populateCategory.php',
        'PopulateImageSha1' => 'maintenance/populateImageSha1.php',
+       'PopulateFilearchiveSha1' => 'maintenance/populateFilearchiveSha1.php',
        'PopulateLogSearch' => 'maintenance/populateLogSearch.php',
        'PopulateLogUsertext' => 'maintenance/populateLogUsertext.php',
        'PopulateParentId' => 'maintenance/populateParentId.php',
@@ -1083,8 +1093,8 @@ $wgAutoloadLocalClasses = array(
        'DummyContentForTesting' => 'tests/phpunit/includes/ContentHandlerTest.php',
        'JavascriptContentTest' => 'tests/phpunit/includes/JavascriptContentTest.php',
        'RevisionStorageTest' => 'tests/phpunit/includes/RevisionStorageTest.php',
+       'TextContentTest' => 'tests/phpunit/includes/TextContentTest.php',
        'WikiPageTest' => 'tests/phpunit/includes/WikiPageTest.php',
-       'WikitextContentTest' => 'tests/phpunit/includes/WikitextContentTest.php',
 
        # tests/phpunit/includes
        'GenericArrayObjectTest' => 'tests/phpunit/includes/libs/GenericArrayObjectTest.php',
@@ -1092,6 +1102,10 @@ $wgAutoloadLocalClasses = array(
        # tests/phpunit/includes/db
        'ORMRowTest' => 'tests/phpunit/includes/db/ORMRowTest.php',
 
+       # tests/phpunit/includes/site
+       'SiteObjectTest' => 'tests/phpunit/includes/site/SiteObjectTest.php',
+       'TestSites' => 'tests/phpunit/includes/site/TestSites.php',
+
        # tests/parser
        'ParserTest' => 'tests/parser/parserTest.inc',
        'ParserTestParserHook' => 'tests/parser/parserTestsParserHook.php',
index c97cf13..f58e07e 100644 (file)
@@ -180,7 +180,7 @@ class CdbReader_PHP extends CdbReader {
        protected function read( $length, $pos ) {
                if ( fseek( $this->handle, $pos ) == -1 ) {
                        // This can easily happen if the internal pointers are incorrect
-                       throw new MWException( 
+                       throw new MWException(
                                'Seek failed, file "' . $this->fileName . '" may be corrupted.' );
                }
 
@@ -205,7 +205,7 @@ class CdbReader_PHP extends CdbReader {
        protected function unpack31( $s ) {
                $data = unpack( 'V', $s );
                if ( $data[1] > 0x7fffffff ) {
-                       throw new MWException( 
+                       throw new MWException(
                                'Error in CDB file "' . $this->fileName . '", integer too big.' );
                }
                return $data[1];
@@ -477,7 +477,7 @@ class CdbWriter_PHP extends CdbWriter {
 
        /**
         * Clean up the temp file and throw an exception
-        * 
+        *
         * @param $msg string
         * @throws MWException
         */
index ad2b94b..8554c2b 100644 (file)
@@ -152,10 +152,10 @@ class IcuCollation extends Collation {
        /**
         * Unified CJK blocks.
         *
-        * The same definition of a CJK block must be used for both Collation and 
-        * generateCollationData.php. These blocks are omitted from the first 
-        * letter data, as an optimisation measure and because the default UCA table 
-        * is pretty useless for sorting Chinese text anyway. Japanese and Korean 
+        * The same definition of a CJK block must be used for both Collation and
+        * generateCollationData.php. These blocks are omitted from the first
+        * letter data, as an optimisation measure and because the default UCA table
+        * is pretty useless for sorting Chinese text anyway. Japanese and Korean
         * blocks are not included here, because they are smaller and more useful.
         */
        static $cjkBlocks = array(
@@ -180,7 +180,7 @@ class IcuCollation extends Collation {
 
        function __construct( $locale ) {
                if ( !extension_loaded( 'intl' ) ) {
-                       throw new MWException( 'An ICU collation was requested, ' . 
+                       throw new MWException( 'An ICU collation was requested, ' .
                                'but the intl extension is not available.' );
                }
                $this->locale = $locale;
@@ -218,8 +218,8 @@ class IcuCollation extends Collation {
 
                // Check for CJK
                $firstChar = mb_substr( $string, 0, 1, 'UTF-8' );
-               if ( ord( $firstChar ) > 0x7f 
-                       && self::isCjk( utf8ToCodepoint( $firstChar ) ) ) 
+               if ( ord( $firstChar ) > 0x7f
+                       && self::isCjk( utf8ToCodepoint( $firstChar ) ) )
                {
                        return $firstChar;
                }
@@ -265,9 +265,9 @@ class IcuCollation extends Collation {
                // Sort the letters.
                //
                // It's impossible to have the precompiled data file properly sorted,
-               // because the sort order changes depending on ICU version. If the 
-               // array is not properly sorted, the binary search will return random 
-               // results. 
+               // because the sort order changes depending on ICU version. If the
+               // array is not properly sorted, the binary search will return random
+               // results.
                //
                // We also take this opportunity to remove primary collisions.
                $letterMap = array();
@@ -320,7 +320,7 @@ class IcuCollation extends Collation {
        }
 
        /**
-        * Do a binary search, and return the index of the largest item that sorts 
+        * Do a binary search, and return the index of the largest item that sorts
         * less than or equal to the target value.
         *
         * @param $valueCallback array A function to call to get the value with
index 858eebf..fcf6a39 100644 (file)
@@ -391,7 +391,7 @@ class MWCryptRand {
                // We hash the random state with more salt to avoid the state from leaking
                // out and being used to predict the /randomness/ that follows.
                if ( strlen( $buffer ) < $bytes ) {
-                       wfDebug( __METHOD__ . ": Falling back to using a pseudo random state to generate randomness.\n" ); 
+                       wfDebug( __METHOD__ . ": Falling back to using a pseudo random state to generate randomness.\n" );
                }
                while ( strlen( $buffer ) < $bytes ) {
                        wfProfileIn( __METHOD__ . '-fallback' );
index 2e1e82f..320ce62 100644 (file)
@@ -748,6 +748,7 @@ $wgContentHandlers = array(
        CONTENT_MODEL_WIKITEXT => 'WikitextContentHandler', // the usual case
        CONTENT_MODEL_JAVASCRIPT => 'JavaScriptContentHandler', // dumb version, no syntax highlighting
        CONTENT_MODEL_CSS => 'CssContentHandler', // dumb version, no syntax highlighting
+       CONTENT_MODEL_TEXT => 'TextContentHandler', // plain text, for use by extensions etc
 );
 
 /**
@@ -1088,6 +1089,16 @@ $wgThumbUpright = 0.75;
  */
 $wgDirectoryMode = 0777;
 
+/**
+ * Generate and use thumbnails suitable for screens with 1.5 and 2.0 pixel densities.
+ *
+ * This means a 320x240 use of an image on the wiki will also generate 480x360 and 640x480
+ * thumbnails, output via data-src-1-5 and data-src-2-0. Runtime JavaScript switches the
+ * images in after loading the original low-resolution versions depending on the reported
+ * window.devicePixelRatio.
+ */
+$wgResponsiveImages = true;
+
 /**
  * @name DJVU settings
  * @{
@@ -2047,6 +2058,27 @@ $wgSquidServersNoPurge = array();
 /** Maximum number of titles to purge in any one client operation */
 $wgMaxSquidPurgeTitles = 400;
 
+/**
+ * Whether to use a Host header in purge requests sent to the proxy servers
+ * configured in $wgSquidServers. Set this to false to support Squid 
+ * configured in forward-proxy mode.
+ *
+ * If this is set to true, a Host header will be sent, and only the path
+ * component of the URL will appear on the request line, as if the request
+ * were a non-proxy HTTP 1.1 request. Varnish only supports this style of 
+ * request. Squid supports this style of request only if reverse-proxy mode
+ * (http_port ... accel) is enabled.
+ *
+ * If this is set to false, no Host header will be sent, and the absolute URL
+ * will be sent in the request line, as is the standard for an HTTP proxy
+ * request in both HTTP 1.0 and 1.1. This style of request is not supported
+ * by Varnish, but is supported by Squid in either configuration (forward or
+ * reverse). 
+ *
+ * @since 1.21
+ */
+$wgSquidPurgeUseHostHeader = true;
+
 /**
  * Routing configuration for HTCP multicast purging. Add elements here to
  * enable HTCP and determine which purges are sent where. If set to an empty
@@ -5922,6 +5954,7 @@ $wgAPIModules = array();
 $wgAPIMetaModules = array();
 $wgAPIPropModules = array();
 $wgAPIListModules = array();
+$wgAPIGeneratorModules = array();
 
 /**
  * Maximum amount of rows to scan in a DB query in the API
@@ -6283,6 +6316,14 @@ $wgContentHandlerUseDB = true;
  */
 $wgRequirePasswordforEmailChange = true;
 
+/**
+ * Register handlers for specific types of sites.
+ *
+ * @since 1.20
+ */
+$wgSiteTypes = array();
+$wgSiteTypes['mediawiki'] = 'MediaWikiSite';
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index 1bcb058..2ddd053 100644 (file)
@@ -213,6 +213,7 @@ require_once __DIR__.'/normal/UtfNormalDefines.php';
 define( 'MW_SUPPORTS_EDITFILTERMERGED', 1 );
 define( 'MW_SUPPORTS_PARSERFIRSTCALLINIT', 1 );
 define( 'MW_SUPPORTS_LOCALISATIONCACHE', 1 );
+define( 'MW_SUPPORTS_CONTENTHANDLER', 1 );
 /**@}*/
 
 /** Support for $wgResourceModules */
index 35328f8..cc41b02 100644 (file)
@@ -381,7 +381,6 @@ class EditPage {
                $this->isCssSubpage         = $this->mTitle->isCssSubpage();
                $this->isJsSubpage          = $this->mTitle->isJsSubpage();
                $this->isWrongCaseCssJsPage = $this->isWrongCaseCssJsPage();
-               $this->isNew                = !$this->mTitle->exists() || $this->section == 'new';
 
                # Show applicable editing introductions
                if ( $this->formtype == 'initial' || $this->firsttime ) {
@@ -588,12 +587,13 @@ class EditPage {
         * @param $request WebRequest
         */
        function importFormData( &$request ) {
-               global $wgLang, $wgUser;
+               global $wgContLang, $wgUser;
 
                wfProfileIn( __METHOD__ );
 
                # Section edit can come from either the form or a link
                $this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
+               $this->isNew = !$this->mTitle->exists() || $this->section == 'new';
 
                if ( $request->wasPosted() ) {
                        # These fields need to be checked for encoding.
@@ -612,7 +612,7 @@ class EditPage {
                        }
 
                        # Truncate for whole multibyte characters
-                       $this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 255 );
+                       $this->summary = $wgContLang->truncate( $request->getText( 'wpSummary' ), 255 );
 
                        # If the summary consists of a heading, e.g. '==Foobar==', extract the title from the
                        # header syntax, e.g. 'Foobar'. This is mainly an issue when we are using wpSummary for
@@ -624,7 +624,7 @@ class EditPage {
                        # currently doing double duty as both edit summary and section title. Right now this
                        # is just to allow API edits to work around this limitation, but this should be
                        # incorporated into the actual edit form when EditPage is rewritten (Bugs 18654, 26312).
-                       $this->sectiontitle = $wgLang->truncate( $request->getText( 'wpSectionTitle' ), 255 );
+                       $this->sectiontitle = $wgContLang->truncate( $request->getText( 'wpSectionTitle' ), 255 );
                        $this->sectiontitle = preg_replace( '/^\s*=+\s*(.*?)\s*=+\s*$/', '$1', $this->sectiontitle );
 
                        $this->edittime = $request->getVal( 'wpEdittime' );
@@ -806,10 +806,10 @@ class EditPage {
         * @param $def_text string
         * @return mixed string on success, $def_text for invalid sections
         * @private
-        * @deprecated since 1.21
+        * @deprecated since 1.21, get WikiPage::getContent() instead.
         */
        function getContent( $def_text = false ) {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                if ( $def_text !== null && $def_text !== false && $def_text !== '' ) {
                        $def_content = $this->toEditContent( $def_text );
@@ -989,10 +989,10 @@ class EditPage {
         * Use this method before edit() to preload some text into the edit box
         *
         * @param $text string
-        * @deprecated since 1.21
+        * @deprecated since 1.21, use setPreloadedContent() instead.
         */
        public function setPreloadedText( $text ) {
-               wfDeprecated( __METHOD__, "1.21" );
+               ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $content = $this->toEditContent( $text );
 
@@ -1007,7 +1007,7 @@ class EditPage {
         * @since 1.21
         */
        public function setPreloadedContent( Content $content ) {
-               $this->mPreloadedContent = $content;
+               $this->mPreloadContent = $content;
        }
 
        /**
@@ -1021,7 +1021,7 @@ class EditPage {
         * @deprecated since 1.21, use getPreloadedContent() instead
         */
        protected function getPreloadedText( $preload ) {
-               wfDeprecated( __METHOD__, "1.21" );
+               ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $content = $this->getPreloadedContent( $preload );
                $text = $this->toEditText( $content );
@@ -1643,7 +1643,7 @@ class EditPage {
         * @deprecated since 1.21, use mergeChangesIntoContent() instead
         */
        function mergeChangesInto( &$editText ){
-               wfDebug( __METHOD__, "1.21" );
+               ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $editContent = $this->toEditContent( $editText );
 
@@ -1921,13 +1921,18 @@ class EditPage {
         * an exception will be raised. Set $this->allowNonTextContent to true to allow editing of non-textual
         * content.
         *
-        * @param String $text Text to unserialize
-        * @return Content the content object created from $text
+        * @param String|null|false $text Text to unserialize
+        * @return Content The content object created from $text. If $text was false or null, false resp. null will be
+        *                 returned instead.
         *
         * @throws MWException if unserializing the text results in a Content object that is not an instance of TextContent
         *          and $this->allowNonTextContent is not true.
         */
        protected function toEditContent( $text ) {
+               if ( $text === false || $text === null ) {
+                       return $text;
+               }
+
                $content = ContentHandler::makeContent( $text, $this->getTitle(),
                        $this->contentModel, $this->contentFormat );
 
index 9a01deb..23944a5 100644 (file)
@@ -288,7 +288,7 @@ abstract class ExternalUser {
                                   'eu_external_id' => $this->getId() ),
                        __METHOD__ );
        }
-       
+
        /**
         * Check whether this external user id is already linked with
         * a local user.
@@ -305,5 +305,5 @@ abstract class ExternalUser {
                        ? User::newFromId( $row->eu_local_id )
                        : null;
        }
-       
+
 }
index b0a0e2b..82c6e4a 100644 (file)
@@ -87,7 +87,7 @@ class FeedUtils {
                        ($row->rc_deleted & Revision::DELETED_COMMENT)
                                ? wfMessage('rev-deleted-comment')->escaped()
                                : $row->rc_comment,
-                       $actiontext 
+                       $actiontext
                );
        }
 
index f978639..1cfe88e 100644 (file)
@@ -22,7 +22,7 @@
  *
  * @file
  * @author Niklas Laxström
- * @author Antoine Musso 
+ * @author Antoine Musso
  */
 
 /**
index f4a3b55..a07dd4c 100644 (file)
@@ -796,10 +796,12 @@ class Html {
                        if ( $nsId < NS_MAIN || in_array( $nsId, $params['exclude'] ) ) {
                                continue;
                        }
-                       if ( $nsId === 0 ) {
+                       if ( $nsId === NS_MAIN ) {
                                // For other namespaces use use the namespace prefix as label, but for
                                // main we don't use "" but the user message descripting it (e.g. "(Main)" or "(Article)")
                                $nsName = wfMessage( 'blanknamespace' )->text();
+                       } elseif ( is_int( $nsId ) ) {
+                               $nsName = $wgContLang->convertNamespace( $nsId );
                        }
                        $optionsHtml[] = Html::element(
                                'option', array(
@@ -940,4 +942,22 @@ class Html {
 
                return $s;
        }
+
+       /**
+        * Generate a srcset attribute value from an array mapping pixel densities
+        * to URLs. Note that srcset supports width and height values as well, which
+        * are not used here.
+        *
+        * @param array $urls
+        * @return string
+        */
+       static function srcSet( $urls ) {
+               $candidates = array();
+               foreach( $urls as $density => $url ) {
+                       // Image candidate syntax per current whatwg live spec, 2012-09-23:
+                       // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#attr-img-srcset
+                       $candidates[] = "{$url} {$density}x";
+               }
+               return implode( ", ", $candidates );
+       }
 }
index c9b0997..7cc6fb1 100644 (file)
@@ -1215,7 +1215,7 @@ class WikiRevision {
         * @deprecated Since 1.21, use getContent() instead.
         */
        function getText() {
-               wfDeprecated( "Use getContent() instead." );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                return $this->text;
        }
index c17e2d1..0f45165 100644 (file)
@@ -676,6 +676,7 @@ class Linker {
                if ( !$thumb ) {
                        $s = self::makeBrokenImageLinkObj( $title, $fp['title'], '', '', '', $time == true );
                } else {
+                       self::processResponsiveImages( $file, $thumb, $hp );
                        $params = array(
                                'alt' => $fp['alt'],
                                'title' => $fp['title'],
@@ -796,6 +797,7 @@ class Linker {
                        $hp['width'] = isset( $fp['upright'] ) ? 130 : 180;
                }
                $thumb = false;
+               $noscale = false;
 
                if ( !$exists ) {
                        $outerWidth = $hp['width'] + 2;
@@ -814,6 +816,7 @@ class Linker {
                        } elseif ( isset( $fp['framed'] ) ) {
                                // Use image dimensions, don't scale
                                $thumb = $file->getUnscaledThumb( $hp );
+                               $noscale = true;
                        } else {
                                # Do not present an image bigger than the source, for bitmap-style images
                                # This is a hack to maintain compatibility with arbitrary pre-1.10 behaviour
@@ -847,6 +850,9 @@ class Linker {
                        $s .= wfMessage( 'thumbnail_error', '' )->escaped();
                        $zoomIcon = '';
                } else {
+                       if ( !$noscale ) {
+                               self::processResponsiveImages( $file, $thumb, $hp );
+                       }
                        $params = array(
                                'alt' => $fp['alt'],
                                'title' => $fp['title'],
@@ -873,6 +879,37 @@ class Linker {
                return str_replace( "\n", ' ', $s );
        }
 
+       /**
+        * Process responsive images: add 1.5x and 2x subimages to the thumbnail, where
+        * applicable.
+        *
+        * @param File $file
+        * @param MediaOutput $thumb
+        * @param array $hp image parameters
+        */
+       protected static function processResponsiveImages( $file, $thumb, $hp ) {
+               global $wgResponsiveImages;
+               if ( $wgResponsiveImages ) {
+                       $hp15 = $hp;
+                       $hp15['width'] = round( $hp['width'] * 1.5 );
+                       $hp20 = $hp;
+                       $hp20['width'] = $hp['width'] * 2;
+                       if ( isset( $hp['height'] ) ) {
+                               $hp15['height'] = round( $hp['height'] * 1.5 );
+                               $hp20['height'] = $hp['height'] * 2;
+                       }
+
+                       $thumb15 = $file->transform( $hp15 );
+                       $thumb20 = $file->transform( $hp20 );
+                       if ( $thumb15->url !== $thumb->url ) {
+                               $thumb->responsiveUrls['1.5'] = $thumb15->url;
+                       }
+                       if ( $thumb20->url !== $thumb->url ) {
+                               $thumb->responsiveUrls['2'] = $thumb20->url;
+                       }
+               }
+       }
+
        /**
         * Make a "broken" link to an image
         *
index 3a698e5..09561bd 100644 (file)
@@ -140,7 +140,7 @@ class MessageBlobStore {
                // Save the old and new blobs for later
                $oldBlob = $row->mr_blob;
                $newBlob = self::generateMessageBlob( $module, $lang );
-               
+
                $newRow = array(
                        'mr_resource' => $name,
                        'mr_lang' => $lang,
index 46a43f6..78435e4 100644 (file)
@@ -22,9 +22,9 @@
 
 /**
  * Standard output handler for use with ob_start
- * 
+ *
  * @param $s string
- * 
+ *
  * @return string
  */
 function wfOutputHandler( $s ) {
@@ -85,7 +85,7 @@ function wfRequestExtension() {
 /**
  * Handler that compresses data with gzip if allowed by the Accept header.
  * Unlike ob_gzhandler, it works for HEAD requests too.
- * 
+ *
  * @param $s string
  *
  * @return string
index dd9c9e3..3578568 100644 (file)
@@ -2462,7 +2462,7 @@ $templates
         */
        private function addDefaultModules() {
                global $wgIncludeLegacyJavaScript, $wgPreloadJavaScriptMwUtil, $wgUseAjax,
-                       $wgAjaxWatch;
+                       $wgAjaxWatch, $wgResponsiveImages;
 
                // Add base resources
                $this->addModules( array(
@@ -2503,6 +2503,11 @@ $templates
                if ( $this->isArticle() && $this->getUser()->getOption( 'editondblclick' ) ) {
                        $this->addModules( 'mediawiki.action.view.dblClickEdit' );
                }
+
+               // Support for high-density display images
+               if ( $wgResponsiveImages ) {
+                       $this->addModules( 'mediawiki.hidpi' );
+               }
        }
 
        /**
index 216ba48..65a0d02 100644 (file)
@@ -879,7 +879,7 @@ class Preferences {
                global $wgUseRCPatrol, $wgEnableAPI, $wgRCMaxAge;
 
                $watchlistdaysMax = ceil( $wgRCMaxAge / ( 3600 * 24 ) );
-               
+
                ## Watchlist #####################################
                $defaultPreferences['watchlistdays'] = array(
                        'type' => 'float',
index beb20ea..9643ba7 100644 (file)
@@ -63,7 +63,7 @@ class ProtectionForm {
                $this->mArticle = $article;
                $this->mTitle = $article->getTitle();
                $this->mApplicableTypes = $this->mTitle->getRestrictionTypes();
-               
+
                // Check if the form should be disabled.
                // If it is, the form will be available in read-only to show levels.
                $this->mPermErrors = $this->mTitle->getUserPermissionsErrors( 'protect', $wgUser );
index 1b2db36..c39183b 100644 (file)
@@ -890,7 +890,7 @@ class Revision implements IDBAccessObject {
         * @return String
         */
        public function getText( $audience = self::FOR_PUBLIC, User $user = null ) {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                $content = $this->getContent( $audience, $user );
                return ContentHandler::getContentText( $content ); # returns the raw content text, if applicable
@@ -940,7 +940,7 @@ class Revision implements IDBAccessObject {
         *                         or Revision::getSerializedData() as appropriate.
         */
        public function getRawText() {
-               wfDeprecated( __METHOD__, "1.21" );
+               ContentHandler::deprecated( __METHOD__, "1.21" );
 
                return $this->getText( self::RAW );
        }
index 8eb0f6b..7d75f2c 100644 (file)
@@ -21,9 +21,9 @@
  */
 
 /**
- * An HTTP 1.0 client built for the purposes of purging Squid and Varnish. 
- * Uses asynchronous I/O, allowing purges to be done in a highly parallel 
- * manner. 
+ * An HTTP 1.0 client built for the purposes of purging Squid and Varnish.
+ * Uses asynchronous I/O, allowing purges to be done in a highly parallel
+ * manner.
  *
  * Could be replaced by curl_multi_exec() or some such.
  */
@@ -123,7 +123,7 @@ class SquidPurgeClient {
                return array( $socket );
        }
 
-       /** 
+       /**
         * Get the host's IP address.
         * Does not support IPv6 at present due to the lack of a convenient interface in PHP.
         */
@@ -176,11 +176,32 @@ class SquidPurgeClient {
         * @param $url string
         */
        public function queuePurge( $url ) {
+               global $wgSquidPurgeUseHostHeader;
                $url = SquidUpdate::expand( str_replace( "\n", '', $url ) );
-               $this->requests[] = "PURGE $url HTTP/1.0\r\n" .
-                       "Connection: Keep-Alive\r\n" .
-                       "Proxy-Connection: Keep-Alive\r\n" .
-                       "User-Agent: " . Http::userAgent() . ' ' . __CLASS__ . "\r\n\r\n";
+               $request = array();
+               if ( $wgSquidPurgeUseHostHeader ) {
+                       $url = wfParseUrl( $url );
+                       $host = $url['host'];
+                       if ( isset( $url['port'] ) && strlen( $url['port'] ) > 0 ) {
+                               $host .= ":" . $url['port'];
+                       }
+                       $path = $url['path'];
+                       if ( isset( $url['query'] ) && is_string( $url['query'] ) ) {
+                               $path = wfAppendQuery( $path, $url['query'] );
+                       }
+                       $request[] = "PURGE $path HTTP/1.1";
+                       $request[] = "Host: $host";
+               } else {
+                       $request[] = "PURGE $url HTTP/1.0";
+               }
+               $request[] = "Connection: Keep-Alive";
+               $request[] = "Proxy-Connection: Keep-Alive";
+               $request[] = "User-Agent: " . Http::userAgent() . ' ' . __CLASS__;
+               // Two ''s to create \r\n\r\n
+               $request[] = '';
+               $request[] = '';
+
+               $this->requests[] = implode( "\r\n", $request );
                if ( $this->currentRequestIndex === null ) {
                        $this->nextRequest();
                }
@@ -408,7 +429,7 @@ class SquidPurgeClientPool {
                        $numReady = socket_select( $readSockets, $writeSockets, $exceptSockets, $timeout );
                        wfRestoreWarnings();
                        if ( $numReady === false ) {
-                               wfDebugLog( 'squid', __METHOD__.': Error in stream_select: ' . 
+                               wfDebugLog( 'squid', __METHOD__.': Error in stream_select: ' .
                                        socket_strerror( socket_last_error() ) . "\n" );
                                break;
                        }
index 10dfb51..147b0df 100644 (file)
@@ -225,6 +225,15 @@ class Status {
                }
        }
 
+       /**
+        * Get the error message as HTML. This is done by parsing the wikitext error 
+        * message.
+        */
+       public function getHTML( $shortContext = false, $longContext = false ) {
+               $text = $this->getWikiText( $shortContext, $longContext );
+               return MessageCache::singleton()->transform( $text, true );
+       }
+
        /**
         * Return an array with the wikitext for each item in the array.
         * @param $errors Array
index 43275a6..fba31ea 100644 (file)
@@ -424,7 +424,7 @@ class ReplacementArray {
 
 /**
  * An iterator which works exactly like:
- * 
+ *
  * foreach ( explode( $delim, $s ) as $element ) {
  *    ...
  * }
index 3212f54..ee3e01f 100644 (file)
@@ -387,6 +387,8 @@ class Title {
         * @deprecated since 1.21, use Content::getRedirectTarget instead.
         */
        public static function newFromRedirect( $text ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+
                $content = ContentHandler::makeContent( $text, null, CONTENT_MODEL_WIKITEXT );
                return $content->getRedirectTarget();
        }
@@ -402,6 +404,8 @@ class Title {
         * @deprecated since 1.21, use Content::getUltimateRedirectTarget instead.
         */
        public static function newFromRedirectRecurse( $text ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+
                $content = ContentHandler::makeContent( $text, null, CONTENT_MODEL_WIKITEXT );
                return $content->getUltimateRedirectTarget();
        }
@@ -417,6 +421,8 @@ class Title {
         * @deprecated since 1.21, use Content::getRedirectChain instead.
         */
        public static function newFromRedirectArray( $text ) {
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+
                $content = ContentHandler::makeContent( $text, null, CONTENT_MODEL_WIKITEXT );
                return $content->getRedirectChain();
        }
@@ -2916,10 +2922,10 @@ class Title {
 
                $linkCache = LinkCache::singleton();
                $cached = $linkCache->getGoodLinkFieldObj( $this, 'redirect' );
-               if ( $cached === null ) { # check the assumption that the cache actually knows about this title
-                       # XXX: this does apparently happen, see https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
-                       #      as a stop gap, perhaps log this, but don't throw an exception?
-                       throw new MWException( "LinkCache doesn't currently know about this title: " . $this->getPrefixedDBkey() );
+               if ( $cached === null ) { 
+                       // TODO: check the assumption that the cache actually knows about this title
+                       // and handle this, such as get the title from the database.
+                       // See https://bugzilla.wikimedia.org/show_bug.cgi?id=37209
                }
 
                $this->mRedirect = (bool)$cached;
index 93a6835..f80319d 100644 (file)
@@ -893,7 +893,7 @@ class User {
                if( $loggedOut !== null ) {
                        $this->mTouched = wfTimestamp( TS_MW, $loggedOut );
                } else {
-                       $this->mTouched = '0'; # Allow any pages to be cached
+                       $this->mTouched = '1'; # Allow any pages to be cached
                }
 
                $this->mToken = null; // Don't run cryptographic functions till we need a token
@@ -1224,9 +1224,8 @@ class User {
 
                $defOpt = $wgDefaultUserOptions;
                # default language setting
-               $variant = $wgContLang->getDefaultVariant();
-               $defOpt['variant'] = $variant;
-               $defOpt['language'] = $variant;
+               $defOpt['variant'] = $wgContLang->getCode();
+               $defOpt['language'] = $wgContLang->getCode();
                foreach( SearchEngine::searchableNamespaces() as $nsnum => $nsname ) {
                        $defOpt['searchNs'.$nsnum] = !empty( $wgNamespacesToBeSearchedDefault[$nsnum] );
                }
@@ -3009,7 +3008,29 @@ class User {
        }
 
        /**
-        * Add this existing user object to the database
+        * Add this existing user object to the database. If the user already 
+        * exists, a fatal status object is returned, and the user object is 
+        * initialised with the data from the database.
+        *
+        * Previously, this function generated a DB error due to a key conflict
+        * if the user already existed. Many extension callers use this function
+        * in code along the lines of:
+        *
+        *   $user = User::newFromName( $name );
+        *   if ( !$user->isLoggedIn() ) {
+        *       $user->addToDatabase();
+        *   }
+        *   // do something with $user...
+        *
+        * However, this was vulnerable to a race condition (bug 16020). By 
+        * initialising the user object if the user exists, we aim to support this
+        * calling sequence as far as possible.
+        *
+        * Note that if the user exists, this function will acquire a write lock,
+        * so it is still advisable to make the call conditional on isLoggedIn(), 
+        * and to commit the transaction after calling.
+        *
+        * @return Status
         */
        public function addToDatabase() {
                $this->load();
@@ -3032,14 +3053,31 @@ class User {
                                'user_registration' => $dbw->timestamp( $this->mRegistration ),
                                'user_editcount' => 0,
                                'user_touched' => $dbw->timestamp( $this->mTouched ),
-                       ), __METHOD__
+                       ), __METHOD__,
+                       array( 'IGNORE' )
                );
+               if ( !$dbw->affectedRows() ) {
+                       $this->mId = $dbw->selectField( 'user', 'user_id', 
+                               array( 'user_name' => $this->mName ), __METHOD__ );
+                       $loaded = false;
+                       if ( $this->mId ) {
+                               if ( $this->loadFromDatabase() ) {
+                                       $loaded = true;
+                               }
+                       }
+                       if ( !$loaded ) {
+                               throw new MWException( __METHOD__. ": hit a key conflict attempting " .
+                                       "to insert a user row, but then it doesn't exist when we select it!" );
+                       }
+                       return Status::newFatal( 'userexists' );
+               }
                $this->mId = $dbw->insertId();
 
                // Clear instance cache other than user table data, which is already accurate
                $this->clearInstanceCache();
 
                $this->saveOptions();
+               return Status::newGood();
        }
 
        /**
@@ -4079,12 +4117,28 @@ class User {
         * @todo document
         */
        protected function loadOptions() {
+               global $wgContLang;
+
                $this->load();
-               if ( $this->mOptionsLoaded || !$this->getId() )
+
+               if ( $this->mOptionsLoaded ) {
                        return;
+               }
 
                $this->mOptions = self::getDefaultOptions();
 
+               if ( !$this->getId() ) {
+                       // For unlogged-in users, load language/variant options from request.
+                       // There's no need to do it for logged-in users: they can set preferences,
+                       // and handling of page content is done by $pageLang->getPreferredVariant() and such,
+                       // so don't override user's choice (especially when the user chooses site default).
+                       $variant = $wgContLang->getDefaultVariant();
+                       $this->mOptions['variant'] = $variant;
+                       $this->mOptions['language'] = $variant;
+                       $this->mOptionsLoaded = true;
+                       return;
+               }
+
                // Maybe load from the object
                if ( !is_null( $this->mOptionOverrides ) ) {
                        wfDebug( "User: loading options for user " . $this->getId() . " from override cache.\n" );
index 80fb81a..7005416 100644 (file)
@@ -380,7 +380,6 @@ class WebRequest {
                return $ret;
        }
 
-       
        /**
         * Unset an arbitrary value from our get/post data.
         *
index 770c37a..9986a8d 100644 (file)
@@ -631,7 +631,8 @@ class WikiPage extends Page implements IDBAccessObject {
         * @deprecated as of 1.21, getContent() should be used instead.
         */
        public function getText( $audience = Revision::FOR_PUBLIC, User $user = null ) { #@todo: deprecated, replace usage!
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
+
                $this->loadLastEdit();
                if ( $this->mLastRevision ) {
                        return $this->mLastRevision->getText( $audience, $user );
@@ -646,7 +647,7 @@ class WikiPage extends Page implements IDBAccessObject {
         * @deprecated as of 1.21, getContent() should be used instead.
         */
        public function getRawText() {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                return $this->getText( Revision::RAW );
        }
@@ -1381,7 +1382,7 @@ class WikiPage extends Page implements IDBAccessObject {
         * @deprecated since 1.21: use ContentHandler::getUndoContent() instead.
         */
        public function getUndoText( Revision $undo, Revision $undoafter = null ) {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                $this->loadLastEdit();
 
@@ -1413,7 +1414,7 @@ class WikiPage extends Page implements IDBAccessObject {
         * @deprecated since 1.21, use replaceSectionContent() instead
         */
        public function replaceSection( $section, $text, $sectionTitle = '', $edittime = null ) {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                if ( strval( $section ) == '' ) { //NOTE: keep condition in sync with condition in replaceSectionContent!
                        // Whole-page edit; let the whole text through
@@ -1561,7 +1562,7 @@ class WikiPage extends Page implements IDBAccessObject {
         * @deprecated since 1.21: use doEditContent() instead.
         */
        public function doEdit( $text, $summary, $flags = 0, $baseRevId = false, $user = null ) {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                $content = ContentHandler::makeContent( $text, $this->getTitle() );
 
@@ -1647,7 +1648,7 @@ class WikiPage extends Page implements IDBAccessObject {
                $hook_args = array( &$this, &$user, &$content, &$summary,
                                                        $flags & EDIT_MINOR, null, null, &$flags, &$status );
 
-               if ( !wfRunHooks( 'ArticleContentSave', $hook_args )
+               if ( !wfRunHooks( 'PageContentSave', $hook_args )
                        || !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args ) ) {
 
                        wfDebug( __METHOD__ . ": ArticleSave or ArticleSaveContent hook aborted save!\n" );
@@ -1878,7 +1879,7 @@ class WikiPage extends Page implements IDBAccessObject {
                                                                $flags & EDIT_MINOR, null, null, &$flags, $revision );
 
                        ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $hook_args );
-                       wfRunHooks( 'ArticleContentInsertComplete', $hook_args );
+                       wfRunHooks( 'PageContentInsertComplete', $hook_args );
                }
 
                # Do updates right now unless deferral was requested
@@ -1893,7 +1894,7 @@ class WikiPage extends Page implements IDBAccessObject {
                                                        $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );
 
                ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
-               wfRunHooks( 'ArticleContentSaveComplete', $hook_args );
+               wfRunHooks( 'PageContentSaveComplete', $hook_args );
 
                # Promote user to any groups they meet the criteria for
                $user->addAutopromoteOnceGroups( 'onEdit' );
@@ -1934,7 +1935,7 @@ class WikiPage extends Page implements IDBAccessObject {
         * @deprecated in 1.21: use prepareContentForEdit instead.
         */
        public function prepareTextForEdit( $text, $revid = null, User $user = null ) {
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
                $content = ContentHandler::makeContent( $text, $this->getTitle() );
                return $this->prepareContentForEdit( $content, $revid , $user );
        }
@@ -2136,7 +2137,7 @@ class WikiPage extends Page implements IDBAccessObject {
         * @deprecated since 1.21, use doEditContent() instead.
         */
        public function doQuickEdit( $text, User $user, $comment = '', $minor = 0 ) {
-               wfDeprecated( __METHOD__, "1.21" );
+               ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $content = ContentHandler::makeContent( $text, $this->getTitle() );
                return $this->doQuickEditContent( $content, $user, $comment , $minor );
@@ -2937,7 +2938,7 @@ class WikiPage extends Page implements IDBAccessObject {
        public static function getAutosummary( $oldtext, $newtext, $flags ) {
                # NOTE: stub for backwards-compatibility. assumes the given text is wikitext. will break horribly if it isn't.
 
-               wfDeprecated( __METHOD__, '1.21' );
+               ContentHandler::deprecated( __METHOD__, '1.21' );
 
                $handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT );
                $oldContent = is_null( $oldtext ) ? null : $handler->unserializeContent( $oldtext );
@@ -3333,6 +3334,10 @@ class PoolWorkArticleView extends PoolCounterWork {
                } elseif ( $isCurrent ) {
                        #XXX: why use RAW audience here, and PUBLIC (default) below?
                        $content = $this->page->getContent( Revision::RAW );
+                       if ( $content === null ) {
+                               return false;
+                       }
+
                } else {
                        $rev = Revision::newFromTitle( $this->page->getTitle(), $this->revid );
                        if ( $rev === null ) {
index 35019ff..2f8ba0f 100644 (file)
@@ -208,7 +208,7 @@ class Xml {
 
        /**
         * Construct a language selector appropriate for use in a form or preferences
-        * 
+        *
         * @param string $selected The language code of the selected language
         * @param boolean $customisedOnly If true only languages which have some content are listed
         * @param string $inLanguage The ISO code of the language to display the select list in (optional)
index f715229..d0bc22c 100644 (file)
@@ -122,7 +122,7 @@ class CreditsAction extends FormlessAction {
 
                # Sift for real versus user names
                foreach ( $contributors as $user ) {
-                       $cnt--; 
+                       $cnt--;
                        if ( $user->isLoggedIn() ) {
                                $link = $this->link( $user );
                                if ( !in_array( 'realname', $wgHiddenPrefs ) && $user->getRealName() ) {
index a2d49e6..61de3b6 100644 (file)
@@ -158,8 +158,12 @@ class HistoryAction extends FormlessAction {
                } else {
                        $conds = array();
                }
-               $checkDeleted = Xml::checkLabel( $this->msg( 'history-show-deleted' )->text(),
+               if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
+                       $checkDeleted = Xml::checkLabel( $this->msg( 'history-show-deleted' )->text(),
                        'deleted', 'mw-show-deleted-only', $request->getBool( 'deleted' ) ) . "\n";
+               } else {
+                       $checkDeleted = '';
+               }
 
                // Add the general form
                $action = htmlspecialchars( $wgScript );
index a4b0cb7..3adf890 100644 (file)
@@ -58,6 +58,22 @@ class InfoAction extends FormlessAction {
        public function onView() {
                $content = '';
 
+               // Validate revision
+               $oldid = $this->page->getOldID();
+               if ( $oldid ) {
+                       $revision = $this->page->getRevisionFetched();
+
+                       // Revision is missing
+                       if ( $revision === null ) {
+                               return $this->msg( 'missing-revision', $oldid )->parse();
+                       }
+
+                       // Revision is not current
+                       if ( !$revision->isCurrent() ) {
+                               return $this->msg( 'pageinfo-not-current' )->plain();
+                       }
+               }
+
                // Page header
                if ( !$this->msg( 'pageinfo-header' )->isDisabled() ) {
                        $content .= $this->msg( 'pageinfo-header' )->parse();
@@ -75,7 +91,7 @@ class InfoAction extends FormlessAction {
                $pageInfo = $this->pageInfo();
 
                // Allow extensions to add additional information
-               wfRunHooks( 'InfoAction', array( &$pageInfo ) );
+               wfRunHooks( 'InfoAction', array( $this->getContext(), &$pageInfo ) );
 
                // Render page information
                foreach ( $pageInfo as $header => $infoTable ) {
@@ -149,7 +165,7 @@ class InfoAction extends FormlessAction {
         * @return array
         */
        protected function pageInfo() {
-               global $wgContLang, $wgDisableCounters, $wgRCMaxAge;
+               global $wgContLang, $wgRCMaxAge;
 
                $user = $this->getUser();
                $lang = $this->getLanguage();
@@ -157,8 +173,7 @@ class InfoAction extends FormlessAction {
                $id = $title->getArticleID();
 
                // Get page information that would be too "expensive" to retrieve by normal means
-               $userCanViewUnwatchedPages = $user->isAllowed( 'unwatchedpages' );
-               $pageCounts = self::pageCounts( $title, $userCanViewUnwatchedPages, $wgDisableCounters );
+               $pageCounts = self::pageCounts( $title, $user );
 
                // Get page properties
                $dbr = wfGetDB( DB_SLAVE );
@@ -216,14 +231,14 @@ class InfoAction extends FormlessAction {
                        $this->msg( 'pageinfo-robot-policy' ), $this->msg( "pageinfo-robot-${policy['index']}" )
                );
 
-               if ( !$wgDisableCounters ) {
+               if ( isset( $pageCounts['views'] ) ) {
                        // Number of views
                        $pageInfo['header-basic'][] = array(
                                $this->msg( 'pageinfo-views' ), $lang->formatNum( $pageCounts['views'] )
                        );
                }
 
-               if ( $userCanViewUnwatchedPages ) {
+               if ( isset( $pageCounts['watchers'] ) ) {
                        // Number of page watchers
                        $pageInfo['header-basic'][] = array(
                                $this->msg( 'pageinfo-watchers' ), $lang->formatNum( $pageCounts['watchers'] )
@@ -282,6 +297,10 @@ class InfoAction extends FormlessAction {
                        );
                }
 
+               if ( !$this->page->exists() ) {
+                       return $pageInfo;
+               }
+
                // Edit history
                $pageInfo['header-edits'] = array();
 
@@ -402,12 +421,11 @@ class InfoAction extends FormlessAction {
         * Returns page counts that would be too "expensive" to retrieve by normal means.
         *
         * @param $title Title object
-        * @param $canViewUnwatched bool
-        * @param $disableCounter bool
+        * @param $user User object
         * @return array
         */
-       protected static function pageCounts( $title, $canViewUnwatched, $disableCounter ) {
-               global $wgRCMaxAge;
+       protected static function pageCounts( $title, $user ) {
+               global $wgRCMaxAge, $wgDisableCounters;
 
                wfProfileIn( __METHOD__ );
                $id = $title->getArticleID();
@@ -415,7 +433,7 @@ class InfoAction extends FormlessAction {
                $dbr = wfGetDB( DB_SLAVE );
                $result = array();
 
-               if ( !$disableCounter ) {
+               if ( !$wgDisableCounters ) {
                        // Number of views
                        $views = (int) $dbr->selectField(
                                'page',
@@ -426,7 +444,7 @@ class InfoAction extends FormlessAction {
                        $result['views'] = $views;
                }
 
-               if ( $canViewUnwatched ) {
+               if ( $user->isAllowed( 'unwatchedpages' ) ) {
                        // Number of page watchers
                        $watchers = (int) $dbr->selectField(
                                'watchlist',
index 7e7784c..ec3d60a 100644 (file)
@@ -151,8 +151,8 @@ class RawAction extends FormlessAction {
                                $content = $rev->getContent();
 
                                if ( !$content instanceof TextContent ) {
-                                       wfHttpError( 406, "Not Acceptable", "The requested page uses the content model `"
-                                                                                                               . $content->getModel() . "` which is not supported via this interface." );
+                                       wfHttpError( 415, "Unsupported Media Type", "The requested page uses the content model `"
+                                                                               . $content->getModel() . "` which is not supported via this interface." );
                                        die();
                                }
 
index 1fc7e90..a5fc4e1 100644 (file)
@@ -124,7 +124,7 @@ class RevertFileAction extends FormAction {
                $lang = $this->getLanguage();
                $userDate = $lang->userDate( $timestamp, $user );
                $userTime = $lang->userTime( $timestamp, $user );
-       
+
                $this->getOutput()->addWikiMsg( 'filerevert-success', $this->getTitle()->getText(),
                        $userDate, $userTime,
                        wfExpandUrl( $this->page->getFile()->getArchiveUrl( $this->getRequest()->getText( 'oldimage' ) ),
@@ -136,7 +136,7 @@ class RevertFileAction extends FormAction {
        protected function getPageTitle() {
                return $this->msg( 'filerevert', $this->getTitle()->getText() );
        }
-       
+
        protected function getDescription() {
                $this->getOutput()->addBacklinkSubtitle( $this->getTitle() );
                return '';
index 283250c..964e0ae 100644 (file)
@@ -119,7 +119,7 @@ class ApiDelete extends ApiBase {
                        // Need to pass a throwaway variable because generateReason expects
                        // a reference
                        $hasHistory = false;
-                       $reason = $page->getAutoDeleteReason( $hasHistory ); 
+                       $reason = $page->getAutoDeleteReason( $hasHistory );
                        if ( $reason === false ) {
                                return array( array( 'cannotdelete', $title->getPrefixedText() ) );
                        }
index 7d7eb14..3aa51b7 100644 (file)
@@ -840,7 +840,7 @@ class ApiMain extends ApiBase {
        protected function logRequest( $time ) {
                $request = $this->getRequest();
                $milliseconds = $time === null ? '?' : round( $time * 1000 );
-               $s = 'API' . 
+               $s = 'API' .
                        ' ' . $request->getMethod() .
                        ' ' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) .
                        ' ' . $request->getIP() .
@@ -897,7 +897,7 @@ class ApiMain extends ApiBase {
         */
        public function getCheck( $name ) {
                $this->mParamsUsed[$name] = true;
-               return $this->getRequest()->getCheck( $name );          
+               return $this->getRequest()->getCheck( $name );
        }
 
        /**
index 312e439..a29a0bd 100644 (file)
@@ -158,7 +158,7 @@ class ApiParse extends ApiBase {
                                $popts->enableLimitReport( !$params['disablepp'] );
 
                                // Potentially cached
-                               $p_result = $this->getParsedContent( $pageObj, $popts, $pageid, 
+                               $p_result = $this->getParsedContent( $pageObj, $popts, $pageid,
                                        isset( $prop['wikitext'] ) ) ;
                        }
                } else { // Not $oldid, $pageid, $page. Hence based on $text
index 64399b2..dff7524 100644 (file)
@@ -46,6 +46,10 @@ class ApiQuery extends ApiBase {
 
        private $params, $redirects, $convertTitles, $iwUrl;
 
+       /**
+        * List of Api Query prop modules
+        * @var array
+        */
        private $mQueryPropModules = array(
                'categories' => 'ApiQueryCategories',
                'categoryinfo' => 'ApiQueryCategoryInfo',
@@ -63,6 +67,10 @@ class ApiQuery extends ApiBase {
                'templates' => 'ApiQueryLinks',
        );
 
+       /**
+        * List of Api Query list modules
+        * @var array
+        */
        private $mQueryListModules = array(
                'allcategories' => 'ApiQueryAllCategories',
                'allimages' => 'ApiQueryAllImages',
@@ -92,16 +100,52 @@ class ApiQuery extends ApiBase {
                'watchlistraw' => 'ApiQueryWatchlistRaw',
        );
 
+       /**
+        * List of Api Query meta modules
+        * @var array
+        */
        private $mQueryMetaModules = array(
                'allmessages' => 'ApiQueryAllMessages',
                'siteinfo' => 'ApiQuerySiteinfo',
                'userinfo' => 'ApiQueryUserInfo',
        );
 
+       /**
+        * List of Api Query generator modules
+        * Defined in code, rather than being derived at runtime,
+        * due to performance reasons
+        * @var array
+        */
+       private $mQueryGenerators = array(
+               'allcategories' => 'ApiQueryAllCategories',
+               'allimages' => 'ApiQueryAllImages',
+               'alllinks' => 'ApiQueryAllLinks',
+               'allpages' => 'ApiQueryAllPages',
+               'backlinks' => 'ApiQueryBacklinks',
+               'categories' => 'ApiQueryCategories',
+               'categorymembers' => 'ApiQueryCategoryMembers',
+               'duplicatefiles' => 'ApiQueryDuplicateFiles',
+               'embeddedin' => 'ApiQueryBacklinks',
+               'exturlusage' => 'ApiQueryExtLinksUsage',
+               'images' => 'ApiQueryImages',
+               'imageusage' => 'ApiQueryBacklinks',
+               'iwbacklinks' => 'ApiQueryIWBacklinks',
+               'langbacklinks' => 'ApiQueryLangBacklinks',
+               'links' => 'ApiQueryLinks',
+               'protectedtitles' => 'ApiQueryProtectedTitles',
+               'querypage' => 'ApiQueryQueryPage',
+               'random' => 'ApiQueryRandom',
+               'recentchanges' => 'ApiQueryRecentChanges',
+               'search' => 'ApiQuerySearch',
+               'templates' => 'ApiQueryLinks',
+               'watchlist' => 'ApiQueryWatchlist',
+               'watchlistraw' => 'ApiQueryWatchlistRaw',
+       );
+
        private $mSlaveDB = null;
        private $mNamedDB = array();
 
-       protected $mAllowedGenerators = array();
+       protected $mAllowedGenerators;
 
        /**
         * @param $main ApiMain
@@ -111,32 +155,16 @@ class ApiQuery extends ApiBase {
                parent::__construct( $main, $action );
 
                // Allow custom modules to be added in LocalSettings.php
-               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules,
-                       $wgMemc, $wgAPICacheHelpTimeout;
+               global $wgAPIPropModules, $wgAPIListModules, $wgAPIMetaModules, $wgAPIGeneratorModules;
                self::appendUserModules( $this->mQueryPropModules, $wgAPIPropModules );
                self::appendUserModules( $this->mQueryListModules, $wgAPIListModules );
                self::appendUserModules( $this->mQueryMetaModules, $wgAPIMetaModules );
+               self::appendUserModules( $this->mQueryGenerators, $wgAPIGeneratorModules );
 
                $this->mPropModuleNames = array_keys( $this->mQueryPropModules );
                $this->mListModuleNames = array_keys( $this->mQueryListModules );
                $this->mMetaModuleNames = array_keys( $this->mQueryMetaModules );
-
-               // Get array of query generators from cache if present
-               $key = wfMemcKey( 'apiquerygenerators', SpecialVersion::getVersion( 'nodb' ) );
-
-               if ( $wgAPICacheHelpTimeout > 0 ) {
-                       $cached = $wgMemc->get( $key );
-                       if ( $cached ) {
-                               $this->mAllowedGenerators = $cached;
-                               return;
-                       }
-               }
-               $this->makeGeneratorList( $this->mQueryPropModules );
-               $this->makeGeneratorList( $this->mQueryListModules );
-
-               if ( $wgAPICacheHelpTimeout > 0 ) {
-                       $wgMemc->set( $key, $this->mAllowedGenerators, $wgAPICacheHelpTimeout );
-               }
+               $this->mAllowedGenerators = array_keys( $this->mQueryGenerators );
        }
 
        /**
@@ -196,10 +224,18 @@ class ApiQuery extends ApiBase {
         * Get the array mapping module names to class names
         * @return array array(modulename => classname)
         */
-       function getModules() {
+       public function getModules() {
                return array_merge( $this->mQueryPropModules, $this->mQueryListModules, $this->mQueryMetaModules );
        }
 
+       /**
+        * Get the generators array mapping module names to class names
+        * @return array array(modulename => classname)
+        */
+       public function getGenerators() {
+               return $this->mQueryGenerators;
+       }
+
        /**
         * Get whether the specified module is a prop, list or a meta query module
         * @param $moduleName string Name of the module to find type for
@@ -680,19 +716,6 @@ class ApiQuery extends ApiBase {
                return implode( "\n", $moduleDescriptions );
        }
 
-       /**
-        * Adds any classes that are a subclass of ApiQueryGeneratorBase
-        * to the allowed generator list
-        * @param $moduleList array()
-        */
-       private function makeGeneratorList( $moduleList ) {
-               foreach( $moduleList as  $moduleName => $moduleClass ) {
-                       if ( is_subclass_of( $moduleClass, 'ApiQueryGeneratorBase'  ) ) {
-                               $this->mAllowedGenerators[] = $moduleName;
-                       }
-               }
-       }
-
        /**
         * Override to add extra parameters from PageSet
         * @return string
index 4f4c77f..c2beaec 100644 (file)
@@ -81,7 +81,6 @@ class ApiQueryAllCategories extends ApiQueryGeneratorBase {
                } else {
                        $this->addWhereRange( 'cat_pages', 'older', $max, $min);
                }
-    
 
                if ( isset( $params['prefix'] ) ) {
                        $this->addWhere( 'cat_title' . $db->buildLike( $this->titlePartToKey( $params['prefix'] ), $db->anyString() ) );
index a5486ef..dbca1d9 100644 (file)
@@ -64,7 +64,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
                $this->addTables( 'filearchive' );
 
                $this->addFields( array( 'fa_name', 'fa_deleted' ) );
-               $this->addFieldsIf( 'fa_storage_key', $fld_sha1 );
+               $this->addFieldsIf( 'fa_sha1', $fld_sha1 );
                $this->addFieldsIf( 'fa_timestamp', $fld_timestamp );
                $this->addFieldsIf( array( 'fa_user', 'fa_user_text' ), $fld_user );
                $this->addFieldsIf( array( 'fa_height', 'fa_width', 'fa_size' ), $fld_dimensions || $fld_size );
@@ -101,11 +101,6 @@ class ApiQueryFilearchive extends ApiQueryBase {
                $sha1Set = isset( $params['sha1'] );
                $sha1base36Set = isset( $params['sha1base36'] );
                if ( $sha1Set || $sha1base36Set ) {
-                       global $wgMiserMode;
-                       if ( $wgMiserMode  ) {
-                               $this->dieUsage( 'Search by hash disabled in Miser Mode', 'hashsearchdisabled' );
-                       }
-
                        $sha1 = false;
                        if ( $sha1Set ) {
                                if ( !$this->validateSha1Hash( $params['sha1'] ) ) {
@@ -119,7 +114,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
                                $sha1 = $params['sha1base36'];
                        }
                        if ( $sha1 ) {
-                               $this->addWhere( 'fa_storage_key ' . $db->buildLike( "{$sha1}.", $db->anyString() ) );
+                               $this->addWhereFld( 'fa_sha1', $sha1 );
                        }
                }
 
@@ -155,7 +150,7 @@ class ApiQueryFilearchive extends ApiQueryBase {
                        self::addTitleInfo( $file, $title );
 
                        if ( $fld_sha1 ) {
-                               $file['sha1'] = wfBaseConvert( LocalRepo::getHashFromKey( $row->fa_storage_key ), 36, 16, 40 );
+                               $file['sha1'] = wfBaseConvert( $row->fa_sha1, 36, 16, 40 );
                        }
                        if ( $fld_timestamp ) {
                                $file['timestamp'] = wfTimestamp( TS_ISO_8601, $row->fa_timestamp );
@@ -276,8 +271,8 @@ class ApiQueryFilearchive extends ApiQueryBase {
                        'prefix' => 'Search for all image titles that begin with this value',
                        'dir' => 'The direction in which to list',
                        'limit' => 'How many images to return in total',
-                       'sha1' => "SHA1 hash of image. Overrides {$this->getModulePrefix()}sha1base36. Disabled in Miser Mode",
-                       'sha1base36' => 'SHA1 hash of image in base 36 (used in MediaWiki). Disabled in Miser Mode',
+                       'sha1' => "SHA1 hash of image. Overrides {$this->getModulePrefix()}sha1base36",
+                       'sha1base36' => 'SHA1 hash of image in base 36 (used in MediaWiki)',
                        'prop' => array(
                                'What image information to get:',
                                ' sha1              - Adds SHA-1 hash for the image',
index 3a9b5c5..6b8639c 100644 (file)
@@ -86,10 +86,13 @@ class ApiUpload extends ApiBase {
                        if( $this->mParams['filesize'] > $maxSize ) {
                                $this->dieUsage( 'The file you submitted was too large', 'file-too-large' );
                        }
+                       if ( !$this->mUpload->getTitle() ) {
+                               $this->dieUsage( 'Invalid file title supplied', 'internal-error' );
+                       }
                } else {
                        $this->verifyUpload();
                }
+
                // Check if the user has the rights to modify or overwrite the requested title
                // (This check is irrelevant if stashing is already requested, since the errors
                //  can always be fixed by changing the title)
@@ -99,7 +102,7 @@ class ApiUpload extends ApiBase {
                                $this->dieRecoverableError( $permErrors[0], 'filename' );
                        }
                }
-               // Get the result based on the current upload context: 
+               // Get the result based on the current upload context:
                $result = $this->getContextResult();
 
                if ( $result['result'] === 'Success' ) {
@@ -196,7 +199,7 @@ class ApiUpload extends ApiBase {
                                return array();
                        }
 
-                       // Check we added the last chunk: 
+                       // Check we added the last chunk:
                        if( $this->mParams['offset'] + $chunkSize == $this->mParams['filesize'] ) {
                                $status = $this->mUpload->concatenateChunks();
 
@@ -222,7 +225,7 @@ class ApiUpload extends ApiBase {
                $result['offset'] = $this->mParams['offset'] + $chunkSize;
                return $result;
        }
-       
+
        /**
         * Stash the file and return the file key
         * Also re-raises exceptions with slightly more informative message strings (useful for API)
index c0c5609..1a08d9f 100644 (file)
@@ -229,7 +229,7 @@ abstract class FileCacheBase {
        public function incrMissesRecent( WebRequest $request ) {
                global $wgMemc;
                if ( mt_rand( 0, self::MISS_FACTOR - 1 ) == 0 ) {
-                       # Get a large IP range that should include the user  even if that 
+                       # Get a large IP range that should include the user  even if that
                        # person's IP address changes
                        $ip = $request->getIP();
                        if ( !IP::isValid( $ip ) ) {
index 423e388..a4b2002 100644 (file)
@@ -249,7 +249,7 @@ class SquidUpdate {
        static function expand( $url ) {
                return wfExpandUrl( $url, PROTO_INTERNAL );
        }
-       
+
        /**
         * Find the HTCP routing rule to use for a given URL.
         * @param $url string URL to match
@@ -264,5 +264,4 @@ class SquidUpdate {
                }
                return false;
        }
-       
 }
index e2e36ce..d8f644d 100644 (file)
@@ -39,7 +39,7 @@ class DatabaseConf extends Conf {
         *
         * @param $name
         * @param $value
-        * 
+        *
         * @return bool
         */
        protected function writeSetting( $name, $value ) {
index 00761cf..4bb4e40 100644 (file)
@@ -28,6 +28,15 @@ class MWContentSerializationException extends MWException {
  */
 abstract class ContentHandler {
 
+       /**
+        * Switch for enabling deprecation warnings. Used by ContentHandler::deprecated()
+        * and ContentHandler::runLegacyHooks().
+        *
+        * Once the ContentHandler code has settled in a bit, this should be set to true to
+        * make extensions etc. show warnings when using deprecated functions and hooks.
+        */
+       protected static $enableDeprecationWarnings = false;
+
        /**
         * Convenience function for getting flat text from a Content object. This
         * should only be used in the context of backwards compatibility with code
@@ -50,7 +59,6 @@ abstract class ContentHandler {
         * - otherwise, the behaviour is undefined.
         *
         * @since 1.21
-        * @deprecated since 1.21. Always try to use the content object.
         *
         * @static
         * @param $content Content|null
@@ -294,7 +302,7 @@ abstract class ContentHandler {
                        wfRunHooks( 'ContentHandlerForModelID', array( $modelId, &$handler ) );
 
                        if ( $handler === null ) {
-                               throw new MWException( "No handler for model #$modelId registered in \$wgContentHandlers" );
+                               throw new MWException( "No handler for model '$modelId'' registered in \$wgContentHandlers" );
                        }
 
                        if ( !( $handler instanceof ContentHandler ) ) {
@@ -951,6 +959,25 @@ abstract class ContentHandler {
                return false;
        }
 
+       /**
+        * Logs a deprecation warning, visible if $wgDevelopmentWarnings, but only if
+        * self::$enableDeprecationWarnings is set to true.
+        *
+        * @param String      $func The name of the deprecated function
+        * @param string      $version The version since the method is deprecated. Usually 1.21
+        *                    for ContentHandler related stuff.
+        * @param String|bool $component: Component to which the function belongs.
+        *                                If false, it is assumed the function is in MediaWiki core.
+        *
+        * @see ContentHandler::$enableDeprecationWarnings
+        * @see wfDeprecated
+        */
+       public static function deprecated( $func, $version, $component = false ) {
+               if ( self::$enableDeprecationWarnings ) {
+                       wfDeprecated( $func, $version, $component, 3 );
+               }
+       }
+
        /**
         * Call a legacy hook that uses text instead of Content objects.
         * Will log a warning when a matching hook function is registered.
@@ -960,15 +987,22 @@ abstract class ContentHandler {
         *
         * @param $event String: event name
         * @param $args Array: parameters passed to hook functions
-        * @param $warn bool: whether to log a warning (default: true). Should generally be true,
-        *                    may be set to false for testing.
+        * @param $warn bool: whether to log a warning.
+        *                    Default to self::$enableDeprecationWarnings.
+        *                    May be set to false for testing.
         *
         * @return Boolean True if no handler aborted the hook
+        *
+        * @see ContentHandler::$enableDeprecationWarnings
         */
-       public static function runLegacyHooks( $event, $args = array(), $warn = true ) {
-               global $wgHooks; //@todo: once I39bd5de2 is merged, direct access to $wgHooks is no longer needed.
+       public static function runLegacyHooks( $event, $args = array(),
+                       $warn = null ) {
+
+               if ( $warn === null ) {
+                       $warn = self::$enableDeprecationWarnings;
+               }
 
-               if ( !Hooks::isRegistered( $event ) && empty( $wgHooks[$event] ) ) {
+               if ( !Hooks::isRegistered( $event ) ) {
                        return true; // nothing to do here
                }
 
@@ -1050,9 +1084,9 @@ abstract class ContentHandler {
 /**
  * @since 1.21
  */
-abstract class TextContentHandler extends ContentHandler {
+class TextContentHandler extends ContentHandler {
 
-       public function __construct( $modelId, $formats ) {
+       public function __construct( $modelId = CONTENT_MODEL_TEXT, $formats = array( CONTENT_FORMAT_TEXT ) ) {
                parent::__construct( $modelId, $formats );
        }
 
@@ -1108,6 +1142,32 @@ abstract class TextContentHandler extends ContentHandler {
                return $mergedContent;
        }
 
+       /**
+        * Unserializes a Content object of the type supported by this ContentHandler.
+        *
+        * @since 1.21
+        *
+        * @param $text   string serialized form of the content
+        * @param $format null|String the format used for serialization
+        *
+        * @return Content the TextContent object wrapping $text
+        */
+       public function unserializeContent( $text, $format = null ) {
+               $this->checkFormat( $format );
+
+               return new TextContent( $text );
+       }
+
+       /**
+        * Creates an empty TextContent object.
+        *
+        * @since 1.21
+        *
+        * @return Content
+        */
+       public function makeEmptyContent() {
+               return new TextContent( '' );
+       }
 }
 
 /**
index 68e6c39..9baa7ab 100644 (file)
@@ -7,11 +7,15 @@
  *
  * @since 1.21
  */
-abstract class TextContent extends AbstractContent {
+class TextContent extends AbstractContent {
 
-       public function __construct( $text, $model_id = null ) {
+       public function __construct( $text, $model_id = CONTENT_MODEL_TEXT ) {
                parent::__construct( $model_id );
 
+               if ( !is_string( $text ) ) {
+                       throw new MWException( "TextContent expects a string in the constructor." );
+               }
+
                $this->mText = $text;
        }
 
@@ -177,4 +181,4 @@ abstract class TextContent extends AbstractContent {
                # TODO: make Highlighter interface, use highlighter here, if available
                return htmlspecialchars( $this->getNativeData() );
        }
-}
\ No newline at end of file
+}
index b660fc0..a17bf31 100644 (file)
@@ -17,7 +17,11 @@ class WikitextContent extends TextContent {
                $text = $this->getNativeData();
                $sect = $wgParser->getSection( $text, $section, false );
 
-               return new WikitextContent( $sect );
+               if ( $sect === false ) {
+                       return false;
+               } else {
+                       return new WikitextContent( $sect );
+               }
        }
 
        /**
@@ -286,4 +290,4 @@ class WikitextContent extends TextContent {
        public function matchMagicWord( MagicWord $word ) {
                return $word->match( $this->getNativeData() );
        }
-}
\ No newline at end of file
+}
index 45bd6ff..d5a6d15 100644 (file)
@@ -165,6 +165,4 @@ abstract class ContextSource implements IContextSource {
                $args = func_get_args();
                return call_user_func_array( array( $this->getContext(), 'msg' ), $args );
        }
-       
 }
-
index a528f22..cd2bf55 100644 (file)
@@ -307,7 +307,7 @@ class RequestContext implements IContextSource {
        public function getSkin() {
                if ( $this->skin === null ) {
                        wfProfileIn( __METHOD__ . '-createskin' );
-                       
+
                        $skin = null;
                        wfRunHooks( 'RequestContextCreateSkin', array( $this, &$skin ) );
 
@@ -397,4 +397,3 @@ class RequestContext implements IContextSource {
        }
 
 }
-
index 4e43642..4ff7913 100644 (file)
@@ -87,18 +87,17 @@ class CloneDatabase {
         * Clone the table structure
         */
        public function cloneTableStructure() {
-               
                foreach( $this->tablesToClone as $tbl ) {
                        # Clean up from previous aborted run.  So that table escaping
                        # works correctly across DB engines, we need to change the pre-
                        # fix back and forth so tableName() works right.
-                       
+
                        self::changePrefix( $this->oldTablePrefix );
                        $oldTableName = $this->db->tableName( $tbl, 'raw' );
-                       
+
                        self::changePrefix( $this->newTablePrefix );
                        $newTableName = $this->db->tableName( $tbl, 'raw' );
-                       
+
                        if( $this->dropCurrentTables && !in_array( $this->db->getType(), array( 'postgres', 'oracle' ) ) ) {
                                $this->db->dropTable( $tbl, __METHOD__ );
                                wfDebug( __METHOD__." dropping {$newTableName}\n", true);
@@ -108,9 +107,7 @@ class CloneDatabase {
                        # Create new table
                        wfDebug( __METHOD__." duplicating $oldTableName to $newTableName\n", true );
                        $this->db->duplicateTableStructure( $oldTableName, $newTableName, $this->useTemporaryTables );
-                       
                }
-               
        }
 
        /**
index 99413f9..9693789 100644 (file)
@@ -298,6 +298,72 @@ interface IORMTable {
         */
        public function setReadDb( $db );
 
+
+       /**
+        * Get the ID of the any foreign wiki to use as a target for database operations
+        *
+        * @since 1.20
+        *
+        * @return String|bool The target wiki, in a form that  LBFactory understands (or false if the local wiki is used)
+        */
+       public function getTargetWiki();
+
+       /**
+        * Set the ID of the any foreign wiki to use as a target for database operations
+        *
+        * @param String|bool $wiki The target wiki, in a form that  LBFactory understands (or false if the local wiki shall be used)
+        *
+        * @since 1.20
+        */
+       public function setTargetWiki( $wiki );
+
+       /**
+        * Get the database type used for read operations.
+        * This is to be used instead of wfGetDB.
+        *
+        * @see LoadBalancer::getConnection
+        *
+        * @since 1.20
+        *
+        * @return DatabaseBase The database object
+        */
+       public function getReadDbConnection();
+
+       /**
+        * Get the database type used for read operations.
+        * This is to be used instead of wfGetDB.
+        *
+        * @see LoadBalancer::getConnection
+        *
+        * @since 1.20
+        *
+        * @return DatabaseBase The database object
+        */
+       public function getWriteDbConnection();
+
+       /**
+        * Get the database type used for read operations.
+        *
+        * @see wfGetLB
+        *
+        * @since 1.20
+        *
+        * @return LoadBalancer The database load balancer object
+        */
+       public function getLoadBalancer();
+
+       /**
+        * Releases the lease on the given database connection. This is useful mainly
+        * for connections to a foreign wiki. It does nothing for connections to the local wiki.
+        *
+        * @see LoadBalancer::reuseConnection
+        *
+        * @param DatabaseBase $db the database
+        *
+        * @since 1.20
+        */
+       public function releaseConnection( DatabaseBase $db );
+
        /**
         * Update the records matching the provided conditions by
         * setting the fields that are keys in the $values param to
index a77074f..e3a3434 100644 (file)
@@ -47,7 +47,7 @@ abstract class ORMTable implements IORMTable {
        protected static $instanceCache = array();
 
        /**
-        * The database connection to use for read operations.
+        * ID of the database connection to use for read operations.
         * Can be changed via @see setReadDb.
         *
         * @since 1.20
@@ -55,6 +55,15 @@ abstract class ORMTable implements IORMTable {
         */
        protected $readDb = DB_SLAVE;
 
+       /**
+        * The ID of any foreign wiki to use as a target for database operations,
+        * or false to use the local wiki.
+        *
+        * @since 1.20
+        * @var String|bool
+        */
+       protected $wiki = false;
+
        /**
         * Returns a list of default field values.
         * field name => field value
@@ -145,13 +154,17 @@ abstract class ORMTable implements IORMTable {
                        $fields = (array)$fields;
                }
 
-               return wfGetDB( $this->getReadDb() )->select(
+               $dbr = $this->getReadDbConnection();
+               $result = $dbr->select(
                        $this->getName(),
                        $this->getPrefixedFields( $fields ),
                        $this->getPrefixedValues( $conditions ),
                        is_null( $functionName ) ? __METHOD__ : $functionName,
                        $options
                );
+
+               $this->releaseConnection( $dbr );
+               return $result;
        }
 
        /**
@@ -241,15 +254,18 @@ abstract class ORMTable implements IORMTable {
         */
        public function rawSelectRow( array $fields, array $conditions = array(),
                                                                  array $options = array(), $functionName = null ) {
-               $dbr = wfGetDB( $this->getReadDb() );
+               $dbr = $this->getReadDbConnection();
 
-               return $dbr->selectRow(
+               $result = $dbr->selectRow(
                        $this->getName(),
                        $fields,
                        $conditions,
                        is_null( $functionName ) ? __METHOD__ : $functionName,
                        $options
                );
+
+               $this->releaseConnection( $dbr );
+               return $result;
        }
 
        /**
@@ -327,13 +343,18 @@ abstract class ORMTable implements IORMTable {
         * @return boolean Success indicator
         */
        public function delete( array $conditions, $functionName = null ) {
-               return wfGetDB( DB_MASTER )->delete(
+               $dbw = $this->getWriteDbConnection();
+
+               $result = $dbw->delete(
                        $this->getName(),
                        $conditions === array() ? '*' : $this->getPrefixedValues( $conditions ),
                        $functionName
                ) !== false; // DatabaseBase::delete does not always return true for success as documented...
+
+               $this->releaseConnection( $dbw );
+               return $result;
        }
-       
+
        /**
         * Get API parameters for the fields supported by this object.
         *
@@ -397,7 +418,7 @@ abstract class ORMTable implements IORMTable {
        }
 
        /**
-        * Get the database type used for read operations.
+        * Get the database ID used for read operations.
         *
         * @since 1.20
         *
@@ -408,7 +429,7 @@ abstract class ORMTable implements IORMTable {
        }
 
        /**
-        * Set the database type to use for read operations.
+        * Set the database ID to use for read operations, use DB_XXX constants or an index to the load balancer setup.
         *
         * @param integer $db
         *
@@ -418,6 +439,86 @@ abstract class ORMTable implements IORMTable {
                $this->readDb = $db;
        }
 
+       /**
+        * Get the ID of the any foreign wiki to use as a target for database operations
+        *
+        * @since 1.20
+        *
+        * @return String|bool The target wiki, in a form that  LBFactory understands (or false if the local wiki is used)
+        */
+       public function getTargetWiki() {
+               return $this->wiki;
+       }
+
+       /**
+        * Set the ID of the any foreign wiki to use as a target for database operations
+        *
+        * @param String|bool $wiki The target wiki, in a form that  LBFactory understands (or false if the local wiki shall be used)
+        *
+        * @since 1.20
+        */
+       public function setTargetWiki( $wiki ) {
+               $this->wiki = $wiki;
+       }
+
+       /**
+        * Get the database type used for read operations.
+        * This is to be used instead of wfGetDB.
+        *
+        * @see LoadBalancer::getConnection
+        *
+        * @since 1.20
+        *
+        * @return DatabaseBase The database object
+        */
+       public function getReadDbConnection() {
+               return $this->getLoadBalancer()->getConnection( $this->getReadDb(), array(), $this->getTargetWiki() );
+       }
+
+       /**
+        * Get the database type used for read operations.
+        * This is to be used instead of wfGetDB.
+        *
+        * @see LoadBalancer::getConnection
+        *
+        * @since 1.20
+        *
+        * @return DatabaseBase The database object
+        */
+       public function getWriteDbConnection() {
+               return $this->getLoadBalancer()->getConnection( DB_MASTER, array(), $this->getTargetWiki() );
+       }
+
+       /**
+        * Get the database type used for read operations.
+        *
+        * @see wfGetLB
+        *
+        * @since 1.20
+        *
+        * @return LoadBalancer The database load balancer object
+        */
+       public function getLoadBalancer() {
+               return wfGetLB( $this->getTargetWiki() );
+       }
+
+       /**
+        * Releases the lease on the given database connection. This is useful mainly
+        * for connections to a foreign wiki. It does nothing for connections to the local wiki.
+        *
+        * @see LoadBalancer::reuseConnection
+        *
+        * @param DatabaseBase $db the database
+        *
+        * @since 1.20
+        */
+       public function releaseConnection( DatabaseBase $db ) {
+               if ( $this->wiki !== false ) {
+                       // recycle connection to foreign wiki
+                       $this->getLoadBalancer()->reuseConnection( $db );
+               }
+       }
+
        /**
         * Update the records matching the provided conditions by
         * setting the fields that are keys in the $values param to
@@ -431,14 +532,17 @@ abstract class ORMTable implements IORMTable {
         * @return boolean Success indicator
         */
        public function update( array $values, array $conditions = array() ) {
-               $dbw = wfGetDB( DB_MASTER );
+               $dbw = $this->getWriteDbConnection();
 
-               return $dbw->update(
+               $result = $dbw->update(
                        $this->getName(),
                        $this->getPrefixedValues( $values ),
                        $this->getPrefixedValues( $conditions ),
                        __METHOD__
                ) !== false; // DatabaseBase::update does not always return true for success as documented...
+
+               $this->releaseConnection( $dbw );
+               return $result;
        }
 
        /**
@@ -450,6 +554,7 @@ abstract class ORMTable implements IORMTable {
         * @param array $conditions
         */
        public function updateSummaryFields( $summaryFields = null, array $conditions = array() ) {
+               $slave = $this->getReadDb();
                $this->setReadDb( DB_MASTER );
 
                /**
@@ -461,7 +566,7 @@ abstract class ORMTable implements IORMTable {
                        $item->save();
                }
 
-               $this->setReadDb( DB_SLAVE );
+               $this->setReadDb( $slave );
        }
 
        /**
index 18dcfe9..f3dc5a3 100644 (file)
@@ -544,8 +544,19 @@ class DifferenceEngine extends ContextSource {
 
                                $parserOutput = $this->getParserOutput( $wikiPage, $this->mNewRev );
 
-                               # WikiPage::getParserOutput() should not return false, but just in case
-                               if( $parserOutput ) {
+                               # Also try to load it as a redirect
+                               $rt = $this->mNewContent->getRedirectTarget();
+
+                               if ( $rt ) {
+                                       $article = Article::newFromTitle( $this->mNewPage, $this->getContext() );
+                                       $out->addHTML( $article->viewRedirect( $rt ) );
+
+                                       # WikiPage::getParserOutput() should not return false, but just in case
+                                       if ( $parserOutput ) {
+                                               # Show categories etc.
+                                               $out->addParserOutputNoText( $parserOutput );
+                                       }
+                               } else if ( $parserOutput ) {
                                        $out->addParserOutput( $parserOutput );
                                }
                        }
@@ -703,12 +714,19 @@ class DifferenceEngine extends ContextSource {
        /**
         * Generate a diff, no caching.
         *
-        * Subclasses may override this to provide a
+        * This implementation uses generateTextDiffBody() to generate a diff based on the default
+        * serialization of the given Content objects. This will fail if $old or $new are not
+        * instances of TextContent.
+        *
+        * Subclasses may override this to provide a different rendering for the diff,
+        * perhaps taking advantage of the content's native form. This is required for all content
+        * models that are not text based.
         *
         * @param $old Content: old content
         * @param $new Content: new content
         *
         * @since 1.21
+        * @throws MWException if $old or $new are not instances of TextContent.
         */
        function generateContentDiffBody( Content $old, Content $new ) {
                if ( !( $old instanceof TextContent ) ) {
@@ -735,7 +753,7 @@ class DifferenceEngine extends ContextSource {
         * @deprecated since 1.21, use generateContentDiffBody() instead!
         */
        function generateDiffBody( $otext, $ntext ) {
-               wfDeprecated( __METHOD__, "1.21" );
+               ContentHandler::deprecated( __METHOD__, "1.21" );
 
                return $this->generateTextDiffBody( $otext, $ntext );
        }
@@ -1007,7 +1025,7 @@ class DifferenceEngine extends ContextSource {
         * @deprecated since 1.21, use setContent() instead.
         */
        function setText( $oldText, $newText ) {
-               wfDeprecated( __METHOD__, "1.21" );
+               ContentHandler::deprecated( __METHOD__, "1.21" );
 
                $oldContent = ContentHandler::makeContent( $oldText, $this->getTitle() );
                $newContent = ContentHandler::makeContent( $newText, $this->getTitle() );
index c9751be..694623b 100644 (file)
@@ -47,6 +47,7 @@ class ArchivedFile {
                $timestamp, # time of upload
                $dataLoaded, # Whether or not all this has been loaded from the database (loadFromXxx)
                $deleted, # Bitfield akin to rev_deleted
+               $sha1, # sha1 hash of file content
                $pageCount,
                $archive_name;
 
@@ -87,6 +88,7 @@ class ArchivedFile {
                $this->deleted = 0;
                $this->dataLoaded = false;
                $this->exists = false;
+               $this->sha1 = '';
 
                if( $title instanceof Title ) {
                        $this->title = File::normalizeTitle( $title, 'exception' );
@@ -153,7 +155,8 @@ class ArchivedFile {
                                        'fa_user',
                                        'fa_user_text',
                                        'fa_timestamp',
-                                       'fa_deleted' ),
+                                       'fa_deleted',
+                                       'fa_sha1' ),
                                $conds,
                                __METHOD__,
                                array( 'ORDER BY' => 'fa_timestamp DESC' ) );
@@ -165,23 +168,7 @@ class ArchivedFile {
                        $row = $ret->fetchObject();
 
                        // initialize fields for filestore image object
-                       $this->id = intval($row->fa_id);
-                       $this->name = $row->fa_name;
-                       $this->archive_name = $row->fa_archive_name;
-                       $this->group = $row->fa_storage_group;
-                       $this->key = $row->fa_storage_key;
-                       $this->size = $row->fa_size;
-                       $this->bits = $row->fa_bits;
-                       $this->width = $row->fa_width;
-                       $this->height = $row->fa_height;
-                       $this->metadata = $row->fa_metadata;
-                       $this->mime = "$row->fa_major_mime/$row->fa_minor_mime";
-                       $this->media_type = $row->fa_media_type;
-                       $this->description = $row->fa_description;
-                       $this->user = $row->fa_user;
-                       $this->user_text = $row->fa_user_text;
-                       $this->timestamp = $row->fa_timestamp;
-                       $this->deleted = $row->fa_deleted;
+                       $this->loadFromRow( $row );
                } else {
                        throw new MWException( 'This title does not correspond to an image page.' );
                }
@@ -200,28 +187,42 @@ class ArchivedFile {
         */
        public static function newFromRow( $row ) {
                $file = new ArchivedFile( Title::makeTitle( NS_FILE, $row->fa_name ) );
-
-               $file->id = intval($row->fa_id);
-               $file->name = $row->fa_name;
-               $file->archive_name = $row->fa_archive_name;
-               $file->group = $row->fa_storage_group;
-               $file->key = $row->fa_storage_key;
-               $file->size = $row->fa_size;
-               $file->bits = $row->fa_bits;
-               $file->width = $row->fa_width;
-               $file->height = $row->fa_height;
-               $file->metadata = $row->fa_metadata;
-               $file->mime = "$row->fa_major_mime/$row->fa_minor_mime";
-               $file->media_type = $row->fa_media_type;
-               $file->description = $row->fa_description;
-               $file->user = $row->fa_user;
-               $file->user_text = $row->fa_user_text;
-               $file->timestamp = $row->fa_timestamp;
-               $file->deleted = $row->fa_deleted;
-
+               $file->loadFromRow( $row );
                return $file;
        }
 
+       /**
+        * Load ArchivedFile object fields from a DB row.
+        *
+        * @param $row Object database row
+        * @since 1.21
+        */
+       public function loadFromRow( $row ) {
+               $this->id = intval($row->fa_id);
+               $this->name = $row->fa_name;
+               $this->archive_name = $row->fa_archive_name;
+               $this->group = $row->fa_storage_group;
+               $this->key = $row->fa_storage_key;
+               $this->size = $row->fa_size;
+               $this->bits = $row->fa_bits;
+               $this->width = $row->fa_width;
+               $this->height = $row->fa_height;
+               $this->metadata = $row->fa_metadata;
+               $this->mime = "$row->fa_major_mime/$row->fa_minor_mime";
+               $this->media_type = $row->fa_media_type;
+               $this->description = $row->fa_description;
+               $this->user = $row->fa_user;
+               $this->user_text = $row->fa_user_text;
+               $this->timestamp = $row->fa_timestamp;
+               $this->deleted = $row->fa_deleted;
+               if( isset( $row->fa_sha1 ) ) {
+                       $this->sha1 = $row->fa_sha1;
+               } else {
+                       // old row, populate from key
+                       $this->sha1 = LocalRepo::getHashFromKey( $this->key );
+               }
+       }
+
        /**
         * Return the associated title object
         *
@@ -381,6 +382,17 @@ class ArchivedFile {
                return wfTimestamp( TS_MW, $this->timestamp );
        }
 
+       /**
+        * Get the SHA-1 base 36 hash of the file
+        *
+        * @return string
+        * @since 1.21
+        */
+       function getSha1() {
+               $this->load();
+               return $this->sha1;
+       }
+
        /**
         * Return the user ID of the uploader.
         *
index 05958d6..caa93a4 100644 (file)
@@ -1774,7 +1774,8 @@ class LocalFileDeleteBatch {
                                        'fa_description'  => 'img_description',
                                        'fa_user'         => 'img_user',
                                        'fa_user_text'    => 'img_user_text',
-                                       'fa_timestamp'    => 'img_timestamp'
+                                       'fa_timestamp'    => 'img_timestamp',
+                                       'fa_sha1'         => 'img_sha1',
                                ), $where, __METHOD__ );
                }
 
@@ -1806,6 +1807,7 @@ class LocalFileDeleteBatch {
                                        'fa_user'         => 'oi_user',
                                        'fa_user_text'    => 'oi_user_text',
                                        'fa_timestamp'    => 'oi_timestamp',
+                                       'fa_sha1'         => 'oi_sha1',
                                ), $where, __METHOD__ );
                }
        }
@@ -2038,7 +2040,12 @@ class LocalFileRestoreBatch {
                        $deletedRel = $this->file->repo->getDeletedHashPath( $row->fa_storage_key ) . $row->fa_storage_key;
                        $deletedUrl = $this->file->repo->getVirtualUrl() . '/deleted/' . $deletedRel;
 
-                       $sha1 = substr( $row->fa_storage_key, 0, strcspn( $row->fa_storage_key, '.' ) );
+                       if( isset( $row->fa_sha1 ) ) {
+                               $sha1 = $row->fa_sha1;
+                       } else {
+                               // old row, populate from key
+                               $sha1 = LocalRepo::getHashFromKey( $row->fa_storage_key );
+                       }
 
                        # Fix leading zero
                        if ( strlen( $sha1 ) == 32 && $sha1[0] == '0' ) {
index a575334..7223003 100644 (file)
@@ -54,12 +54,17 @@ abstract class DatabaseUpdater {
 
        protected $shared = false;
 
+       /**
+        * Scripts to run after database update
+        * Should be a subclass of LoggedUpdateMaintenance
+        */
        protected $postDatabaseUpdateMaintenance = array(
                'DeleteDefaultMessages',
                'PopulateRevisionLength',
                'PopulateRevisionSha1',
                'PopulateImageSha1',
                'FixExtLinksProtocolRelative',
+               'PopulateFilearchiveSha1',
        );
 
        /**
@@ -254,6 +259,8 @@ abstract class DatabaseUpdater {
        /**
         * Add a maintenance script to be run after the database updates are complete.
         *
+        * Script should subclass LoggedUpdateMaintenance
+        *
         * @since 1.19
         *
         * @param $class string Name of a Maintenance subclass
index 3a42953..805ff0f 100644 (file)
@@ -77,7 +77,7 @@ class Ibm_db2Updater extends DatabaseUpdater {
                        array( 'modifyField', 'user_properties', 'up_property', 'patch-up_property.sql' ),
                        array( 'addTable', 'uploadstash',                       'patch-uploadstash.sql' ),
                        array( 'addTable', 'user_former_groups',                'patch-user_former_groups.sql'),
-                       array( 'doRebuildLocalisationCache' ), 
+                       array( 'doRebuildLocalisationCache' ),
 
                        // 1.19
                        array( 'addIndex', 'logging',       'type_action',      'patch-logging-type-action-index.sql'),
index 00009ca..a6cb13f 100644 (file)
@@ -206,7 +206,6 @@ class MysqlUpdater extends DatabaseUpdater {
                        array( 'modifyField', 'user_groups', 'ug_group', 'patch-ug_group-length-increase.sql' ),
                        array( 'addField',      'uploadstash',  'us_chunk_inx',         'patch-uploadstash_chunk.sql' ),
                        array( 'addfield', 'job',           'job_timestamp',    'patch-jobs-add-timestamp.sql' ),
-
                        array( 'modifyField', 'user_former_groups', 'ufg_group', 'patch-ufg_group-length-increase.sql' ),
 
                        // 1.20
@@ -224,6 +223,8 @@ class MysqlUpdater extends DatabaseUpdater {
                        array( 'addField',      'page',     'page_content_model',               'patch-page-page_content_model.sql' ),
                        array( 'dropField', 'site_stats',   'ss_admins',        'patch-drop-ss_admins.sql' ),
                        array( 'dropField', 'recentchanges', 'rc_moved_to_title',            'patch-rc_moved.sql' ),
+                       array( 'addTable', 'sites',                            'patch-sites.sql' ),
+                       array( 'addField', 'filearchive',   'fa_sha1',          'patch-fa_sha1.sql' ),
                );
        }
 
index 72ec800..845816e 100644 (file)
@@ -40,7 +40,7 @@ class OracleInstaller extends DatabaseInstaller {
        protected $internalDefaults = array(
                '_OracleDefTS' => 'USERS',
                '_OracleTempTS' => 'TEMP',
-               '_InstallUser' => 'SYSDBA',
+               '_InstallUser' => 'SYSTEM',
        );
 
        public $minimumVersion = '9.0.1'; // 9iR1
index 2f20135..f946d59 100644 (file)
@@ -70,6 +70,7 @@ class OracleUpdater extends DatabaseUpdater {
                        array( 'addTable', 'config', 'patch-config.sql' ),
                        array( 'addIndex', 'ipblocks', 'i05', 'patch-ipblocks_i05_index.sql' ),
                        array( 'addIndex', 'revision', 'i05', 'patch-revision_i05_index.sql' ),
+                       array( 'dropField', 'category', 'cat_hidden', 'patch-cat_hidden.sql' ),
 
                        //1.21
                        array( 'addField',      'revision',     'rev_content_format',           'patch-revision-rev_content_format.sql' ),
@@ -77,6 +78,8 @@ class OracleUpdater extends DatabaseUpdater {
                        array( 'addField',      'archive',      'ar_content_format',            'patch-archive-ar_content_format.sql' ),
                        array( 'addField',      'archive',      'ar_content_model',                 'patch-archive-ar_content_model.sql' ),
                        array( 'addField',      'page',     'page_content_model',               'patch-page-page_content_model.sql' ),
+                       array( 'dropField', 'site_stats', 'ss_admins',  'patch-ss_admins.sql' ),
+                       array( 'dropField', 'recentchanges', 'rc_moved_to_title', 'patch-rc_moved.sql' ),
 
                        // KEEP THIS AT THE BOTTOM!!
                        array( 'doRebuildDuplicateFunction' ),
index 499a2d6..9ad91b7 100644 (file)
@@ -101,6 +101,8 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgField', 'archive',       'ar_len',               'INTEGER' ),
                        array( 'addPgField', 'archive',       'ar_page_id',           'INTEGER' ),
                        array( 'addPgField', 'archive',       'ar_parent_id',         'INTEGER' ),
+                       array( 'addPgField', 'archive',       'ar_content_model',     'TEXT' ),
+                       array( 'addPgField', 'archive',       'ar_content_format',    'TEXT' ),
                        array( 'addPgField', 'categorylinks', 'cl_sortkey_prefix',    "TEXT NOT NULL DEFAULT ''"),
                        array( 'addPgField', 'categorylinks', 'cl_collation',         "TEXT NOT NULL DEFAULT 0"),
                        array( 'addPgField', 'categorylinks', 'cl_type',              "TEXT NOT NULL DEFAULT 'page'"),
@@ -125,6 +127,7 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgField', 'oldimage',      'oi_metadata',          "BYTEA NOT NULL DEFAULT ''" ),
                        array( 'addPgField', 'oldimage',      'oi_minor_mime',        "TEXT NOT NULL DEFAULT 'unknown'" ),
                        array( 'addPgField', 'oldimage',      'oi_sha1',              "TEXT NOT NULL DEFAULT ''" ),
+                       array( 'addPgField', 'page',          'page_content_model',   'TEXT' ),
                        array( 'addPgField', 'page_restrictions', 'pr_id',            "INTEGER NOT NULL UNIQUE DEFAULT nextval('page_restrictions_pr_id_seq')" ),
                        array( 'addPgField', 'profiling',     'pf_memory',            'NUMERIC(18,10) NOT NULL DEFAULT 0' ),
                        array( 'addPgField', 'recentchanges', 'rc_deleted',           'SMALLINT NOT NULL DEFAULT 0' ),
@@ -139,6 +142,8 @@ class PostgresUpdater extends DatabaseUpdater {
                        array( 'addPgField', 'revision',      'rev_deleted',          'SMALLINT NOT NULL DEFAULT 0' ),
                        array( 'addPgField', 'revision',      'rev_len',              'INTEGER' ),
                        array( 'addPgField', 'revision',      'rev_parent_id',        'INTEGER DEFAULT NULL' ),
+                       array( 'addPgField', 'revision',      'rev_content_model',    'TEXT' ),
+                       array( 'addPgField', 'revision',      'rev_content_format',   'TEXT' ),
                        array( 'addPgField', 'site_stats',    'ss_active_users',      "INTEGER DEFAULT '-1'" ),
                        array( 'addPgField', 'user_newtalk',  'user_last_timestamp',  'TIMESTAMPTZ' ),
                        array( 'addPgField', 'logging',       'log_user_text',        "TEXT NOT NULL DEFAULT ''" ),
index e26aa78..e7f3939 100644 (file)
@@ -85,7 +85,6 @@ class SqliteUpdater extends DatabaseUpdater {
                        array( 'modifyField', 'user_groups', 'ug_group', 'patch-ug_group-length-increase.sql' ),
                        array( 'addField',      'uploadstash',  'us_chunk_inx',         'patch-uploadstash_chunk.sql' ),
                        array( 'addfield', 'job',           'job_timestamp',    'patch-jobs-add-timestamp.sql' ),
-
                        array( 'modifyField', 'user_former_groups', 'ufg_group', 'patch-ug_group-length-increase.sql' ),
 
                        // 1.20
@@ -104,6 +103,8 @@ class SqliteUpdater extends DatabaseUpdater {
 
                        array( 'dropField', 'site_stats',    'ss_admins',         'patch-drop-ss_admins.sql' ),
                        array( 'dropField', 'recentchanges', 'rc_moved_to_title', 'patch-rc_moved.sql' ),
+                       array( 'addTable', 'sites',                            'patch-sites.sql' ),
+                       array( 'addField', 'filearchive',   'fa_sha1',          'patch-fa_sha1.sql' ),
                );
        }
 
index 37560d8..2ca525e 100644 (file)
@@ -335,9 +335,9 @@ class ManualLogEntry extends LogEntryBase {
 
        /**
         * Constructor.
-        * 
+        *
         * @since 1.19
-        * 
+        *
         * @param string $type
         * @param string $subtype
         */
@@ -357,9 +357,9 @@ class ManualLogEntry extends LogEntryBase {
         *   '4:color' => 'blue',
         *   'animal' => 'dog'
         * );
-        * 
+        *
         * @since 1.19
-        * 
+        *
         * @param $parameters array Associative array
         */
        public function setParameters( $parameters ) {
@@ -368,9 +368,9 @@ class ManualLogEntry extends LogEntryBase {
 
        /**
         * Set the user that performed the action being logged.
-        * 
+        *
         * @since 1.19
-        * 
+        *
         * @param User $performer
         */
        public function setPerformer( User $performer ) {
@@ -379,9 +379,9 @@ class ManualLogEntry extends LogEntryBase {
 
        /**
         * Set the title of the object changed.
-        * 
+        *
         * @since 1.19
-        * 
+        *
         * @param Title $target
         */
        public function setTarget( Title $target ) {
@@ -390,9 +390,9 @@ class ManualLogEntry extends LogEntryBase {
 
        /**
         * Set the timestamp of when the logged action took place.
-        * 
+        *
         * @since 1.19
-        * 
+        *
         * @param string $timestamp
         */
        public function setTimestamp( $timestamp ) {
@@ -401,9 +401,9 @@ class ManualLogEntry extends LogEntryBase {
 
        /**
         * Set a comment associated with the action being logged.
-        * 
+        *
         * @since 1.19
-        * 
+        *
         * @param string $comment
         */
        public function setComment( $comment ) {
@@ -412,9 +412,9 @@ class ManualLogEntry extends LogEntryBase {
 
        /**
         * TODO: document
-        * 
+        *
         * @since 1.19
-        * 
+        *
         * @param integer $deleted
         */
        public function setDeleted( $deleted ) {
index d96a5ea..90393ea 100644 (file)
@@ -220,7 +220,7 @@ class LogPage {
        }
 
        /**
-        * Generate text for a log entry. 
+        * Generate text for a log entry.
         * Only LogFormatter should call this function.
         *
         * @param $type String: log type
index c5e4566..69bdc2f 100644 (file)
@@ -33,6 +33,13 @@ abstract class MediaTransformOutput {
        var $file;
 
        var $width, $height, $url, $page, $path;
+
+       /**
+        * @var array Associative array mapping optional supplementary image files
+        * from pixel density (eg 1.5 or 2) to additional URLs.
+        */
+       public $responsiveUrls = array();
+
        protected $storagePath = false;
 
        /**
@@ -324,7 +331,7 @@ class ThumbnailImage extends MediaTransformOutput {
                        'alt' => $alt,
                        'src' => $this->url,
                        'width' => $this->width,
-                       'height' => $this->height,
+                       'height' => $this->height
                );
                if ( !empty( $options['valign'] ) ) {
                        $attribs['style'] = "vertical-align: {$options['valign']}";
@@ -332,6 +339,11 @@ class ThumbnailImage extends MediaTransformOutput {
                if ( !empty( $options['img-class'] ) ) {
                        $attribs['class'] = $options['img-class'];
                }
+
+               // Additional densities for responsive images, if specified.
+               if ( !empty( $this->responsiveUrls ) ) {
+                       $attribs['srcset'] = Html::srcSet( $this->responsiveUrls );
+               }
                return $this->linkWrap( $linkAttribs, Xml::element( 'img', $attribs ) );
        }
 
index 2917b4a..0f22675 100644 (file)
@@ -200,7 +200,7 @@ class DateFormatter {
                $linked = true;
                if ( isset( $this->mLinked ) )
                        $linked = $this->mLinked;
-               
+
                $bits = array();
                $key = $this->keys[$this->mSource];
                for ( $p=0; $p < strlen($key); $p++ ) {
@@ -219,7 +219,7 @@ class DateFormatter {
         */
        function formatDate( $bits, $link = true ) {
                $format = $this->targets[$this->mTarget];
-               
+
                if (!$link) {
                        // strip piped links
                        $format = preg_replace( '/\[\[[^|]+\|([^\]]+)\]\]/', '$1', $format );
index d9356b4..49160e8 100644 (file)
@@ -45,7 +45,7 @@ class LinkHolderArray {
 
        /**
         * Don't serialize the parent object, it is big, and not needed when it is
-        * a parameter to mergeForeign(), which is the only application of 
+        * a parameter to mergeForeign(), which is the only application of
         * serializing at present.
         *
         * Compact the titles, only serialize the text form.
@@ -103,9 +103,9 @@ class LinkHolderArray {
        }
 
        /**
-        * Merge a LinkHolderArray from another parser instance into this one. The 
-        * keys will not be preserved. Any text which went with the old 
-        * LinkHolderArray and needs to work with the new one should be passed in 
+        * Merge a LinkHolderArray from another parser instance into this one. The
+        * keys will not be preserved. Any text which went with the old
+        * LinkHolderArray and needs to work with the new one should be passed in
         * the $texts array. The strings in this array will have their link holders
         * converted for use in the destination link holder. The resulting array of
         * strings will be returned.
@@ -126,7 +126,7 @@ class LinkHolderArray {
                                $maxId = $newKey > $maxId ? $newKey : $maxId;
                        }
                }
-               $texts = preg_replace_callback( '/(<!--LINK \d+:)(\d+)(-->)/', 
+               $texts = preg_replace_callback( '/(<!--LINK \d+:)(\d+)(-->)/',
                        array( $this, 'mergeForeignCallback' ), $texts );
 
                # Renumber interwiki links
@@ -135,7 +135,7 @@ class LinkHolderArray {
                        $this->interwikis[$newKey] = $entry;
                        $maxId = $newKey > $maxId ? $newKey : $maxId;
                }
-               $texts = preg_replace_callback( '/(<!--IWLINK )(\d+)(-->)/', 
+               $texts = preg_replace_callback( '/(<!--IWLINK )(\d+)(-->)/',
                        array( $this, 'mergeForeignCallback' ), $texts );
 
                # Set the parent link ID to be beyond the highest used ID
@@ -159,8 +159,8 @@ class LinkHolderArray {
                # Internal links
                $pos = 0;
                while ( $pos < strlen( $text ) ) {
-                       if ( !preg_match( '/<!--LINK (\d+):(\d+)-->/', 
-                               $text, $m, PREG_OFFSET_CAPTURE, $pos ) ) 
+                       if ( !preg_match( '/<!--LINK (\d+):(\d+)-->/',
+                               $text, $m, PREG_OFFSET_CAPTURE, $pos ) )
                        {
                                break;
                        }
index e5beba8..d419621 100644 (file)
@@ -201,8 +201,8 @@ class ParserCache {
 
                wfDebug( "ParserOutput cache found.\n" );
 
-               // The edit section preference may not be the appropiate one in 
-               // the ParserOutput, as we are not storing it in the parsercache 
+               // The edit section preference may not be the appropiate one in
+               // the ParserOutput, as we are not storing it in the parsercache
                // key. Force it here. See bug 31445.
                $value->setEditSectionTokens( $popts->getEditSection() );
 
index 009b18a..064182e 100644 (file)
  * @ingroup Parser
  */
 class ParserOptions {
-       
+
        /**
         * Use DateFormatter to format dates
         */
        var $mUseDynamicDates;
-       
+
        /**
         * Interlanguage links are removed and returned in an array
         */
        var $mInterwikiMagic;
-       
+
        /**
         * Allow external images inline?
         */
        var $mAllowExternalImages;
-       
+
        /**
         * If not, any exception?
         */
        var $mAllowExternalImagesFrom;
-       
+
        /**
         * If not or it doesn't match, should we check an on-wiki whitelist?
         */
        var $mEnableImageWhitelist;
-       
+
        /**
         * Date format index
         */
        var $mDateFormat = null;
-       
+
        /**
         * Create "edit section" links?
         */
        var $mEditSection = true;
-       
+
        /**
         * Allow inclusion of special pages?
         */
        var $mAllowSpecialInclusion;
-       
+
        /**
         * Use tidy to cleanup output HTML?
         */
        var $mTidy = false;
-       
+
        /**
         * Which lang to call for PLURAL and GRAMMAR
         */
        var $mInterfaceMessage = false;
-       
+
        /**
         * Overrides $mInterfaceMessage with arbitrary language
         */
        var $mTargetLanguage = null;
-       
+
        /**
         * Maximum size of template expansions, in bytes
         */
        var $mMaxIncludeSize;
-       
+
        /**
         * Maximum number of nodes touched by PPFrame::expand()
         */
@@ -99,56 +99,56 @@ class ParserOptions {
         * Maximum number of nodes generated by Preprocessor::preprocessToObj()
         */
        var $mMaxGeneratedPPNodeCount;
-       
+
        /**
         * Maximum recursion depth in PPFrame::expand()
         */
        var $mMaxPPExpandDepth;
-       
+
        /**
         * Maximum recursion depth for templates within templates
         */
        var $mMaxTemplateDepth;
-       
+
        /**
         * Maximum number of calls per parse to expensive parser functions
         */
        var $mExpensiveParserFunctionLimit;
-       
+
        /**
         * Remove HTML comments. ONLY APPLIES TO PREPROCESS OPERATIONS
         */
        var $mRemoveComments = true;
-       
+
        /**
         * Callback for template fetching. Used as first argument to call_user_func().
         */
        var $mTemplateCallback =
                array( 'Parser', 'statelessFetchTemplate' );
-               
+
        /**
         * Enable limit report in an HTML comment on output
         */
        var $mEnableLimitReport = false;
-       
+
        /**
         * Timestamp used for {{CURRENTDAY}} etc.
         */
        var $mTimestamp;
-       
+
        /**
         * Target attribute for external links
         */
        var $mExternalLinkTarget;
-       
+
        /**
-        * Clean up signature texts? 
+        * Clean up signature texts?
         *
         * 1) Strip ~~~, ~~~~ and ~~~~~ out of signatures
         * 2) Substitute all transclusions
         */
        var $mCleanSignatures;
-       
+
        /**
         * Transform wiki markup when saving the page?
         */
@@ -168,43 +168,43 @@ class ParserOptions {
         * Automatically number headings?
         */
        var $mNumberHeadings;
-       
+
        /**
         * User math preference (as integer). Not used (1.19)
         */
        var $mMath;
-       
+
        /**
         * Thumb size preferred by the user.
         */
        var $mThumbSize;
-       
+
        /**
         * Maximum article size of an article to be marked as "stub"
         */
        private $mStubThreshold;
-       
+
        /**
         * Language object of the User language.
         */
        var $mUserLang;
 
        /**
-        * @var User 
+        * @var User
         * Stored user object
         */
        var $mUser;
-       
+
        /**
         * Parsing the page for a "preview" operation?
         */
        var $mIsPreview = false;
-       
+
        /**
         * Parsing the page for a "preview" operation on a single section?
         */
        var $mIsSectionPreview = false;
-       
+
        /**
         * Parsing the printable version of the page?
         */
@@ -415,8 +415,8 @@ class ParserOptions {
                return new ParserOptions( $context->getUser(), $context->getLanguage() );
        }
 
-       /** 
-        * Get user options 
+       /**
+        * Get user options
         *
         * @param $user User object
         * @param $lang Language object
index 9c750b8..e4f5d12 100644 (file)
@@ -32,7 +32,7 @@ class Parser_LinkHooks extends Parser {
         * can automatically discard old data.
         */
        const VERSION = '1.6.4';
-       
+
        # Flags for Parser::setLinkHook
        # Also available as global constants from Defines.php
        const SLH_PATTERN = 1;
@@ -112,7 +112,7 @@ class Parser_LinkHooks extends Parser {
                $this->mLinkHooks[$ns] = array( $callback, $flags );
                return $oldVal;
        }
-       
+
        /**
         * Get all registered link hook identifiers
         *
@@ -147,7 +147,7 @@ class Parser_LinkHooks extends Parser {
                }
 
                $holders = new LinkHolderArray( $this );
-               
+
                if( is_null( $this->mTitle ) ) {
                        wfProfileOut( __METHOD__ );
                        wfProfileOut( __METHOD__.'-setup' );
@@ -155,7 +155,7 @@ class Parser_LinkHooks extends Parser {
                }
 
                wfProfileOut( __METHOD__.'-setup' );
-               
+
                $offset = 0;
                $offsetStack = array();
                $markers = new LinkMarkerReplacer( $this, $holders, array( &$this, 'replaceInternalLinksCallback' ) );
@@ -181,7 +181,7 @@ class Parser_LinkHooks extends Parser {
                                $startBracketOffset = array_pop($offsetStack);
                                # Just to clean up the code, lets place offsets on the outer ends
                                $endBracketOffset += 2;
-                               
+
                                # Only do logic if we actually have a opening bracket for this
                                if( isset($startBracketOffset) ) {
                                        # Extract text inside the link
@@ -206,22 +206,20 @@ class Parser_LinkHooks extends Parser {
                                        # ToDO: Some LinkHooks use patterns rather than namespaces
                                        # these need to be tested at this point here
                                }
-                               
                        }
                        # Bump our offset to after our current bracket
                        $offset = $bracketOffset+2;
                }
-               
-               
+
                # Now expand our tree
                wfProfileIn( __METHOD__.'-expand' );
                $s = $markers->expand( $s );
                wfProfileOut( __METHOD__.'-expand' );
-               
+
                wfProfileOut( __METHOD__ );
                return $holders;
        }
-       
+
        function replaceInternalLinksCallback( $parser, $holders, $markers, $titleText, $paramText ) {
                wfProfileIn( __METHOD__ );
                $wt = isset($paramText) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
@@ -233,16 +231,16 @@ class Parser_LinkHooks extends Parser {
                        wfProfileOut( __METHOD__ );
                        return $wt;
                }
-               
+
                # Make subpage if necessary
                if( $this->areSubpagesAllowed() ) {
                        $titleText = $this->maybeDoSubpageLink( $titleText, $paramText );
                }
-               
+
                # Check for a leading colon and strip it if it is there
                $leadingColon = $titleText[0] == ':';
                if( $leadingColon ) $titleText = substr( $titleText, 1 );
-               
+
                wfProfileOut( __METHOD__."-misc" );
                # Make title object
                wfProfileIn( __METHOD__."-title" );
@@ -254,7 +252,7 @@ class Parser_LinkHooks extends Parser {
                }
                $ns = $title->getNamespace();
                wfProfileOut( __METHOD__."-title" );
-               
+
                # Default for Namespaces is a default link
                # ToDo: Default for patterns is plain wikitext
                $return = true;
@@ -273,7 +271,7 @@ class Parser_LinkHooks extends Parser {
                }
                if( $return === true ) {
                        # True (treat as plain link) was returned, call the defaultLinkHook
-                       $return = CoreLinkFunctions::defaultLinkHook( $parser, $holders, $markers, $title, 
+                       $return = CoreLinkFunctions::defaultLinkHook( $parser, $holders, $markers, $title,
                                $titleText, $paramText, $leadingColon );
                }
                if( $return === false ) {
@@ -285,13 +283,13 @@ class Parser_LinkHooks extends Parser {
                wfProfileOut( __METHOD__ );
                return $return;
        }
-       
+
 }
 
 class LinkMarkerReplacer {
-       
+
        protected $markers, $nextId, $parser, $holders, $callback;
-       
+
        function __construct( $parser, $holders, $callback ) {
                $this->nextId   = 0;
                $this->markers  = array();
@@ -299,21 +297,21 @@ class LinkMarkerReplacer {
                $this->holders  = $holders;
                $this->callback = $callback;
        }
-       
+
        function addMarker($titleText, $paramText) {
                $id = $this->nextId++;
                $this->markers[$id] = array( $titleText, $paramText );
                return "<!-- LINKMARKER $id -->";
        }
-       
+
        function findMarker( $string ) {
                return (bool) preg_match('/<!-- LINKMARKER [0-9]+ -->/', $string );
        }
-       
+
        function expand( $string ) {
                return StringUtils::delimiterReplaceCallback( "<!-- LINKMARKER ", " -->", array( &$this, 'callback' ), $string );
        }
-       
+
        function callback( $m ) {
                $id = intval($m[1]);
                if( !array_key_exists($id, $this->markers) ) return $m[0];
@@ -323,5 +321,4 @@ class LinkMarkerReplacer {
                array_unshift( $args, $this->parser );
                return call_user_func_array( $this->callback, $args );
        }
-       
 }
index 15ea5e4..b2dd7db 100644 (file)
@@ -165,7 +165,7 @@ class Preprocessor_DOM implements Preprocessor {
                }
 
                // Fail if the number of elements exceeds acceptable limits
-               // Do not attempt to generate the DOM 
+               // Do not attempt to generate the DOM
                $this->parser->mGeneratedPPNodeCount += substr_count( $xml, '<' );
                $max = $this->parser->mOptions->getMaxGeneratedPPNodeCount();
                if ( $this->parser->mGeneratedPPNodeCount > $max ) {
index ad95d5f..57f623d 100644 (file)
@@ -112,7 +112,7 @@ class StripState {
         * @return mixed
         */
        protected function unstripType( $type, $text ) {
-               // Shortcut 
+               // Shortcut
                if ( !count( $this->data[$type] ) ) {
                        return $text;
                }
@@ -139,7 +139,7 @@ class StripState {
                                        . '</span>';
                        }
                        if ( $this->recursionLevel >= self::UNSTRIP_RECURSION_LIMIT ) {
-                               return '<span class="error">' . 
+                               return '<span class="error">' .
                                        wfMessage( 'parser-unstrip-recursion-limit' )
                                                ->numParams( self::UNSTRIP_RECURSION_LIMIT )->inContentLanguage()->text() .
                                        '</span>';
@@ -156,7 +156,7 @@ class StripState {
        }
 
        /**
-        * Get a StripState object which is sufficient to unstrip the given text. 
+        * Get a StripState object which is sufficient to unstrip the given text.
         * It will contain the minimum subset of strip items necessary.
         *
         * @param $text string
diff --git a/includes/site/MediaWikiSite.php b/includes/site/MediaWikiSite.php
new file mode 100644 (file)
index 0000000..b05c421
--- /dev/null
@@ -0,0 +1,320 @@
+<?php
+
+/**
+ * Class representing a MediaWiki site.
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @licence GNU GPL v2+
+ * @author John Erling Blad < jeblad@gmail.com >
+ * @author Daniel Kinzler
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class MediaWikiSite extends SiteObject {
+
+       const PATH_FILE = 'file_path';
+       const PATH_PAGE = 'page_path';
+
+       /**
+        * @since 1.21
+        *
+        * @param integer $globalId
+        *
+        * @return MediaWikiSite
+        */
+       public static function newFromGlobalId( $globalId ) {
+               return SitesTable::singleton()->newRow( array(
+                       'type' => Site::TYPE_MEDIAWIKI,
+                       'global_key' => $globalId,
+               ), true );
+       }
+
+       /**
+        * Returns the database form of the given title.
+        *
+        * @since 1.21
+        *
+        * @param String $title the target page's title, in normalized form.
+        *
+        * @return String
+        */
+       public function toDBKey( $title ) {
+               return str_replace( ' ', '_', $title );
+       }
+
+       /**
+        * Returns the normalized form of the given page title, using the normalization rules of the given site.
+        * If the given title is a redirect, the redirect weill be resolved and the redirect target is returned.
+        *
+        * @note  : This actually makes an API request to the remote site, so beware that this function is slow and depends
+        *          on an external service.
+        *
+        * @note  : If MW_PHPUNIT_TEST is defined or $egWBRemoteTitleNormalization is set to false, the call to the
+        *          external site is skipped, and the title is normalized using the local normalization rules as
+        *          implemented by the Title class.
+        *
+        * @see Site::normalizePageName
+        *
+        * @since 1.21
+        *
+        * @param string $pageName
+        *
+        * @return string
+        * @throws MWException
+        */
+       public function normalizePageName( $pageName ) {
+               global $egWBRemoteTitleNormalization;
+
+               // Check if we have strings as arguments.
+               if ( !is_string( $pageName ) ) {
+                       throw new MWException( '$pageName must be a string' );
+               }
+
+               // Go on call the external site
+               if ( defined( 'MW_PHPUNIT_TEST' ) ) {
+                       // If the code is under test, don't call out to other sites, just normalize locally.
+                       // Note: this may cause results to be inconsistent with the actual normalization used by the respective remote site!
+
+                       $t = Title::newFromText( $pageName );
+                       return $t->getPrefixedText();
+               } else {
+
+                       // Make sure the string is normalized into NFC (due to the bug 40017)
+                       // but do nothing to the whitespaces, that should work appropriately.
+                       // @see https://bugzilla.wikimedia.org/show_bug.cgi?id=40017
+                       $pageName = UtfNormal::cleanUp( $pageName );
+
+                       // Build the args for the specific call
+                       $args = array(
+                               'action' => 'query',
+                               'prop' => 'info',
+                               'redirects' => true,
+                               'converttitles' => true,
+                               'format' => 'json',
+                               'titles' => $pageName,
+                               //@todo: options for maxlag and maxage
+                               // Note that maxlag will lead to a long delay before a reply is made,
+                               // but that maxage can avoid the extreme delay. On the other hand
+                               // maxage could be nice to use anyhow as it stops unnecessary requests.
+                               // Also consider smaxage if maxage is used.
+                       );
+
+                       $url = $this->getFileUrl( 'api.php' ) . '?' . wfArrayToCgi( $args );
+
+                       // Go on call the external site
+                       //@todo: we need a good way to specify a timeout here.
+                       $ret = Http::get( $url );
+               }
+
+               if ( $ret === false ) {
+                       wfDebugLog( "MediaWikiSite", "call to external site failed: $url" );
+                       return false;
+               }
+
+               $data = FormatJson::decode( $ret, true );
+
+               if ( !is_array( $data ) ) {
+                       wfDebugLog( "MediaWikiSite", "call to <$url> returned bad json: " . $ret );
+                       return false;
+               }
+
+               $page = static::extractPageRecord( $data, $pageName );
+
+               if ( isset( $page['missing'] ) ) {
+                       wfDebugLog( "MediaWikiSite", "call to <$url> returned a missing page title! " . $ret );
+                       return false;
+               }
+
+               if ( !isset( $page['title'] ) ) {
+                       wfDebugLog( "MediaWikiSite", "call to <$url> did not return a page title! " . $ret );
+                       return false;
+               }
+
+               return $page['title'];
+       }
+
+
+       /**
+        * Get normalization record for a given page title from an API response.
+        *
+        * @since 1.21
+        *
+        * @param array $externalData A reply from the API on a external server.
+        * @param string $pageTitle Identifies the page at the external site, needing normalization.
+        *
+        * @return array|false a 'page' structure representing the page identified by $pageTitle.
+        */
+       private static function extractPageRecord( $externalData, $pageTitle ) {
+               // If there is a special case with only one returned page
+               // we can cheat, and only return
+               // the single page in the "pages" substructure.
+               if ( isset( $externalData['query']['pages'] ) ) {
+                       $pages = array_values( $externalData['query']['pages'] );
+                       if ( count( $pages) === 1 ) {
+                               return $pages[0];
+                       }
+               }
+               // This is only used during internal testing, as it is assumed
+               // a more optimal (and lossfree) storage.
+               // Make initial checks and return if prerequisites are not meet.
+               if ( !is_array( $externalData ) || !isset( $externalData['query'] ) ) {
+                       return false;
+               }
+               // Loop over the tree different named structures, that otherwise are similar
+               $structs = array(
+                       'normalized' => 'from',
+                       'converted' => 'from',
+                       'redirects' => 'from',
+                       'pages' => 'title'
+               );
+               foreach ( $structs as $listId => $fieldId ) {
+                       // Check if the substructure exist at all.
+                       if ( !isset( $externalData['query'][$listId] ) ) {
+                               continue;
+                       }
+                       // Filter the substructure down to what we actually are using.
+                       $collectedHits = array_filter(
+                               array_values( $externalData['query'][$listId] ),
+                               function( $a ) use ( $fieldId, $pageTitle ) {
+                                       return $a[$fieldId] === $pageTitle;
+                               }
+                       );
+                       // If still looping over normalization, conversion or redirects,
+                       // then we need to keep the new page title for later rounds.
+                       if ( $fieldId === 'from' && is_array( $collectedHits ) ) {
+                               switch ( count( $collectedHits ) ) {
+                                       case 0:
+                                               break;
+                                       case 1:
+                                               $pageTitle = $collectedHits[0]['to'];
+                                               break;
+                                       default:
+                                               return false;
+                               }
+                       }
+                       // If on the pages structure we should prepare for returning.
+                       elseif ( $fieldId === 'title' && is_array( $collectedHits ) ) {
+                               switch ( count( $collectedHits ) ) {
+                                       case 0:
+                                               return false;
+                                       case 1:
+                                               return array_shift( $collectedHits );
+                                       default:
+                                               return false;
+                               }
+                       }
+               }
+               // should never be here
+               return false;
+       }
+
+       /**
+        * @see Site::getLinkPathType
+        * Returns Site::PATH_PAGE
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getLinkPathType() {
+               return self::PATH_PAGE;
+       }
+
+       /**
+        * Returns the relative page path.
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getRelativePagePath() {
+               return parse_url( $this->getPath( self::PATH_PAGE ), PHP_URL_PATH );
+       }
+
+       /**
+        * Returns the relative file path.
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getRelativeFilePath() {
+               return parse_url( $this->getPath( self::PATH_FILE ), PHP_URL_PATH );
+       }
+
+       /**
+        * Sets the relative page path.
+        *
+        * @since 1.21
+        *
+        * @param string $path
+        */
+       public function setPagePath( $path ) {
+               $this->setPath( self::PATH_PAGE, $path );
+       }
+
+       /**
+        * Sets the relative file path.
+        *
+        * @since 1.21
+        *
+        * @param string $path
+        */
+       public function setFilePath( $path ) {
+               $this->setPath( self::PATH_FILE, $path );
+       }
+
+       /**
+        * @see Site::getPagePath
+        *
+        * This implementation returns a URL constructed using the path returned by getLinkPath().
+        * In addition to the default behaviour implemented by SiteObject::getPageUrl(), this
+        * method converts the $pageName to DBKey-format by replacing spaces with underscores
+        * before using it in the URL.
+        *
+        * @since 1.21
+        *
+        * @param string|false
+        *
+        * @return string
+        */
+       public function getPageUrl( $pageName = false ) {
+               $url = $this->getLinkPath();
+
+               if ( $url === false ) {
+                       return false;
+               }
+
+               if ( $pageName !== false ) {
+                       $pageName = $this->toDBKey( trim( $pageName ) );
+                       $url = str_replace( '$1', wfUrlencode( $pageName ), $url ) ;
+               }
+
+               return $url;
+       }
+
+       /**
+        * Returns the full file path (ie site url + relative file path).
+        * The path should go at the $1 marker. If the $path
+        * argument is provided, the marker will be replaced by it's value.
+        *
+        * @since 1.21
+        *
+        * @param string|false $path
+        *
+        * @return string
+        */
+       public function getFileUrl( $path = false ) {
+               $filePath = $this->getPath( self::PATH_FILE );
+
+               if ( $filePath !== false ) {
+                       $filePath = str_replace( '$1', $path, $filePath );
+               }
+
+               return $filePath;
+       }
+
+}
diff --git a/includes/site/Site.php b/includes/site/Site.php
new file mode 100644 (file)
index 0000000..350a19d
--- /dev/null
@@ -0,0 +1,316 @@
+<?php
+
+/**
+ * Interface for site objects.
+ *
+ * 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface Site {
+
+       const TYPE_UNKNOWN = 'unknown';
+       const TYPE_MEDIAWIKI = 'mediawiki';
+
+       const GROUP_NONE = 'none';
+
+       const ID_INTERWIKI = 'interwiki';
+       const ID_EQUIVALENT = 'equivalent';
+
+       const SOURCE_LOCAL = 'local';
+
+       /**
+        * Returns the global site identifier (ie enwiktionary).
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getGlobalId();
+
+       /**
+        * Sets the global site identifier (ie enwiktionary).
+        *
+        * @since 1.21
+        *
+        * @param string $globalId
+        */
+       public function setGlobalId( $globalId );
+
+       /**
+        * Returns the type of the site (ie mediawiki).
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getType();
+
+       /**
+        * Sets the type of the site (ie mediawiki).
+        * TODO: remove, we cannot change this after instantiation
+        *
+        * @since 1.21
+        *
+        * @param string $type
+        */
+       public function setType( $type );
+
+       /**
+        * Gets the type of the site (ie wikipedia).
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getGroup();
+
+       /**
+        * Sets the type of the site (ie wikipedia).
+        *
+        * @since 1.21
+        *
+        * @param string $group
+        */
+       public function setGroup( $group );
+
+       /**
+        * Returns the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getSource();
+
+       /**
+        * Sets the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
+        *
+        * @since 1.21
+        *
+        * @param string $source
+        */
+       public function setSource( $source );
+
+       /**
+        * Returns the protocol of the site, ie 'http://', 'irc://', '//'
+        * Or false if it's not known.
+        *
+        * @since 1.21
+        *
+        * @return string|false
+        */
+       public function getProtocol();
+
+       /**
+        * Returns the domain of the site, ie en.wikipedia.org
+        * Or false if it's not known.
+        *
+        * @since 1.21
+        *
+        * @return string|false
+        */
+       public function getDomain();
+
+       /**
+        * Returns the full URL for the given page on the site.
+        * Or false if the needed information is not known.
+        *
+        * This generated URL is usually based upon the path returned by getLinkPath(),
+        * but this is not a requirement.
+        *
+        * @since 1.21
+        * @see Site::getLinkPath()
+        *
+        * @param bool|String $page
+        *
+        * @return string|false
+        */
+       public function getPageUrl( $page = false );
+
+       /**
+        * Returns language code of the sites primary language.
+        * Or false if it's not known.
+        *
+        * @since 1.21
+        *
+        * @return string|false
+        */
+       public function getLanguageCode();
+
+       /**
+        * Sets language code of the sites primary language.
+        *
+        * @since 1.21
+        *
+        * @param string $languageCode
+        */
+       public function setLanguageCode( $languageCode );
+
+       /**
+        * Returns the normalized, canonical form of the given page name.
+        * How normalization is performed or what the properties of a normalized name are depends on the site.
+        * The general contract of this method is that the normalized form shall refer to the same content
+        * as the original form, and any other page name referring to the same content will have the same normalized form.
+        *
+        * Note that this method may call out to the target site to perform the normalization, so it may be slow
+        * and fail due to IO errors.
+        *
+        * @since 1.21
+        *
+        * @param string $pageName
+        *
+        * @return string the normalized page name
+        */
+       public function normalizePageName( $pageName );
+
+       /**
+        * Returns the interwiki link identifiers that can be used for this site.
+        *
+        * @since 1.21
+        *
+        * @return array of string
+        */
+       public function getInterwikiIds();
+
+       /**
+        * Returns the equivalent link identifiers that can be used to make
+        * the site show up in interfaces such as the "language links" section.
+        *
+        * @since 1.21
+        *
+        * @return array of string
+        */
+       public function getNavigationIds();
+
+       /**
+        * Adds an local identifier to the site.
+        *
+        * @since 1.21
+        *
+        * @param string $type The type of the identifier, element of the Site::ID_ enum
+        * @param string $identifier
+        */
+       public function addLocalId( $type, $identifier );
+
+       /**
+        * Adds an interwiki id to the site.
+        *
+        * @since 1.21
+        *
+        * @param string $identifier
+        */
+       public function addInterwikiId( $identifier );
+
+       /**
+        * Adds a navigation id to the site.
+        *
+        * @since 1.21
+        *
+        * @param string $identifier
+        */
+       public function addNavigationId( $identifier );
+
+       /**
+        * Saves the site.
+        *
+        * @since 1.21
+        *
+        * @param string|null $functionName
+        */
+       public function save( $functionName = null );
+
+       /**
+        * Returns the internal ID of the site.
+        *
+        * @since 1.21
+        *
+        * @return integer
+        */
+       public function getInternalId();
+
+       /**
+        * Sets the provided url as path of the specified type.
+        *
+        * @since 1.21
+        *
+        * @param string $pathType
+        * @param string $fullUrl
+        */
+       public function setPath( $pathType, $fullUrl );
+
+       /**
+        * Returns the path of the provided type or false if there is no such path.
+        *
+        * @since 1.21
+        *
+        * @param string $pathType
+        *
+        * @return string|false
+        */
+       public function getPath( $pathType );
+
+       /**
+        * Sets the path used to construct links with.
+        * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
+        *
+        * @param string $fullUrl
+        *
+        * @since 1.21
+        */
+       public function setLinkPath( $fullUrl );
+
+       /**
+        * Returns the path used to construct links with or false if there is no such path.
+        * Shall be equivalent to getPath( getLinkPathType() ).
+        *
+        * @return string|false
+        */
+       public function getLinkPath();
+
+       /**
+        * Returns the path type used to construct links with.
+        *
+        * @return string|false
+        */
+       public function getLinkPathType();
+
+       /**
+        * Returns the paths as associative array.
+        * The keys are path types, the values are the path urls.
+        *
+        * @since 1.21
+        *
+        * @return array of string
+        */
+       public function getAllPaths();
+
+       /**
+        * Removes the path of the provided type if it's set.
+        *
+        * @since 1.21
+        *
+        * @param string $pathType
+        */
+       public function removePath( $pathType );
+
+}
\ No newline at end of file
diff --git a/includes/site/SiteArray.php b/includes/site/SiteArray.php
new file mode 100644 (file)
index 0000000..df43148
--- /dev/null
@@ -0,0 +1,205 @@
+<?php
+
+/**
+ * Implementation of SiteList using GenericArrayObject.
+ *
+ * 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteArray extends GenericArrayObject implements SiteList {
+
+       /**
+        * Internal site identifiers pointing to their sites offset value.
+        *
+        * @since 1.21
+        *
+        * @var array of integer
+        */
+       protected $byInternalId = array();
+
+       /**
+        * Global site identifiers pointing to their sites offset value.
+        *
+        * @since 1.21
+        *
+        * @var array of string
+        */
+       protected $byGlobalId = array();
+
+       /**
+        * @see GenericArrayObject::getObjectType
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getObjectType() {
+               return 'Site';
+       }
+
+       /**
+        * @see GenericArrayObject::preSetElement
+        *
+        * @since 1.21
+        *
+        * @param int|string $index
+        * @param Site $site
+        *
+        * @return boolean
+        */
+       protected function preSetElement( $index, $site ) {
+               if ( $this->hasSite( $site->getGlobalId() ) ) {
+                       $this->removeSite( $site->getGlobalId() );
+               }
+
+               $this->byGlobalId[$site->getGlobalId()] = $index;
+               $this->byInternalId[$site->getInternalId()] = $index;
+
+               return true;
+       }
+
+       /**
+        * @see ArrayObject::offsetUnset()
+        *
+        * @since 1.21
+        *
+        * @param mixed $index
+        */
+       public function offsetUnset( $index ) {
+               /**
+                * @var Site $site
+                */
+               $site = $this->offsetGet( $index );
+
+               if ( $site !== false ) {
+                       unset( $this->byGlobalId[$site->getGlobalId()] );
+                       unset( $this->byInternalId[$site->getInternalId()] );
+               }
+
+               parent::offsetUnset( $index );
+       }
+
+       /**
+        * @see SiteList::getGlobalIdentifiers
+        *
+        * @since 1.21
+        *
+        * @return array
+        */
+       public function getGlobalIdentifiers() {
+               return array_keys( $this->byGlobalId );
+       }
+
+       /**
+        * @see SiteList::hasSite
+        *
+        * @param string $globalSiteId
+        *
+        * @return boolean
+        */
+       public function hasSite( $globalSiteId ) {
+               return array_key_exists( $globalSiteId, $this->byGlobalId );
+       }
+
+       /**
+        * @see SiteList::getSite
+        *
+        * @since 1.21
+        *
+        * @param string $globalSiteId
+        *
+        * @return Site
+        */
+       public function getSite( $globalSiteId ) {
+               return $this->offsetGet( $this->byGlobalId[$globalSiteId] );
+       }
+
+       /**
+        * @see SiteList::removeSite
+        *
+        * @since 1.21
+        *
+        * @param string $globalSiteId
+        */
+       public function removeSite( $globalSiteId ) {
+               $this->offsetUnset( $this->byGlobalId[$globalSiteId] );
+       }
+
+       /**
+        * @see SiteList::isEmpty
+        *
+        * @since 1.21
+        *
+        * @return boolean
+        */
+       public function isEmpty() {
+               return $this->byGlobalId === array();
+       }
+
+       /**
+        * @see SiteList::hasInternalId
+        *
+        * @param integer $id
+        *
+        * @return boolean
+        */
+       public function hasInternalId( $id ) {
+               return array_key_exists( $id, $this->byInternalId );
+       }
+
+       /**
+        * @see SiteList::getSiteByInternalId
+        *
+        * @since 1.21
+        *
+        * @param integer $id
+        *
+        * @return Site
+        */
+       public function getSiteByInternalId( $id ) {
+               return $this->offsetGet( $this->byInternalId[$id] );
+       }
+
+       /**
+        * @see SiteList::removeSiteByInternalId
+        *
+        * @since 1.21
+        *
+        * @param integer $id
+        */
+       public function removeSiteByInternalId( $id ) {
+               $this->offsetUnset( $this->byInternalId[$id] );
+       }
+
+       /**
+        * @see SiteList::setSite
+        *
+        * @since 1.21
+        *
+        * @param Site $site
+        */
+       public function setSite( Site $site ) {
+               $this[] = $site;
+       }
+
+}
diff --git a/includes/site/SiteList.php b/includes/site/SiteList.php
new file mode 100644 (file)
index 0000000..68bd106
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+
+/**
+ * Interface for lists of Site objects.
+ *
+ * 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
+
+       /**
+        * Returns all the global site identifiers.
+        * Optionally only those belonging to the specified group.
+        *
+        * @since 1.21
+        *
+        * @return array
+        */
+       public function getGlobalIdentifiers();
+
+       /**
+        * Returns if the list contains the site with the provided global site identifier.
+        *
+        * @param string $globalSiteId
+        *
+        * @return boolean
+        */
+       public function hasSite( $globalSiteId );
+
+       /**
+        * Returns the Site with the provided global site identifier.
+        * The site needs to exist, so if not sure, call hasGlobalId first.
+        *
+        * @since 1.21
+        *
+        * @param string $globalSiteId
+        *
+        * @return Site
+        */
+       public function getSite( $globalSiteId );
+
+       /**
+        * Removes the site with the specified global site identifier.
+        * The site needs to exist, so if not sure, call hasGlobalId first.
+        *
+        * @since 1.21
+        *
+        * @param string $globalSiteId
+        */
+       public function removeSite( $globalSiteId );
+
+       /**
+        * Returns if the list contains the site with the provided site id.
+        *
+        * @param integer $id
+        *
+        * @return boolean
+        */
+       public function hasInternalId( $id );
+
+       /**
+        * Returns the Site with the provided site id.
+        * The site needs to exist, so if not sure, call has first.
+        *
+        * @since 1.21
+        *
+        * @param integer $id
+        *
+        * @return Site
+        */
+       public function getSiteByInternalId( $id );
+
+       /**
+        * Removes the site with the specified site id.
+        * The site needs to exist, so if not sure, call has first.
+        *
+        * @since 1.21
+        *
+        * @param integer $id
+        */
+       public function removeSiteByInternalId( $id );
+
+       /**
+        * Sets a site in the list. If the site was not there,
+        * it will be added. If it was, it will be updated.
+        *
+        * @since 1.21
+        *
+        * @param Site $site
+        */
+       public function setSite( Site $site );
+
+       /**
+        * Returns if the site list contains no sites.
+        *
+        * @since 1.21
+        *
+        * @return boolean
+        */
+       public function isEmpty();
+
+}
\ No newline at end of file
diff --git a/includes/site/SiteObject.php b/includes/site/SiteObject.php
new file mode 100644 (file)
index 0000000..7f143d1
--- /dev/null
@@ -0,0 +1,537 @@
+<?php
+
+/**
+ * Class representing a single site.
+ *
+ * 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Daniel Werner
+ */
+class SiteObject extends ORMRow implements Site {
+
+       const PATH_LINK = 'link';
+
+       /**
+        * Holds the local ids for this site.
+        * You can obtain them via @see getLocalIds
+        *
+        * @since 1.21
+        *
+        * @var array|false
+        */
+       protected $localIds = false;
+
+       /**
+        * @see Site::getGlobalId
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getGlobalId() {
+               return $this->getField( 'global_key' );
+       }
+
+       /**
+        * @see Site::setGlobalId
+        *
+        * @since 1.21
+        *
+        * @param string $globalId
+        */
+       public function setGlobalId( $globalId ) {
+               $this->setField( 'global_key', $globalId );
+       }
+
+       /**
+        * @see Site::getType
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getType() {
+               return $this->getField( 'type' );
+       }
+
+       /**
+        * @see Site::setType
+        *
+        * @since 1.21
+        *
+        * @param string $type
+        */
+       public function setType( $type ) {
+               $this->setField( 'type', $type );
+       }
+
+       /**
+        * @see Site::getGroup
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getGroup() {
+               return $this->getField( 'group' );
+       }
+
+       /**
+        * @see Site::setGroup
+        *
+        * @since 1.21
+        *
+        * @param string $group
+        */
+       public function setGroup( $group ) {
+               $this->setField( 'group', $group );
+       }
+
+       /**
+        * @see Site::getSource
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getSource() {
+               return $this->getField( 'source' );
+       }
+
+       /**
+        * @see Site::setSource
+        *
+        * @since 1.21
+        *
+        * @param string $source
+        */
+       public function setSource( $source ) {
+               $this->setField( 'source', $source );
+       }
+
+       /**
+        * @see Site::getDomain
+        *
+        * @since 1.21
+        *
+        * @return string|false
+        */
+       public function getDomain() {
+               $path = $this->getLinkPath();
+
+               if ( $path === false ) {
+                       return false;
+               }
+
+               return parse_url( $path, PHP_URL_HOST );
+       }
+
+       /**
+        * @see Site::getProtocol
+        *
+        * @since 1.21
+        *
+        * @return string|false
+        */
+       public function getProtocol() {
+               $path = $this->getLinkPath();
+
+               if ( $path === false ) {
+                       return false;
+               }
+
+               return parse_url( $path, PHP_URL_SCHEME );
+       }
+
+       /**
+        * Sets the path used to construct links with.
+        * @see Site::setLinkPath
+        *
+        * @param string $fullUrl
+        *
+        * @since 1.21
+        *
+        * @throws MWException
+        */
+       public function setLinkPath( $fullUrl ) {
+               $type = $this->getLinkPathType();
+
+               if ( $type === false ) {
+                       throw new MWException( "This SiteObject does not support link paths." );
+               }
+
+               $this->setPath( $type, $fullUrl );
+       }
+
+       /**
+        * Returns the path path used to construct links with or false if there is no such path.
+        *
+        * @see Site::getLinkPath
+        *
+        * @return string|false
+        */
+       public function getLinkPath() {
+               $type = $this->getLinkPathType();
+               return $type === false ? false : $this->getPath( $type );
+       }
+
+       /**
+        * @see Site::getLinkPathType
+        *
+        * Returns the main path type, that is the type of the path that should generally be used to construct links
+        * to the target site.
+        *
+        * This default implementation returns SiteObject::PATH_LINK as the default path type. Subclasses can override this
+        * to define a different default path type, or return false to disable site links.
+        *
+        * @since 1.21
+        *
+        * @return string|false
+        */
+       public function getLinkPathType() {
+               return self::PATH_LINK;
+       }
+
+       /**
+        * @see Site::getPageUrl
+        *
+        * This implementation returns a URL constructed using the path returned by getLinkPath().
+        *
+        * @since 1.21
+        *
+        * @param bool|String $pageName
+        *
+        * @return string|false
+        */
+       public function getPageUrl( $pageName = false ) {
+               $url = $this->getLinkPath();
+
+               if ( $url === false ) {
+                       return false;
+               }
+
+               if ( $pageName !== false ) {
+                       $url = str_replace( '$1', rawurlencode( $pageName ), $url ) ;
+               }
+
+               return $url;
+       }
+
+       /**
+        * Returns $pageName without changes.
+        * Subclasses may override this to apply some kind of normalization.
+        *
+        * @see Site::normalizePageName
+        *
+        * @since 1.21
+        *
+        * @param string $pageName
+        *
+        * @return string
+        */
+       public function normalizePageName( $pageName ) {
+               return $pageName;
+       }
+
+       /**
+        * Returns the value of a type specific field, or the value
+        * of the $default parameter in case it's not set.
+        *
+        * @since 1.21
+        *
+        * @param string $fieldName
+        * @param mixed $default
+        *
+        * @return array
+        */
+       protected function getExtraData( $fieldName, $default = null ) {
+               $data = $this->getField( 'data', array() );
+               return array_key_exists( $fieldName,$data ) ? $data[$fieldName] : $default;
+       }
+
+       /**
+        * Sets the value of a type specific field.
+        * @since 1.21
+        *
+        * @param string $fieldName
+        * @param mixed $value
+        */
+       protected function setExtraData( $fieldName, $value = null ) {
+               $data = $this->getField( 'data', array() );
+               $data[$fieldName] = $value;
+               $this->setField( 'data', $data );
+       }
+
+       /**
+        * @see Site::getLanguageCode
+        *
+        * @since 1.21
+        *
+        * @return string|false
+        */
+       public function getLanguageCode() {
+               return $this->getField( 'language', false );
+       }
+
+       /**
+        * @see Site::setLanguageCode
+        *
+        * @since 1.21
+        *
+        * @param string $languageCode
+        */
+       public function setLanguageCode( $languageCode ) {
+               $this->setField( 'language', $languageCode );
+       }
+
+       /**
+        * Returns the local identifiers of this site.
+        *
+        * @since 1.21
+        *
+        * @param string $type
+        *
+        * @return array
+        */
+       protected function getLocalIds( $type ) {
+               if ( $this->localIds === false ) {
+                       $this->loadLocalIds();
+               }
+
+               return array_key_exists( $type, $this->localIds ) ? $this->localIds[$type] : array();
+       }
+
+       /**
+        * Loads the local ids for the site.
+        *
+        * @since 1.21
+        */
+       protected function loadLocalIds() {
+               $dbr = wfGetDB( $this->getTable()->getReadDb() );
+
+               $ids = $dbr->select(
+                       'site_identifiers',
+                       array(
+                               'si_type',
+                               'si_key',
+                       ),
+                       array(
+                               'si_site' => $this->getId(),
+                       ),
+                       __METHOD__
+               );
+
+               $this->localIds = array();
+
+               foreach ( $ids as $id ) {
+                       $this->addLocalId( $id->si_type, $id->si_key );
+               }
+       }
+
+       /**
+        * Adds a local identifier.
+        *
+        * @since 1.21
+        *
+        * @param string $type
+        * @param string $identifier
+        */
+       public function addLocalId( $type, $identifier ) {
+               if ( $this->localIds === false ) {
+                       $this->localIds = array();
+               }
+
+               if ( !array_key_exists( $type, $this->localIds ) ) {
+                       $this->localIds[$type] = array();
+               }
+
+               if ( !in_array( $identifier, $this->localIds[$type] ) ) {
+                       $this->localIds[$type][] = $identifier;
+               }
+       }
+
+       /**
+        * @see Site::addInterwikiId
+        *
+        * @since 1.21
+        *
+        * @param string $identifier
+        */
+       public function addInterwikiId( $identifier ) {
+               $this->addLocalId( 'interwiki', $identifier );
+       }
+
+       /**
+        * @see Site::addNavigationId
+        *
+        * @since 1.21
+        *
+        * @param string $identifier
+        */
+       public function addNavigationId( $identifier ) {
+               $this->addLocalId( 'equivalent', $identifier );
+       }
+
+       /**
+        * @see Site::getInterwikiIds
+        *
+        * @since 1.21
+        *
+        * @return array of string
+        */
+       public function getInterwikiIds() {
+               return $this->getLocalIds( 'interwiki' );
+       }
+
+       /**
+        * @see Site::getNavigationIds
+        *
+        * @since 1.21
+        *
+        * @return array of string
+        */
+       public function getNavigationIds() {
+               return $this->getLocalIds( 'equivalent' );
+       }
+
+       /**
+        * @see Site::getInternalId
+        *
+        * @since 1.21
+        *
+        * @return integer
+        */
+       public function getInternalId() {
+               return $this->getId();
+       }
+
+       /**
+        * @see ORMRow::save
+        * @see Site::save
+        *
+        * @since 1.21
+        *
+        * @param string|null $functionName
+        *
+        * @return boolean Success indicator
+        */
+       public function save( $functionName = null ) {
+               $dbw = wfGetDB( DB_MASTER );
+
+               $trx = $dbw->trxLevel();
+
+               if ( $trx == 0 ) {
+                       $dbw->begin( __METHOD__ );
+               }
+
+               $this->setField( 'protocol', $this->getProtocol() );
+               $this->setField( 'domain', strrev( $this->getDomain() ) . '.' );
+
+               $existedAlready = $this->hasIdField();
+
+               $success = parent::save( $functionName );
+
+               if ( $success && $existedAlready ) {
+                       $dbw->delete(
+                               'site_identifiers',
+                               array( 'si_site' => $this->getId() ),
+                               __METHOD__
+                       );
+               }
+
+               if ( $success && $this->localIds !== false ) {
+                       foreach ( $this->localIds as $type => $ids ) {
+                               foreach ( $ids as $id ) {
+                                       $dbw->insert(
+                                               'site_identifiers',
+                                               array(
+                                                       'si_site' => $this->getId(),
+                                                       'si_type' => $type,
+                                                       'si_key' => $id,
+                                               ),
+                                               __METHOD__
+                                       );
+                               }
+                       }
+               }
+
+               if ( $trx == 0 ) {
+                       $dbw->commit( __METHOD__ );
+               }
+
+               return $success;
+       }
+
+       /**
+        * @see Site::setPath
+        *
+        * @since 1.21
+        *
+        * @param string $pathType
+        * @param string $fullUrl
+        */
+       public function setPath( $pathType, $fullUrl ) {
+               $paths = $this->getExtraData( 'paths', array() );
+               $paths[$pathType] = $fullUrl;
+               $this->setExtraData( 'paths', $paths );
+       }
+
+       /**
+        * @see Sitres::getPath
+        *
+        * @since 1.21
+        *
+        * @param string $pathType
+        *
+        * @return string|false
+        */
+       public function getPath( $pathType ) {
+               $paths = $this->getExtraData( 'paths', array() );
+               return array_key_exists( $pathType, $paths ) ? $paths[$pathType] : false;
+       }
+
+       /**
+        * @see Sitres::getAll
+        *
+        * @since 1.21
+        *
+        * @return array of string
+        */
+       public function getAllPaths() {
+               return $this->getExtraData( 'paths', array() );
+       }
+
+       /**
+        * @see Sitres::removePath
+        *
+        * @since 1.21
+        *
+        * @param string $pathType
+        */
+       public function removePath( $pathType ) {
+               $paths = $this->getExtraData( 'paths', array() );
+               unset( $paths[$pathType] );
+               $this->setExtraData( 'paths', $paths );
+       }
+
+}
diff --git a/includes/site/Sites.php b/includes/site/Sites.php
new file mode 100644 (file)
index 0000000..9e87ed9
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * Represents the site configuration of a wiki.
+ * Holds a list of sites (ie SiteList) and takes care
+ * of retrieving and caching site information when appropriate.
+ *
+ * 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class Sites {
+
+       /**
+        * @since 1.21
+        * @var SiteList|false
+        */
+       protected $sites = false;
+
+       /**
+        * Constructor.
+        *
+        * @since 1.21
+        */
+       protected function __construct() {}
+
+       /**
+        * Returns an instance of Sites.
+        *
+        * @since 1.21
+        *
+        * @return Sites
+        */
+       public static function singleton() {
+               static $instance = false;
+
+               if ( $instance === false ) {
+                       $instance = new static();
+               }
+
+               return $instance;
+       }
+
+       /**
+        * Factory for creating new site objects.
+        *
+        * @since 1.21
+        *
+        * @param string|false $globalId
+        *
+        * @return Site
+        */
+       public static function newSite( $globalId = false ) {
+               /**
+                * @var Site $site
+                */
+               $site = SitesTable::singleton()->newRow( array(), true );
+
+               if ( $globalId !== false ) {
+                       $site->setGlobalId( $globalId );
+               }
+
+               return $site;
+       }
+
+       /**
+        * Returns a list of all sites. By default this site is
+        * fetched from the cache, which can be changed to loading
+        * the list from the database using the $useCache parameter.
+        *
+        * @since 1.21
+        *
+        * @param string $source either 'cache' or 'recache'
+        *
+        * @return SiteList
+        */
+       public function getSites( $source = 'cache' ) {
+               if ( $source === 'cache' ) {
+                       if ( $this->sites === false ) {
+                               $cache = wfGetMainCache();
+                               $sites = $cache->get( 'sites-cache' );
+
+                               if ( is_object( $sites ) ) {
+                                       $this->sites = $sites;
+                               }
+                               else {
+                                       $this->loadSites();
+                               }
+                       }
+               }
+               else {
+                       $this->loadSites();
+               }
+
+               return $this->sites;
+       }
+
+       /**
+        * Returns a list of sites in the given group. Calling getGroup() on any of
+        * the sites in the resulting SiteList shall return $group.
+        *
+        * @since 1.21
+        *
+        * @param string $group th group to get.
+        *
+        * @return SiteList
+        */
+       public function getSiteGroup( $group ) {
+               $sites = self::getSites();
+
+               $siteGroup = new SiteArray();
+
+               /* @var Site $site */
+               foreach ( $sites as $site ) {
+                       if ( $site->getGroup() == $group ) {
+                               $siteGroup->append( $site );
+                       }
+               }
+
+               return $siteGroup;
+       }
+
+       /**
+        * Fetches the site from the database and loads them into the sites field.
+        *
+        * @since 1.21
+        */
+       protected function loadSites() {
+               $this->sites = new SiteArray( SitesTable::singleton()->select() );
+
+               // Batch load the local site identifiers.
+               $dbr = wfGetDB( SitesTable::singleton()->getReadDb() );
+
+               $ids = $dbr->select(
+                       'site_identifiers',
+                       array(
+                               'si_site',
+                               'si_type',
+                               'si_key',
+                       ),
+                       array(),
+                       __METHOD__
+               );
+
+               foreach ( $ids as $id ) {
+                       if ( $this->sites->hasInternalId( $id->si_site ) ) {
+                               $site = $this->sites->getSiteByInternalId( $id->si_site );
+                               $site->addLocalId( $id->si_type, $id->si_key );
+                               $this->sites->setSite( $site );
+                       }
+               }
+
+               $cache = wfGetMainCache();
+               $cache->set( 'sites-cache', $this->sites );
+       }
+
+       /**
+        * Returns the site with provided global id, or false if there is no such site.
+        *
+        * @since 1.21
+        *
+        * @param string $globalId
+        * @param string $source
+        *
+        * @return Site|false
+        */
+       public function getSite( $globalId, $source = 'cache' ) {
+               if ( $source === 'cache' && $this->sites !== false ) {
+                       return $this->sites->hasSite( $globalId ) ? $this->sites->getSite( $globalId ) : false;
+               }
+
+               return SitesTable::singleton()->selectRow( null, array( 'global_key' => $globalId ) );
+       }
+
+}
diff --git a/includes/site/SitesTable.php b/includes/site/SitesTable.php
new file mode 100644 (file)
index 0000000..71e55f8
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+
+/**
+ * Represents the sites database table.
+ * All access to this table should be done through this class.
+ *
+ * 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
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SitesTable extends ORMTable {
+
+       /**
+        * @see IORMTable::getName()
+        * @since 1.21
+        * @return string
+        */
+       public function getName() {
+               return 'sites';
+       }
+
+       /**
+        * @see IORMTable::getFieldPrefix()
+        * @since 1.21
+        * @return string
+        */
+       public function getFieldPrefix() {
+               return 'site_';
+       }
+
+       /**
+        * @see IORMTable::getRowClass()
+        * @since 1.21
+        * @return string
+        */
+       public function getRowClass() {
+               return 'SiteObject';
+       }
+
+       /**
+        * @see IORMTable::getFields()
+        * @since 1.21
+        * @return array
+        */
+       public function getFields() {
+               return array(
+                       'id' => 'id',
+
+                       // Site data
+                       'global_key' => 'str',
+                       'type' => 'str',
+                       'group' => 'str',
+                       'source' => 'str',
+                       'language' => 'str',
+                       'protocol' => 'str',
+                       'domain' => 'str',
+                       'data' => 'array',
+
+                       // Site config
+                       'forward' => 'bool',
+                       'config' => 'array',
+               );
+       }
+
+       /**
+        * @see IORMTable::getDefaults()
+        * @since 1.21
+        * @return array
+        */
+       public function getDefaults() {
+               return array(
+                       'type' => Site::TYPE_UNKNOWN,
+                       'group' => Site::GROUP_NONE,
+                       'source' => Site::SOURCE_LOCAL,
+                       'data' => array(),
+
+                       'forward' => false,
+                       'config' => array(),
+               );
+       }
+
+       /**
+        * Returns the class name for the provided site type.
+        *
+        * @since 1.21
+        *
+        * @param integer $siteType
+        *
+        * @return string
+        */
+       protected static function getClassForType( $siteType ) {
+               global $wgSiteTypes;
+               return array_key_exists( $siteType, $wgSiteTypes ) ? $wgSiteTypes[$siteType] : 'SiteObject';
+       }
+
+       /**
+        * Factory method to construct a new Site instance.
+        *
+        * @since 1.21
+        *
+        * @param array $data
+        * @param boolean $loadDefaults
+        *
+        * @return Site
+        */
+       public function newRow( array $data, $loadDefaults = false ) {
+               if ( !array_key_exists( 'type', $data ) ) {
+                       $data['type'] = Site::TYPE_UNKNOWN;
+               }
+
+               $class = static::getClassForType( $data['type'] );
+
+               return new $class( $this, $data, $loadDefaults );
+       }
+
+}
\ No newline at end of file
index 7143d5b..faaab72 100644 (file)
@@ -441,7 +441,7 @@ class BlockListPager extends TablePager {
                        $name = str_replace( ' ', '_', $user->getName() );
                        $lb->add( NS_USER, $name );
                        $lb->add( NS_USER_TALK, $name );
-               } 
+               }
 
                $lb->execute();
                wfProfileOut( __METHOD__ );
index 54f8e26..ca8c9c8 100644 (file)
@@ -485,8 +485,8 @@ class SpecialContributions extends SpecialPage {
                                )
                        ) ;
 
-               $extraOptions = Xml::tags( 'td', array( 'colspan' => 2 ),
-                       Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
+               if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
+                       $deletedOnlyCheck = Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
                                Xml::checkLabel(
                                        $this->msg( 'history-show-deleted' )->text(),
                                        'deletedOnly',
@@ -494,7 +494,13 @@ class SpecialContributions extends SpecialPage {
                                        $this->opts['deletedOnly'],
                                        array( 'class' => 'mw-input' )
                                )
-                       ) .
+                       );
+               } else {
+                       $deletedOnlyCheck = '';
+               }
+
+               $extraOptions = Xml::tags( 'td', array( 'colspan' => 2 ),
+                       $deletedOnlyCheck .
                        Html::rawElement( 'span', array( 'style' => 'white-space: nowrap' ),
                                Xml::checkLabel(
                                        $this->msg( 'sp-contributions-toponly' )->text(),
index b4294b3..18dde20 100644 (file)
@@ -286,7 +286,7 @@ class SpecialExport extends SpecialPage {
                } else {
 
                        $pageSet = array(); // Inverted index of all pages to look up
-               
+
                        // Split up and normalize input
                        foreach( explode( "\n", $page ) as $pageName ) {
                                $pageName = trim( $pageName );
index 3ae0b83..6c33bb8 100644 (file)
@@ -449,7 +449,9 @@ class SpecialSearch extends SpecialPage {
                $out = $this->getOutput();
                if( strval( $term ) !== ''  ) {
                        $out->setPageTitle( $this->msg( 'searchresults' ) );
-                       $out->setHTMLTitle( $this->msg( 'pagetitle', $this->msg( 'searchresults-title', $term )->plain() ) );
+                       $out->setHTMLTitle( $this->msg( 'pagetitle' )->rawParams(
+                               $this->msg( 'searchresults-title' )->rawParams( $term )->text()
+                       ) );
                }
                // add javascript specific to special:search
                $out->addModules( 'mediawiki.special.search' );
index b735b18..036b867 100644 (file)
@@ -175,7 +175,8 @@ class PageArchive {
                                        'fa_user',
                                        'fa_user_text',
                                        'fa_timestamp',
-                                       'fa_deleted' ),
+                                       'fa_deleted',
+                                       'fa_sha1' ),
                                array( 'fa_name' => $this->title->getDBkey() ),
                                __METHOD__,
                                array( 'ORDER BY' => 'fa_timestamp DESC' ) );
index a15fdd2..e3a4c3a 100644 (file)
@@ -646,7 +646,7 @@ class SpecialUpload extends SpecialPage {
                                $exists['normalizedFile']->getTitle()->getPrefixedText() )->parse();
                } elseif ( $exists['warning'] == 'thumb' ) {
                        // Swapped argument order compared with other messages for backwards compatibility
-                       $warning = wfMessage( 'fileexists-thumbnail-yes', 
+                       $warning = wfMessage( 'fileexists-thumbnail-yes',
                                $exists['thumbFile']->getTitle()->getPrefixedText(), $filename )->parse();
                } elseif ( $exists['warning'] == 'thumb-name' ) {
                        // Image w/o '180px-' does not exists, but we do not like these filenames
@@ -1107,7 +1107,7 @@ class UploadSourceField extends HTMLTextField {
         * @return string
         */
        function getLabelHtml( $cellAttributes = array() ) {
-               $id = "wpSourceType{$this->mParams['upload-type']}";
+               $id = $this->mParams['id'];
                $label = Html::rawElement( 'label', array( 'for' => $id ), $this->mLabel );
 
                if ( !empty( $this->mParams['radio'] ) ) {
index 6353b1c..3f9851e 100644 (file)
@@ -192,7 +192,7 @@ class SpecialUploadStash extends UnlistedSpecialPage {
 
                // now we should construct a File, so we can get mime and other such info in a standard way
                // n.b. mimetype may be different from original (ogx original -> jpeg thumb)
-               $thumbFile = new UnregisteredLocalFile( false, 
+               $thumbFile = new UnregisteredLocalFile( false,
                        $this->stash->repo, $thumbnailImage->getStoragePath(), false );
                if ( !$thumbFile ) {
                        throw new UploadStashFileNotFoundException( "couldn't create local file object for thumbnail" );
index 995d879..f80e7da 100644 (file)
@@ -443,7 +443,13 @@ class LoginForm extends SpecialPage {
                }
 
                self::clearCreateaccountToken();
-               return $this->initUser( $u, false );
+
+               $status = $this->initUser( $u, false );
+               if ( !$status->isOK() ) {
+                       $this->mainLoginForm( $status->getHTML() );
+                       return false;
+               }
+               return $status->value;
        }
 
        /**
@@ -452,13 +458,16 @@ class LoginForm extends SpecialPage {
         *
         * @param $u User object.
         * @param $autocreate boolean -- true if this is an autocreation via auth plugin
-        * @return User object.
+        * @return Status object, with the User object in the value member on success
         * @private
         */
        function initUser( $u, $autocreate ) {
                global $wgAuth;
 
-               $u->addToDatabase();
+               $status = $u->addToDatabase();
+               if ( !$status->isOK() ) {
+                       return $status;
+               }
 
                if ( $wgAuth->allowPasswordChange() ) {
                        $u->setPassword( $this->mPassword );
@@ -484,7 +493,7 @@ class LoginForm extends SpecialPage {
                # Update user count
                DeferredUpdates::addUpdate( new SiteStatsUpdate( 0, 0, 0, 0, 1 ) );
 
-               return $u;
+               return Status::newGood( $u );
        }
 
        /**
@@ -730,7 +739,14 @@ class LoginForm extends SpecialPage {
                }
 
                wfDebug( __METHOD__ . ": creating account\n" );
-               $this->initUser( $user, true );
+               $status = $this->initUser( $user, true );
+
+               if ( !$status->isOK() ) {
+                       $errors = $status->getErrorsByType( 'error' );
+                       $this->mAbortLoginErrorMsg = $errors[0]['message'];
+                       return self::ABORTED;
+               }
+
                return self::SUCCESS;
        }
 
@@ -989,9 +1005,12 @@ class LoginForm extends SpecialPage {
                if ( $wgSecureLogin && !$this->mStickHTTPS ) {
                        $options = array( 'http' );
                        $proto = PROTO_HTTP;
-               } else {
+               } elseif( $wgSecureLogin ) {
                        $options = array( 'https' );
                        $proto = PROTO_HTTPS;
+               } else {
+                       $options = array();
+                       $proto = PROTO_RELATIVE;
                }
 
                if ( $type == 'successredirect' ) {
index f52f7bb..ddeb4a1 100644 (file)
@@ -42,7 +42,7 @@ class WantedFilesPage extends WantedQueryPage {
                $catMessage = $this->msg( 'broken-file-category' )
                        ->title( Title::newFromText( "Wanted Files", NS_MAIN ) )
                        ->inContentLanguage();
-               
+
                if ( !$catMessage->isDisabled() ) {
                        $category = Title::makeTitleSafe( NS_CATEGORY, $catMessage->text() );
                } else {
index dec123d..05df400 100644 (file)
@@ -27,7 +27,7 @@
  * @ingroup SpecialPage
  */
 class WantedPagesPage extends WantedQueryPage {
-       
+
        function __construct( $name = 'Wantedpages' ) {
                parent::__construct( $name );
        }
index aa0cc77..ab2a7a3 100644 (file)
@@ -79,21 +79,21 @@ class UploadFromFile extends UploadBase {
         * @return array
         */
        public function verifyUpload() {
-               # Check for a post_max_size or upload_max_size overflow, so that a 
+               # Check for a post_max_size or upload_max_size overflow, so that a
                # proper error can be shown to the user
                if ( is_null( $this->mTempPath ) || $this->isEmptyFile() ) {
                        if ( $this->mUpload->isIniSizeOverflow() ) {
-                               return array( 
+                               return array(
                                        'status' => UploadBase::FILE_TOO_LARGE,
-                                       'max' => min( 
-                                               self::getMaxUploadSize( $this->getSourceType() ), 
-                                               wfShorthandToInteger( ini_get( 'upload_max_filesize' ) ), 
+                                       'max' => min(
+                                               self::getMaxUploadSize( $this->getSourceType() ),
+                                               wfShorthandToInteger( ini_get( 'upload_max_filesize' ) ),
                                                wfShorthandToInteger( ini_get( 'post_max_size' ) )
                                        ),
                                );
                        }
                }
-               
+
                return parent::verifyUpload();
        }
 }
index d3841c9..c4807a6 100644 (file)
@@ -54,6 +54,7 @@ class FakeConverter {
        function convert( $t ) { return $t; }
        function convertTo( $text, $variant ) { return $text; }
        function convertTitle( $t ) { return $t->getPrefixedText(); }
+       function convertNamespace( $ns ) { return $this->mLang->getFormattedNsText( $ns ); }
        function getVariants() { return array( $this->mLang->getCode() ); }
        function getPreferredVariant() { return $this->mLang->getCode(); }
        function getDefaultVariant() { return $this->mLang->getCode(); }
@@ -3546,6 +3547,16 @@ class Language {
                return $this->mConverter->convertTitle( $title );
        }
 
+       /**
+        * Convert a namespace index to a string in the preferred variant
+        *
+        * @param $ns int
+        * @return string
+        */
+       public function convertNamespace( $ns ) {
+               return $this->mConverter->convertNamespace( $ns );
+       }
+
        /**
         * Check if this is a language with variants
         *
index 8a69799..6016605 100644 (file)
@@ -184,7 +184,7 @@ class LanguageConverter {
 
        /**
         * Get default variant.
-        * This function would not be affected by user's settings or headers
+        * This function would not be affected by user's settings
         * @return String: the default variant code
         */
        public function getDefaultVariant() {
@@ -192,6 +192,10 @@ class LanguageConverter {
 
                $req = $this->getURLVariant();
 
+               if ( !$req ) {
+                       $req = $this->getHeaderVariant();
+               }
+
                if ( $wgDefaultLanguageVariant && !$req ) {
                        $req = $this->validateVariant( $wgDefaultLanguageVariant );
                }
@@ -406,7 +410,7 @@ class LanguageConverter {
                                        $attr = $attrs[$attrName];
                                        // Don't convert URLs
                                        if ( !strpos( $attr, '://' ) ) {
-                                               $attr = $this->translate( $attr, $toVariant );
+                                               $attr = $this->convertTo( $attr, $toVariant );
                                        }
 
                                        // Remove HTML tags to avoid disrupting the layout
@@ -546,24 +550,41 @@ class LanguageConverter {
        public function convertTitle( $title ) {
                $variant = $this->getPreferredVariant();
                $index = $title->getNamespace();
-               if ( $index === NS_MAIN ) {
+               if ( $index !== NS_MAIN ) {
+                       $text = $this->convertNamespace( $index ) . ':';
+               } else {
                        $text = '';
+               }
+               $text .= $this->translate( $title->getText(), $variant );
+               return $text;
+       }
+
+       /**
+        * Get the namespace display name in the preferred variant.
+        *
+        * @param $index int namespace id
+        * @return String: namespace name for display
+        */
+       public function convertNamespace( $index ) {
+               $variant = $this->getPreferredVariant();
+               if ( $index === NS_MAIN ) {
+                       return '';
                } else {
-                       // first let's check if a message has given us a converted name
+                       // First check if a message gives a converted name in the target variant.
+                       $nsConvMsg = wfMessage( 'conversion-ns' . $index )->inLanguage( $variant );
+                       if ( $nsConvMsg->exists() ) {
+                               return $nsConvMsg->plain();
+                       }
+                       // Then check if a message gives a converted name in content language
+                       // which needs extra translation to the target variant.
                        $nsConvMsg = wfMessage( 'conversion-ns' . $index )->inContentLanguage();
                        if ( $nsConvMsg->exists() ) {
-                               $text = $nsConvMsg->plain();
-                       } else {
-                               // the message does not exist, try retrieve it from the current
-                               // variant's namespace names.
-                               $langObj = $this->mLangObj->factory( $variant );
-                               $text = $langObj->getFormattedNsText( $index );
+                               return $this->translate( $nsConvMsg->plain(), $variant );
                        }
-                       $text .= ':';
+                       // No message exists, retrieve it from the target variant's namespace names.
+                       $langObj = $this->mLangObj->factory( $variant );
+                       return $langObj->getFormattedNsText( $index );
                }
-               $text .= $title->getText();
-               $text = $this->translate( $text, $variant );
-               return $text;
        }
 
        /**
@@ -1050,7 +1071,7 @@ class LanguageConverter {
         * @param $revision Object: new Revision object or null
         * @return Boolean: true
         */
-       function OnArticleContentSaveComplete( $page, $user, $content, $summary, $isMinor,
+       function OnPageContentSaveComplete( $page, $user, $content, $summary, $isMinor,
                        $isWatch, $section, $flags, $revision ) {
                $titleobj = $page->getTitle();
                if ( $titleobj->getNamespace() == NS_MEDIAWIKI ) {
index 0c8bd22..6482070 100644 (file)
@@ -116,7 +116,7 @@ class LanguageGan extends LanguageZh {
                                                                array(),
                                                                $ml );
 
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 
        /**
index 3ff336b..79e5582 100644 (file)
@@ -233,6 +233,6 @@ class LanguageIu extends Language {
 
                $flags = array();
                $this->mConverter = new IuConverter( $this, 'iu', $variants, $variantfallbacks, $flags );
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 }
index a7e5866..bdaf2f4 100644 (file)
@@ -440,7 +440,7 @@ class LanguageKk extends LanguageKk_cyrl {
 
                $this->mConverter = new KkConverter( $this, 'kk', $variants, $variantfallbacks );
 
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 
        /**
index 9150663..0eac439 100644 (file)
@@ -273,6 +273,6 @@ class LanguageKu extends LanguageKu_ku {
                );
 
                $this->mConverter = new KuConverter( $this, 'ku', $variants, $variantfallbacks );
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 }
index 335d551..4833d1c 100644 (file)
@@ -212,6 +212,6 @@ class LanguageShi extends Language {
 
                $flags = array();
                $this->mConverter = new ShiConverter( $this, 'shi', $variants, $variantfallbacks, $flags );
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 }
index b043778..b472743 100644 (file)
@@ -246,7 +246,7 @@ class LanguageSr extends LanguageSr_ec {
                        'W' => 'W', 'реч'   => 'W', 'reč'   => 'W', 'ријеч' => 'W', 'riječ' => 'W'
                );
                $this->mConverter = new SrConverter( $this, 'sr', $variants, $variantfallbacks, $flags );
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 
        /**
index 2db64a7..a2c917c 100644 (file)
@@ -132,6 +132,6 @@ class LanguageUz extends Language {
                );
 
                $this->mConverter = new UzConverter( $this, 'uz', $variants, $variantfallbacks );
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 }
index 11cf0cf..8bf66a3 100644 (file)
@@ -146,7 +146,7 @@ class LanguageZh extends LanguageZh_hans {
                                                                array(),
                                                                $ml );
 
-               $wgHooks['ArticleContentSaveComplete'][] = $this->mConverter;
+               $wgHooks['PageContentSaveComplete'][] = $this->mConverter;
        }
 
        /**
index 6314006..7980208 100644 (file)
@@ -192,7 +192,7 @@ $messages = array(
 'category-subcat-count-limited' => 'ܣܕܪܐ ܗܢܐ ܐܝܬ ܒܗ {{PLURAL:$1|ܣܕܪܐ ܦܪܥܝܐ ܗܢܐ|$1 ܣܕܪ̈ܐ ܦܪ̈ܥܝܐ ܗܠܝܢ}}.',
 'category-article-count' => '{{PLURAL:$2|ܣܕܪܐ ܗܢܐ ܐܝܬ ܒܗ ܦܐܬܐ ܗܕܐ ܒܠܚܘܕ.|ܐܝܬ {{PLURAL:$1|ܦܐܬܐ|$1 ܦܐܬܬ̈ܐ}} ܒܣܕܪܐ ܗܢܐ، ܡܢ ܣܘܝܟܐ ܕ$2.}}',
 'category-article-count-limited' => '{{PLURAL:$1|ܦܐܬܐ ܗܕܐ|$1 ܦܐܬܬ̈ܐ ܗܠܝܢ}} ܒܣܕܪܐ ܗܢܐ.',
-'category-file-count' => '{{PLURAL:$2|ܣܕܪܐ ܗܢܐ ܐܝܬ ܒܗ ܠܦܦܐ ܗܢܐ ܒܠܚܘܕ.|{{PLURAL:$1|ܠܦܦܐ ܕܐܬܐ ܐܝܬܘܗܝ|$1 ܠܦܦ̈ܐ ܕܐܬܝܢ ܐܝܬܝܗܘܢ}} ܒܣܕܪܐ ܗܢܐ، ܡܢ ܣܘܝܟܐ ܕ$2.}}',
+'category-file-count' => '{{PLURAL:$2|ܣܕܪܐ ܗܢܐ ܐܝܬ ܒܗ ܠܦܦܐ ܗܢܐ ܒܠܚܘܕ.|{{PLURAL:$1|ܠܦܦܐ ܕܐܬܐ ܐܝܬܘܗܝ|$1 ܠܦܦ̈ܐ ܕܐܬܝܢ ܐܝܬܝܗܘܢ}} ܒܣܕܪܐ ܗܢܐ، ܡܢ ܣܘܝܟܐ ܕ$2 ܟܠܢܐܝܬ.}}',
 'category-file-count-limited' => 'ܐܝܬ {{PLURAL:$1|ܠܦܦܐ ܕܐܬܐ|$1 ܠܦܦ̈ܐ ܕܐܬܝܢ}} ܒܣܕܪܐ ܗܫܝܐ.',
 'listingcontinuesabbrev' => '(ܫܘܠܡܐ)',
 
@@ -681,7 +681,7 @@ $1',
 'rows' => 'ܨ̈ܦܐ',
 'columns' => 'ܥܡܘܕ̈ܐ:',
 'searchresultshead' => 'ܒܨܝ',
-'resultsperpage' => 'Ü¡Ü¢Ü\9dÜ¢Ü\90 Ü\95ܦܠÜ\9bÌ\88Ü\90 Ü\92Ü\95ܦܐ:',
+'resultsperpage' => 'Ü¡Ü¢Ü\9dÜ¢Ü\90 Ü\95ܦܠÜ\9bÌ\88Ü\90 Ü\92ܦÜ\90ܬܐ:',
 'recentchangesdays' => 'ܝܘܡܬ̈ܐ ܠܚܙܝܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ:',
 'recentchangescount' => 'ܡܢܝܢܐ ܕܫܘܚܠܦ̈ܐ ܠܚܙܝܐ ܪܫܐܝܬ:',
 'savedprefs' => 'ܨܒܝܢܝܘܬ̈ܟ ܐܬܠܒܟܘ.',
@@ -797,7 +797,7 @@ $1',
 'action-createaccount' => 'ܒܪܝܬܐ ܕܚܘܫܒܢܐ ܕܗܢܐ ܡܦܠܚܢܐ',
 'action-minoredit' => 'ܫܘܕܥܬܐ ܥܠ ܫܘܚܠܦܐ ܗܢܐ ܐܝܟ ܙܥܘܪܐ',
 'action-move' => 'ܫܢܝܬܐ ܕܦܐܬܐ ܗܕܐ',
-'action-move-rootuserpages' => 'Ü«Ü¢Ü\9dܬÜ\90 Ü\95Ü\95Ì\88ܦÜ\90 Ü«ÜªÌ\88Ü«Ü\9dܐ ܕܡܦܠܚܢܐ',
+'action-move-rootuserpages' => 'Ü«Ü¢Ü\9dܬÜ\90 Ü\95ܦÜ\90ܬܬÌ\88Ü\90 Ü«ÜªÌ\88Ü«Ü\9dܬܐ ܕܡܦܠܚܢܐ',
 'action-movefile' => 'ܫܢܝܬܐ ܕܗܢܐ ܠܦܦܐ',
 'action-upload' => 'ܐܣܩܬܐ ܕܗܢܐ ܠܦܦܐ',
 'action-delete' => 'ܫܝܦܬܐ ܕܦܐܬܐ ܗܕܐ',
@@ -862,7 +862,7 @@ $1',
 'minlength1' => 'ܫܡܗ̈ܐ ܕܠܦܦܐ ܘܠܐ ܕܢܗܘܐ ܒܪܝܐ ܡܢ ܐܬܘܬܐ ܚܕܐ ܟܕ ܙܥܘܪ',
 'uploadwarning' => 'ܐܣܩ ܙܘܗܪܐ',
 'savefile' => 'ܠܒܘܟ ܠܦܦܐ',
-'uploadedimage' => '',
+'uploadedimage' => 'ܐܣܩ "[[$1]]"',
 'uploadvirus' => 'ܠܦܦܐ ܐܝܬ ܒܗ ܒܝܪܘܣ!
 ܐܪ̈ܝܟܬܐ: $1',
 'upload-source' => 'ܡܒܘܥܐ ܕܠܦܦܐ',
@@ -979,7 +979,7 @@ $1',
 ܗܫܐ ܐܝܬܝܗܝ  ܨܘܝܒܐ ܠ [[$2]].',
 
 'brokenredirects' => 'ܨܘܝܒ̈ܐ ܬܒܝܪ̈ܐ',
-'brokenredirectstext' => 'ܨÜ\98Ì\88Ü\9dÜ\92Ü\90 Ü\97Ü Ü\9dÜ¢ Ü¡Ü\9bÜ\9dÜ¢ Ü Ü\95Ì\88ܦÜ\90 Ü\95Ü Ü\9dܬܠÜ\97Ü\98ܢ ܐܝܬܘܬܐ:',
+'brokenredirectstext' => 'ܨÜ\98Ì\88Ü\9dÜ\92Ü\90 Ü\97Ü Ü\9dÜ¢ Ü¡Ü\9bÜ\9dÜ¢ Ü Ü¦Ü\90ܬܬÌ\88Ü\90 Ü\95Ü Ü\9dܬܠÜ\97Ü\9dܢ ܐܝܬܘܬܐ:',
 'brokenredirects-edit' => 'ܫܚܠܦ',
 'brokenredirects-delete' => 'ܫܘܦ',
 
@@ -1429,7 +1429,7 @@ Do you want to change the settings?',
 'tooltip-pt-mytalk' => 'ܦܐܬܐ ܕܡܡܠܘܟ',
 'tooltip-pt-preferences' => 'Your preferences',
 'tooltip-pt-watchlist' => 'ܡܟܬܒܢܘܬܐ ܕܦܐܬܬ̈ܐ ܕܒܪܗܝܬ ܐܢܬ ܫܘܚܠܦ̈ܐ ܕܬܗܘܐ ܒܗܘܢ',
-'tooltip-pt-mycontris' => 'ܡܟܬܒܢܘܬܐ ܕܫܘܬܦܘܝܬܘ̈ܟ',
+'tooltip-pt-mycontris' => 'ܡܟܬܒܢܘܬܐ ܕܫܘܬܦܘܝܬ̈ܟ',
 'tooltip-pt-login' => 'ܢܠܒܒ ܠܟ ܕܣܓܠ ܐܢܬ ܥܠܠܐ ܕܝܠܟ، ܐܠܐ ܗܢܐ ܠܐ ܐܝܬܝܗܝ ܐܠܨܝܐ',
 'tooltip-pt-logout' => 'ܦܠܛܐ',
 'tooltip-ca-talk' => 'ܡܡܠܠܐ ܥܠ ܚܒܝܫܬܐ ܕܦܐܬܐ',
@@ -1442,7 +1442,7 @@ Do you want to change the settings?',
 'tooltip-search' => 'ܒܨܝ ܒܓܘ {{SITENAME}}',
 'tooltip-search-fulltext' => 'ܒܨܝ ܒܓܘ ܦܐܬܬ̈ܐ ܥܠ ܗܢܐ ܟܬܝܒܬܐ',
 'tooltip-p-logo' => 'ܦܐܬܐ ܪܝܫܝܬܐ',
-'tooltip-n-mainpage' => 'ܬܪÜ\98ܩܬÜ\90 Ü\95ܦܐܬܐ ܪܝܫܝܬܐ',
+'tooltip-n-mainpage' => 'ܣܥܪ ܦܐܬܐ ܪܝܫܝܬܐ',
 'tooltip-n-mainpage-description' => 'ܬܪܘܩܬܐ ܕܦܐܬܐ ܪܝܫܝܬܐ',
 'tooltip-n-portal' => 'ܚܕܪ ܬܪܡܝܬܐ، ܡܢܐ ܡܫܟܚ ܐܢܬ ܠܥܒܕܐ، ܐܝܟܐ ܬܚܙܝ ܟܠ ܡܐ ܕܣܢܝܩ ܐܢܬ ܠܗ',
 'tooltip-n-recentchanges' => 'ܡܟܬܒܢܘܬܐ ܒܫܘܚܠܦ̈ܐ ܚܕ̈ܬܐ ܒܓܘ ܘܝܩܝ.',
@@ -1456,9 +1456,9 @@ Do you want to change the settings?',
 'tooltip-ca-nstab-main' => 'ܚܘܝ ܦܐܬܬܐ ܕܚܒ̈ܝܫܬܐ',
 'tooltip-ca-nstab-user' => 'ܚܘܝ ܦܐܬܐ ܕܡܦܠܚܢܐ',
 'tooltip-ca-nstab-image' => 'ܚܘܝ ܦܐܬܐ ܕܠܦܦܐ',
-'tooltip-ca-nstab-category' => 'ܚܘܝ ܦܐܬܐ ܕܣܕܪ̈ܐ',
+'tooltip-ca-nstab-category' => 'ܚܘܝ ܦܐܬܐ ܕܣܕܪܐ',
 'tooltip-save' => 'ܠܒܘܟ ܫܘܚܠܦܟ',
-'tooltip-watch' => 'Ü\90Ü\98ܣܦ Ü\97Ü¢Ü\90 Ü¦Ü\90ܬÜ\90 Ü Ü¡Ü\9fܬÜ\92Ü¢Ü\98ܬÜ\90 Ü\95ܪÜ\97Ü\9dܬÜ\98ܟ',
+'tooltip-watch' => 'Ü\90Ü\98ܣܦ Ü¦Ü\90ܬÜ\90 Ü\97Ü\95Ü\90 Ü Ü¡Ü\9fܬÜ\92Ü¢Ü\98ܬÜ\90 Ü\95ܪÌ\88Ü\97Ü\9dܬܟ',
 
 # Attribution
 'anonymous' => '{{PLURAL:$1|ܡܦܠܚܢܐ ܠܐ ܝܕܝܥܐ|ܡܦܠܚܢ̈ܐ ܠܐ ܝܕ̈ܝܥܐ}} ܕ {{SITENAME}}',
index 17b5379..5592b14 100644 (file)
@@ -216,7 +216,7 @@ $messages = array(
 'vector-action-protect' => 'Protexer',
 'vector-action-undelete' => 'Restaurar',
 'vector-action-unprotect' => 'Camudar la proteición',
-'vector-simplesearch-preference' => 'Activar suxerencies meyoraes de gueta (namái apariencia Vector)',
+'vector-simplesearch-preference' => 'Activar la barra de gueta simplificada (namái apariencia Vector)',
 'vector-view-create' => 'Crear',
 'vector-view-edit' => 'Editar',
 'vector-view-history' => 'Ver historial',
@@ -439,10 +439,11 @@ Por favor vuelvi intentalo nunos minutos.',
 'protectedpagetext' => 'Esta páxina ta candada pa torgar la so edición.',
 'viewsourcetext' => "Pues ver y copiar la fonte d'esta páxina:",
 'viewyourtext' => "Pues ver y copiar la fonte de '''les tos ediciones''' d'esta páxina:",
-'protectedinterface' => "Esta páxina proporciona testu d'interfaz de l'aplicación, y ta candada pa torgar abusos.",
-'editinginterface' => "'''Avisu:''' Tas editando una páxina que s'usa pa proporcionar el testu d'interfaz de l'aplicación.
-Los cambeos nesta páxina van afeutar l'apariencia de la interfaz pa otros usuarios.
-Si quies facer traducciones, por favor usa [//translatewiki.net/wiki/Main_Page?setlang=ast translatewiki.net], el proyeutu de traducción de MediaWiki.",
+'protectedinterface' => "Esta páxina proporciona'l testu de la interfaz del software d'esta wiki, y ta candada pa torgar abusos.
+P'amestar o cambiar les traducciones de toles wikis, por favor usa [//translatewiki.net/translatewiki.net], el proyeutu de llocalización de MediaWiki.",
+'editinginterface' => "'''Avisu:''' Tas editando una páxina que s'usa pa proporcionar el testu d'interfaz del programa.
+Los cambeos nesta páxina van afeutar l'apariencia de la interfaz pa otros usuarios d'esta wiki.
+P'amestar o camudar traducciones pa toles wikis, por favor, usa [//translatewiki.net/ translatewiki.net], el proyeutu de traducción de MediaWiki.",
 'sqlhidden' => '(consulta SQL anubrida)',
 'cascadeprotected' => "Esta páxina ta protexida d'ediciones porque ta enxerta {{PLURAL:$1|na siguiente páxina|nes siguientes páxines}}, que {{PLURAL:$1|ta protexida|tán protexíes}} cola opción «en cascada» activada:
 $2",
@@ -747,8 +748,7 @@ Pues [[Special:Search/{{PAGENAME}}|guetar esti títulu de páxina]] n\'otres pá
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} guetar los rexistros rellacionaos],
 o [{{fullurl:{{FULLPAGENAME}}|action=edit}} editar esta páxina equí]</span>.',
 'noarticletext-nopermission' => 'Nestos momentos nun hai testu nesta páxina.
-Pues [[Special:Search/{{PAGENAME}}|guetar esti títulu de páxina]] n\'otres páxines,
-o <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} guetar los rexistros rellacionaos]</span>.',
+Pues [[Special:Search/{{PAGENAME}}|guetar esti títulu de páxina]] n\'otres páxines o <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} guetar los rexistros rellacionaos]</span>, pero nun tienes permisu pa crear esta páxina.',
 'missing-revision' => 'La revisión #$1 de la páxina llamada "{{PAGENAME}}" nun esiste.
 
 De vezu la causa d\'esto ye siguir un enllaz antiguu del historial a una páxina que se desanició.
@@ -858,6 +858,15 @@ Paez que se desanició.',
 'edit-already-exists' => 'Nun se pudo crear una páxina nueva.
 Yá esiste.',
 'defaultmessagetext' => 'Testu predetermináu',
+'content-failed-to-parse' => 'Fallu al analizar el conteníu $2 pal modelu $1: $3',
+'invalid-content-data' => 'Datos del conteníu inválidos',
+'content-not-allowed-here' => 'El conteníu «$1» nun se permite na páxina [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'testu wiki',
+'content-model-text' => 'testu simple',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Avisu:''' Esta páxina contién demasiaes llamaes costoses a funciones d'análisis sintáuticu.
@@ -1209,7 +1218,7 @@ Equí tienes un valor al debalu que pues usar: $1",
 'timezoneregion-indian' => 'Océanu Índicu',
 'timezoneregion-pacific' => 'Océanu Pacíficu',
 'allowemail' => 'Dexar a los otros usuarios mandate correos',
-'prefs-searchoptions' => 'Opciones de busca',
+'prefs-searchoptions' => 'Guetar',
 'prefs-namespaces' => 'Espacios de nome',
 'defaultns' => "D'otra miente, guetar nestos espacios de nome:",
 'default' => 'predetermináu',
@@ -1644,7 +1653,7 @@ Si'l problema persiste, contauta con un [[Special:ListUsers/sysop|alministrador]
 'backend-fail-internal' => 'Hebo un fallu desconocíu nel motor d\'almacenamientu "$1".',
 'backend-fail-contenttype' => 'Non se pudo determinar la triba de conteníu de ficheru a guardar en "$1".',
 'backend-fail-batchsize' => "El motor d'almacenamientu dio un llote de $1 {{PLURAL:$1|operación|operaciones}} en ficheros; el llímite ye de $2 {{PLURAL:$2|operación|operaciones}}.",
-'backend-fail-usable' => 'Nun se pudo escribir el ficheru $1 porque nun hai permisos bastantes o falten los direutorios/contenedores.',
+'backend-fail-usable' => 'Nun se pudo llee o escribir el ficheru «$1» porque nun hai permisos bastantes o falten los direutorios/contenedores.',
 
 # File journal errors
 'filejournal-fail-dbconnect' => 'Nun se pudo coneutar cola base de datos del diariu pal sofitu d\'almacenamientu "$1".',
@@ -2324,7 +2333,8 @@ revisión fuera restaurada o eliminada del archivu.",
 'undeletedrevisions' => '{{PLURAL:$1|1 revisión restaurada|$1 revisiones restauraes}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 revisión|$1 revisiones}} y {{PLURAL:$2|1 archivu|$2 archivos}} restauraos',
 'undeletedfiles' => '{{PLURAL:$1|1 archivu restauráu|$1 archivos restauraos}}',
-'cannotundelete' => 'Falló la restauración; seique daquién yá restaurara la páxina enantes.',
+'cannotundelete' => 'Falló la restauración:
+$1',
 'undeletedpage' => "'''Restauróse $1'''
 
 Consulta'l [[Special:Log/delete|rexistru d'esborraos]] pa ver los esborraos y restauraciones de recién.",
@@ -2622,6 +2632,7 @@ La páxina de destín "[[:$1]]" yá esiste. ¿Quies esborrala pa dexar sitiu pal
 'immobile-target-namespace-iw' => "Nun puedes mover una páxina a un enllaz d'Interwiki.",
 'immobile-source-page' => 'Esta páxina nun ye treslladable.',
 'immobile-target-page' => 'Nun se pue treslladar a esi títulu de destín.',
+'bad-target-model' => 'El destín deseáu utiliza un modelu de conteníu diferente. Nun se pue convertir de $1 a $2.',
 'imagenocrossnamespace' => "Nun se pue treslladar una imaxe a nun espaciu de nomes que nun ye d'imáxenes",
 'nonfile-cannot-move-to-file' => 'Nun se pue treslladar más que ficheros al espaciu de nomes de ficheros',
 'imagetypemismatch' => 'La estensión nueva del archivu nun concueya cola so mena',
@@ -2918,6 +2929,7 @@ Probablemente tea causao por un enllaz a un sitiu esternu de la llista prieta.',
 'pageinfo-magic-words' => '{{PLURAL:$1|Pallabra máxica|Pallabres máxiques}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categoría anubrida|Categoríes anubríes}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Plantía incluída|Plantíes incluíes}} ($1)',
+'pageinfo-toolboxlink' => 'Información de la páxina',
 
 # Skin names
 'skinname-standard' => 'Clásicu',
@@ -3503,7 +3515,8 @@ Esti códigu de confirmación caduca\'l $4.',
 
 # Scary transclusion
 'scarytranscludedisabled' => '[La tresclusión interwiki ta desactivada]',
-'scarytranscludefailed' => '[La obtención de la plantía falló pa $1]',
+'scarytranscludefailed' => '[Falló la recuperación de la plantía pa $1]',
+'scarytranscludefailed-httpstatus' => '[Falló la recuperación de la plantía pa $1: HTTP $2]',
 'scarytranscludetoolong' => '[La URL ye demasiao llarga]',
 
 # Delete conflict
index aee486f..1e0c945 100644 (file)
@@ -10,6 +10,7 @@
  * @author Cekli829
  * @author Don Alessandro
  * @author Emperyan
+ * @author Erdemaslancan
  * @author Gulmammad
  * @author Kaganer
  * @author PPerviz
@@ -730,6 +731,9 @@ Məlumat üçün aşağıda bu səhifənin tarixçəsindən müvafiq silmə qeyd
 'edit-already-exists' => 'Yeni səhifəni yaratmaq mümkün deyil.
 Belə ki, bu adda səhifə artıq mövcuddur.',
 
+# Content models
+'content-model-javascript' => 'JavaScript',
+
 # Parser/template warnings
 'expensive-parserfunction-category' => 'Kifayət qədər böyük sayda genişresurslu funksiyaların müraciət olunduğu səhifələr',
 'post-expand-template-inclusion-warning' => "'''DİQQƏT!''' Daxil edilən şablonların həcmi həddindən artıq böyükdür.
index 3db6342..54f9007 100644 (file)
@@ -305,7 +305,7 @@ $messages = array(
 'tog-nocache' => 'Onemogući keširanje stranica u pregledniku',
 'tog-enotifwatchlistpages' => 'Pošalji mi e-poštu kad se promijene stranice',
 'tog-enotifusertalkpages' => 'Pošalji mi e-poštu kad se promijeni moja korisnička stranica za razgovor',
-'tog-enotifminoredits' => 'Pošalji mi e-poštu takođe za male izmjene stranica',
+'tog-enotifminoredits' => 'Pošalji mi e-poštu također za male izmjene u stranicama i datotekama',
 'tog-enotifrevealaddr' => 'Otkrij adresu moje e-pošte u porukama obaviještenja',
 'tog-shownumberswatching' => 'Prikaži broj korisnika koji prate',
 'tog-oldsig' => 'Postojeći potpis:',
@@ -544,6 +544,8 @@ $1',
 'youhavenewmessages' => 'Imate $1 ($2).',
 'newmessageslink' => 'novih poruka',
 'newmessagesdifflink' => 'posljednja promjena',
+'youhavenewmessagesfromusers' => 'Imate $1 od {{PLURAL:$3|drugog korisnika|$3 korisnika}} ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|novu poruku|nove poruke}}',
 'youhavenewmessagesmulti' => 'Imate nove poruke na $1',
 'editsection' => 'uredi',
 'editsection-brackets' => '[$1]',
@@ -653,7 +655,8 @@ Pretraga: $2',
 'protectedpagetext' => 'Ova stranica je zaključana da bi se spriječile izmjene.',
 'viewsourcetext' => 'Možete vidjeti i kopirati izvorni tekst ove stranice:',
 'viewyourtext' => "Možete da pogledate i kopirate izvor '''vaših izmjena''' na ovoj stranici:",
-'protectedinterface' => 'Ova stranica je zaštićena jer sadrži tekst MediaWiki programa.',
+'protectedinterface' => 'Ova stranica sadrži tekst korisničkog okruženja za softver na ovom wikiju i zaštićena je radi sprečavanja zloupotrebe.
+Da biste dodali ili izmjenili prijevode svih wikija, posjetite [//translatewiki.net/  translatewiki.net], projekat za lokalizaciju Mediawikija.',
 'editinginterface' => "'''Upozorenje:''' Mijenjate stranicu koja sadrži aktivan tekst programa.
 Promjene na ovoj stranici dovode i do promjena za druge korisnike.
 Za prijevode, molimo Vas koristite [//translatewiki.net/wiki/Main_Page?setlang=bs translatewiki.net], projekt prijevoda za MediaWiki.",
@@ -667,6 +670,7 @@ $2',
 'titleprotected' => 'Naslov stranice je zaštićen od postavljanja od strane korisnika [[User:$1|$1]].
 Iz razloga "\'\'$2\'\'".',
 'exception-nologin' => 'Niste prijavljeni',
+'exception-nologin-text' => 'Ova stranica ili aktivnost zahtijeva da budete prijavljeni na ovom wikiju.',
 
 # Virus scanner
 'virus-badscanner' => "Loša konfiguracija: nepoznati anti-virus program: ''$1''",
@@ -687,6 +691,7 @@ Ne zaboravite da prilagodite sebi svoja [[Special:Preferences|{{SITENAME}} pode
 'remembermypassword' => 'Zapamti moju šifru na ovom računaru (najviše $1 {{PLURAL:$1|dan|dana|dana}})',
 'securelogin-stick-https' => 'Ostani povezan na HTTPS nakon prijave',
 'yourdomainname' => 'Vaš domen:',
+'password-change-forbidden' => 'Ne možete da promjenite lozinku na ovom wikiju.',
 'externaldberror' => 'Došlo je do greške pri vanjskoj autorizaciji baze podataka ili vam nije dopušteno osvježavanje Vašeg vanjskog korisničkog računa.',
 'login' => 'Prijavi se',
 'nav-login-createaccount' => 'Prijavi se / Registruj se',
@@ -938,7 +943,7 @@ Ako ste anonimni korisnik i mislite da su vam upućene nebitne primjedbe, molimo
 Možete [[Special:Search/{{PAGENAME}}|tražiti naslov ove stranice]] na drugim stranicama.
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} tražiti u povezanim zapisima] ili [{{fullurl:{{FULLPAGENAME}}|action=edit}} urediti ovu stranicu]</span>.',
 'noarticletext-nopermission' => 'Trenutno nema teksta na ovoj stranici.
-Možete [[Special:Search/{{PAGENAME}}|tražiti ovaj naslov stranice]] na drugim stranicama ili <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti povezane zapisnike]</span>.',
+Možete [[Special:Search/{{PAGENAME}}|tražiti ovaj naslov stranice]] na drugim stranicama ili <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} pretražiti povezane zapisnike]</span>, ali nemate dozvolu da napravite ovu stranicu.',
 'userpage-userdoesnotexist' => 'Korisnički račun "<nowiki>$1</nowiki>" nije registrovan.
 Molimo provjerite da li želite napraviti/izmijeniti ovu stranicu.',
 'userpage-userdoesnotexist-view' => 'Korisnički račun "$1" nije registrovan.',
@@ -948,7 +953,6 @@ Posljednje stavke zapisnika blokiranja možete pogledati ispod:',
 *'''Firefox / Safari:''' držite ''Shift'' tipku i kliknite na ''Reload'' dugme ili pritisnite ''Ctrl-F5'' ili ''Ctrl-R'' (''⌘-R'' na Macu)
 *'''Google Chrome:''' pritisnite ''Ctrl-Shift-R'' (''⌘-Shift-R'' na Macu)
 *'''Internet Explorer:''' držite tipku ''Ctrl'' i kliknite na ''Refresh'' ili pritisnite ''Ctrl-F5''
-*'''Konqueror:''' klikni na ''Reload'' ili pritisnite dugme ''F5''
 *'''Opera:''' očistite \"keš\" preko izbornika ''Tools → Preferences''",
 'usercssyoucanpreview' => "'''Pažnja:''' Koristite dugme \"{{int:showpreview}}\" da testirate svoj novi CSS prije nego što sačuvate.",
 'userjsyoucanpreview' => "'''Pažnja:''' Koristite dugme \"{{int:showpreview}}\" da testirate svoj novi JavaScript prije nego što sačuvate.",
@@ -1051,6 +1055,10 @@ Izgleda da je obrisana.',
 Izgleda da već postoji.',
 'defaultmessagetext' => 'Uobičajeni tekst poruke',
 
+# Content models
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Upozorenje: Ova stranica sadrži previše poziva opterećujućih parserskih funkcija.
 
@@ -1396,7 +1404,7 @@ Ovdje su navedene neke nasumično odabrane vrijednosti koje možete koristiti: $
 'timezoneregion-indian' => 'Indijski okean',
 'timezoneregion-pacific' => 'Tihi okean',
 'allowemail' => 'Dozvoli e-poštu od ostalih korisnika',
-'prefs-searchoptions' => 'Opcije pretrage',
+'prefs-searchoptions' => 'Traži',
 'prefs-namespaces' => 'Imenski prostori',
 'defaultns' => 'Inače tražite u ovim imenskim prostorima:',
 'default' => 'standardno',
@@ -2135,6 +2143,9 @@ Možda sadrži jedan ili više znakova koji se ne mogu koristiti u naslovima.',
 'allpages-bad-ns' => '{{SITENAME}} nema imenski prostor "$1".',
 'allpages-hide-redirects' => 'Sakrij preusmjerenja',
 
+# SpecialCachedPage
+'cachedspecial-refresh-now' => 'Pogledaj najnoviju.',
+
 # Special:Categories
 'categories' => 'Kategorije',
 'categoriespagetext' => '{{PLURAL:$1|Slijedeća kategorija sadrži|Slijedeće kategorije sadrže}} stranice ili multimedijalne datoteke.
@@ -2204,6 +2215,7 @@ O svakoj od njih postoje i [[{{MediaWiki:Listgrouprights-helppage}}|dodatne info
 i imati ispravnu adresu e-pošte u vašim [[Special:Preferences|podešavanjima]]
 da biste slali e-poštu drugim korisnicima.',
 'emailuser' => 'Pošalji e-poštu ovom korisniku',
+'emailuser-title-notarget' => 'Pošalji e-mail korisniku',
 'emailpage' => 'Pošalji e-mail korisniku',
 'emailpagetext' => 'Možete korisiti formu ispod za slanje e-mail poruka ovom korisniku.
 E-mail adresa koju ste unijeli u [[Special:Preferences|Vašim korisničkim postavkama]] će biti prikazana kao adresa pošiljaoca, tako da će primaoc poruke moći da Vam odgovori.',
@@ -3967,6 +3979,12 @@ Inače, možete ispuniti jednostavan obrazac ispod. Vaš komentar biti će dodan
 
 # Durations
 'duration-seconds' => '$1 {{PLURAL:$1|sekunda|sekunde}}',
+'duration-minutes' => '$1 {{PLURAL:$1|minut|minuta|minuta}}',
+'duration-hours' => '$1 {{PLURAL:$1|sat|sata|sati}}',
 'duration-days' => '$1 {{PLURAL:$1|dan|dana}}',
+'duration-weeks' => '$1 {{PLURAL:$1|sedmica|sedmice|sedmica}}',
+'duration-years' => '$1 {{PLURAL:$1|godina|godine|godina}}',
+'duration-decades' => '$1 {{PLURAL:$1|decenija|decenije|decenija}}',
+'duration-centuries' => '$1 {{PLURAL:$1|vijek|vijeka|vijekova}}',
 
 );
index 16b256e..0cc6bcb 100644 (file)
@@ -353,7 +353,7 @@ $messages = array(
 'vector-action-protect' => 'Protegeix',
 'vector-action-undelete' => 'Restaura',
 'vector-action-unprotect' => 'Desprotegeix',
-'vector-simplesearch-preference' => 'Habilitar suggeriments de recerca millorats (només aparença Vector)',
+'vector-simplesearch-preference' => 'Activar la barra de cerca simplificada (només aparença Vector)',
 'vector-view-create' => 'Inicia',
 'vector-view-edit' => 'Modifica',
 'vector-view-history' => "Mostra l'historial",
@@ -430,7 +430,7 @@ $1",
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
 'aboutsite' => 'Quant al projecte {{SITENAME}}',
 'aboutpage' => 'Project:Quant a',
-'copyright' => "El contingut és disponible sota els termes d'una llicència $1",
+'copyright' => 'El contingut està disponible sota els termes de la $1.',
 'copyrightpage' => "{{ns:project}}:Drets d'autor",
 'currentevents' => 'Actualitat',
 'currentevents-url' => 'Project:Actualitat',
@@ -573,7 +573,8 @@ Consulta: $2',
 'protectedpagetext' => 'Aquesta pàgina està protegida per evitar modificacions.',
 'viewsourcetext' => "Podeu visualitzar i copiar la font d'aquesta pàgina:",
 'viewyourtext' => "Vostè pot veure i copiar la font de ' ' les modificacions ' ' d'aquesta pàgina:",
-'protectedinterface' => "Aquesta pàgina conté cadenes de text per a la interfície del programari, i és protegida per a previndre'n abusos.",
+'protectedinterface' => "Aquesta pàgina proporciona el text de la interfície del software d'aquest wiki i està protegida per evitar els abusos.
+Per agregar o canviar les traduccions per a tots els wikis, si us plau fes servir [//translatewiki.net/ translatewiki.net], el projecte de localització de MediaWiki.",
 'editinginterface' => "'''Avís:''' Esteu editant una pàgina que conté cadenes de text per a la interfície d'aquest programari. Tingueu en compte que els canvis que es fan a aquesta pàgina afecten a l'aparença de la interfície d'altres usuaris. Pel que fa a les traduccions, plantegeu-vos utilitzar la [//translatewiki.net/wiki/Main_Page?setlang=ca translatewiki.net], el projecte de traducció de MediaWiki.",
 'sqlhidden' => '(consulta SQL oculta)',
 'cascadeprotected' => "Aquesta pàgina està protegida i no es pot modificar perquè està inclosa en {{PLURAL:$1|la següent pàgina, que té|les següents pàgines, que tenen}} activada l'opció de «protecció en cascada»:
@@ -853,12 +854,11 @@ Detalls es poden trobar en el [{{fullurl: {{# especial: registre}} / delete|page
 'userpage-userdoesnotexist-view' => 'El compte d\'usuari "$1" no està registrat.',
 'blocked-notice-logextract' => "En aquests moments aquest compte d'usuari es troba blocat.
 Per més detalls, la darrera entrada del registre es mostra a continuació:",
-'clearyourcache' => "'''Nota:''' Després de desar, podeu haver d'ometre la memòria cau del vostre navegador per a veure'n els canvis.
-* '''Firefox / Safari:''' Premeu ''Maj'' mentre cliqueu a ''Actualitza'' (Reload), o premeu ''Ctrl+F5'' o ''Ctrl+R'' (''⌘+R'' en un Mac)
-* '''Google Chrome:''' Premeu ''Ctrl+Maj+R'' (''⌘+Maj+R'' en un Mac)
-* '''Internet Explorer:''' Premeu ''Ctrl'' mentre cliqueu a ''Actualitza'' (Refresh), o premeu ''Ctrl+F5''
-* '''Konqueror:''' Cliqueu al botó ''Recarrega'' (Reload), o premeu ''F5''
-* '''Opera:''' Netegeu la vostra memòria cau a ''Tools → Preferences''",
+'clearyourcache' => "'''Nota:''' després de guardar possiblement necessites refrescar el teu cache per poder veure els canvis.
+* '''Firefox / Safari:''' pressiona ''Shift'' mentre cliques el botó ''Actualitzar'', o pressiona ''Ctrl+F5'' o ''Ctrl+R'' (''⌘+R'' a Mac)
+* '''Google Chrome:''' pressiona ''Ctrl+Shift+R'' (''⌘+Shift+R'' a Mac)
+* '''Internet Explorer:''' pressiona la tecla ''Ctrl'' mentre cliques a ''Actualitzar'' o pressiona ''Ctrl+F5''
+* '''Opera:''' buida la memòria cau (cache) ''Eines → Preferències''",
 'usercssyoucanpreview' => "'''Consell:''' Utilitzeu el botó \"{{int:showpreview}}\" per provar el vostre nou CSS abans de desar-lo.",
 'userjsyoucanpreview' => "'''Consell:''' Utilitzeu el botó \"{{int:showpreview}}\" per provar el vostre nou JavaScript abans de desar-lo.",
 'usercsspreview' => "'''Recordeu que esteu previsualitzant el vostre CSS d'usuari.'''
@@ -1008,8 +1008,8 @@ El motiu donat per $3 és ''$2''",
 (prev) = diferència amb la versió anterior, m = modificació menor',
 'history-fieldset-title' => "Cerca a l'historial",
 'history-show-deleted' => 'Només esborrats',
-'histfirst' => 'El primer',
-'histlast' => 'El darrer',
+'histfirst' => 'Primeres',
+'histlast' => 'Últimes',
 'historysize' => '({{PLURAL:$1|1 octet|$1 octets}})',
 'historyempty' => '(buit)',
 
@@ -1110,7 +1110,8 @@ Si us plau, verifica els registres.",
 'revdelete-only-restricted' => 'Error amagant els ítems $2, $1: no pots suprimir elements a la vista dels administradors sense seleccionar alhora una de les altres opcions de supressió.',
 'revdelete-reason-dropdown' => "*Raons d'esborrament comunes
 ** Violació del copyright
-** Informació personal inapropiada
+** Comentari o informació personal inapropiada
+** Nom d'usuari inapropiat
 ** Informació potencialment calumniosa",
 'revdelete-otherreason' => 'Altre motiu / motiu suplementari:',
 'revdelete-reasonotherlist' => 'Altres raons',
@@ -2120,6 +2121,8 @@ Pot ser que hi hagi més informació sobre drets individuals [[{{MediaWiki:Listg
 i tenir una direcció electrònica vàlida en les vostres [[Special:Preferences|preferències]]
 per enviar un correu electrònic a altres usuaris.",
 'emailuser' => 'Envia un missatge de correu electrònic a aquest usuari',
+'emailuser-title-target' => 'Enviar un correu electrònic a {{GENDER:$1|aquest usuari|aquesta usuària}}',
+'emailuser-title-notarget' => "Enviar un correu electrònic a l'usuari",
 'emailpage' => 'Correu electrònic a usuari',
 'emailpagetext' => "Podeu usar el següent formulari per a enviar un missatge de correu electrònic a aquest usuari.
 L'adreça electrònica que heu entrat en [[Special:Preferences|les vostres preferències d'usuari]] apareixerà com a remitent del correu electrònic, de manera que el destinatari us podrà respondre directament.",
@@ -2377,7 +2380,8 @@ al resum a continuació, juntament amb detalls dels usuaris que l'havien editat
 'undeletedrevisions' => '{{PLURAL:$1|Una revisió restaurada|$1 revisions restaurades}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|Una revisió|$1 revisions}} i {{PLURAL:$2|un fitxer|$2 fitxers}} restaurats',
 'undeletedfiles' => '$1 {{PLURAL:$1|fitxer restaurat|fitxers restaurats}}',
-'cannotundelete' => "No s'ha pogut restaurar; algú altre pot estar restaurant la mateixa pàgina.",
+'cannotundelete' => 'Hi ha hagut un error en el procés de restauració:
+$1',
 'undeletedpage' => "'''S'ha restaurat «$1»'''
 
 Consulteu el [[Special:Log/delete|registre d'esborraments]] per a veure els esborraments i els restauraments més recents.",
@@ -2839,7 +2843,7 @@ Deseu-lo al vostre ordinador i carregueu-ne una còpia ací.",
 'tooltip-ca-move' => 'Reanomena aquesta pàgina',
 'tooltip-ca-watch' => 'Afegiu aquesta pàgina a la vostra llista de seguiment.',
 'tooltip-ca-unwatch' => 'Suprimiu aquesta pàgina de la vostra llista de seguiment',
-'tooltip-search' => 'Cerca en el projecte {{SITENAME}}',
+'tooltip-search' => 'Cerca a {{SITENAME}}',
 'tooltip-search-go' => 'Vés a una pàgina amb aquest nom exacte si existeix',
 'tooltip-search-fulltext' => 'Cerca a les pàgines aquest text',
 'tooltip-p-logo' => 'Pàgina principal',
@@ -2880,7 +2884,7 @@ Deseu-lo al vostre ordinador i carregueu-ne una còpia ací.",
 'tooltip-watchlistedit-raw-submit' => 'Actualitza la llista de seguiment',
 'tooltip-recreate' => 'Recrea la pàgina malgrat hagi estat suprimida',
 'tooltip-upload' => 'Inicia la càrrega',
-'tooltip-rollback' => "«Rollback» reverteix les edicions del darrer contribuïdor d'aquesta pàgina en un clic.",
+'tooltip-rollback' => "«Revertir» reverteix totes les edicions de l'últim usuari en un clic.",
 'tooltip-undo' => '«Desfés» reverteix aquesta modificació i obre un formulari de previsualització.
 Permet afegir un motiu al resum.',
 'tooltip-preferences-save' => 'Desa preferències',
@@ -2920,11 +2924,17 @@ Això deu ser degut per un enllaç a un lloc extern inclòs a la llista negra.',
 
 # Info page
 'pageinfo-title' => 'Informació de «$1»',
-'pageinfo-header-edits' => 'Modificacions',
+'pageinfo-header-basic' => 'Informació bàsica',
+'pageinfo-header-edits' => "Historial d'edicions",
+'pageinfo-header-restrictions' => 'Protecció de pàgina',
 'pageinfo-views' => 'Número de visites',
-'pageinfo-watchers' => "Número d'usuaris que l'estan vigilant",
-'pageinfo-edits' => "Número d'edicions",
-'pageinfo-authors' => "Número d'autors diferents",
+'pageinfo-watchers' => "Número d'usuaris que vigilen la pàgina",
+'pageinfo-firstuser' => 'Creador de la pàgina',
+'pageinfo-firsttime' => 'Data de la creació de la pàgina',
+'pageinfo-lastuser' => 'Últim editor',
+'pageinfo-lasttime' => "Data de l'última edició",
+'pageinfo-edits' => "Número total d'edicions",
+'pageinfo-authors' => "Número total d'autors diferents",
 
 # Skin names
 'skinname-standard' => 'Clàssic',
index ee80d56..8259eff 100644 (file)
@@ -2584,13 +2584,13 @@ $1',
 'import-logentry-interwiki-detail' => '$1 {{PLURAL:$1|پێداچوونەوە|پێداچوونەوە}} لە $2',
 
 # Tooltip help for the actions
-'tooltip-pt-userpage' => 'پەڕە بەکارھێنەریی تۆ',
+'tooltip-pt-userpage' => 'پەڕەی بەکارھێنەرییەکەت',
 'tooltip-pt-anonuserpage' => 'پەڕەی بەکارھێنەری بۆ ئای‌پی یەکە کە بەناویەوە خەریکی دەستکاری کردنی',
-'tooltip-pt-mytalk' => 'Ù¾Û\95Ú\95Û\95Û\8c Ù\88تÙ\88بÛ\8eÚ\98Û\8c ØªÛ\86',
+'tooltip-pt-mytalk' => 'Ù¾Û\95Ú\95Û\95Û\8c Ù\84Û\8eدÙ\88اÙ\86Û\95Ú©Û\95ت',
 'tooltip-pt-anontalk' => 'لێدوان لەسەر دەستکارییەکان لەم ئایپی ئەدرەسەوە',
-'tooltip-pt-preferences' => 'بژاردەکانت',
+'tooltip-pt-preferences' => 'هەڵبژاردەکانت',
 'tooltip-pt-watchlist' => 'پێرستی ئەو پەڕانە کە چاودێریی گۆڕانکارییەکانیانی دەکەی',
-'tooltip-pt-mycontris' => 'Ù\84Û\8cستی بەشدارییەکانت',
+'tooltip-pt-mycontris' => 'Ù¾Û\8eرستی بەشدارییەکانت',
 'tooltip-pt-login' => 'پێشنیارت پێدەکرێ بچیتە ژوورەوە؛ ھەرچەندە زۆرت لێناکرێ',
 'tooltip-pt-anonlogin' => 'پێشنیار دەکەین بڕۆیتەژوورەوە، ئەگەرچی ئەوە زۆرەملیی نیە',
 'tooltip-pt-logout' => 'دەرچوون',
index ce8cf6e..2c9c6ad 100644 (file)
@@ -1119,6 +1119,15 @@ Zřejmě byla smazána.',
 'edit-no-change' => 'Vaše editace byla ignorována, protože nedošlo k žádné změně textu.',
 'edit-already-exists' => 'Nepodařilo se vytvořit novou stránku, protože již existuje.',
 'defaultmessagetext' => 'Výchozí text hlášení',
+'content-failed-to-parse' => 'Nepodařilo se zpracovat data $2 do modelu $1: $3',
+'invalid-content-data' => 'Obsažená data jsou chybná',
+'content-not-allowed-here' => 'Obsah typu $1 není na stránce [[$2]] dovolen.',
+
+# Content models
+'content-model-wikitext' => 'wikitext',
+'content-model-text' => 'čistý text',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Varování: Tato stránka obsahuje příliš mnoho volání výkonnostně náročných funkcí parseru.
@@ -2554,7 +2563,8 @@ Pro částečné obnovení zaškrtněte čtverečky u obnovovaných revizí a kl
 'undeletedrevisions' => '{{PLURAL:$1|Obnovena $1 verze|Obnoveny $1 verze|Obnoveno $1 verzí}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|Obnovena jedna verze|Obnoveny $1 verze|Obnoveno $1 verzí}} a $2 {{PLURAL:$2|soubor|soubory|souborů}}.',
 'undeletedfiles' => '{{PLURAL:$1|obnoven $1 soubor|obnoveny $1 soubory|obnoveno $1 souborů}}',
-'cannotundelete' => 'Obnovení se nepovedlo; stránku již pravděpodobně obnovil někdo jiný.',
+'cannotundelete' => 'Obnovení se nezdařilo:
+$1',
 'undeletedpage' => "'''$1 byla obnovena'''
 
 Záznam o posledních mazáních a obnoveních najdete v [[Special:Log/delete|knize smazaných stránek]].",
@@ -2848,6 +2858,7 @@ Cílová stránka „[[:$1]]“ již existuje. Přejete si ji smazat pro uvolně
 'immobile-target-namespace-iw' => 'Mezijazykový odkaz není validní cíl při přesouvání stránky.',
 'immobile-source-page' => 'Tuto stránku nelze přesouvat.',
 'immobile-target-page' => 'Stránku nelze přesunout na zadaný název.',
+'bad-target-model' => 'Požadovaný cíl používá jiný model obsahu. Nelze převést $1 na $2.',
 'imagenocrossnamespace' => 'Nelze přesunout mimo jmenný prostor Soubor:',
 'nonfile-cannot-move-to-file' => 'Do jmenného prostoru {{ns:file}} nelze přesouvat stránky nepřináležející k souboru',
 'imagetypemismatch' => 'Nová přípona souboru neodpovídá jeho typu',
index 0022d3b..7e5c8ad 100644 (file)
@@ -952,6 +952,15 @@ Den ser du til at være slettet.',
 'edit-no-change' => 'Din ændring ignoreredes, fordi der ikke var ændring af teksten.',
 'edit-already-exists' => 'En ny side kunne ikke oprettes, fordi den allerede findes.',
 'defaultmessagetext' => 'Standardtekst',
+'content-failed-to-parse' => 'Kunne ikke parse $2 indhold for $1 model: $3',
+'invalid-content-data' => 'Ugyldig indholdsdata',
+'content-not-allowed-here' => '"$1" indhold er ikke tilladt på siden [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitekst',
+'content-model-text' => 'almindelig tekst',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Advarsel: Der er for mange beregningstunge oversætter-funktionskald på denne side.
@@ -2378,7 +2387,8 @@ Teksten i de slettede versioner er kun tilgængelig for administratorer.',
 'undeletedrevisions' => '$1 {{PLURAL:$1|version|versioner}} gendannet',
 'undeletedrevisions-files' => '$1 {{plural:$1|version|versioner}} og $2 {{plural:$2|fil|filer}} gendannet',
 'undeletedfiles' => '$1 {{plural:$1|fil|filer}} gendannet',
-'cannotundelete' => 'Gendannelse mislykkedes; en anden har allerede gendannet siden.',
+'cannotundelete' => 'Gendannelse mislykkedes:
+$1',
 'undeletedpage' => "'''$1''' blev gendannet.
 
 I [[Special:Log/delete|slette-loggen]] findes en oversigt over de nyligt slettede og gendannede sider.",
@@ -2665,6 +2675,7 @@ Artiklen "[[:$1]]" eksisterer allerede. Vil du slette den for at gøre plads til
 'immobile-target-namespace-iw' => 'En side kan ikke flyttes til en interwiki-henvisning.',
 'immobile-source-page' => 'Denne side kan ikke flyttes.',
 'immobile-target-page' => 'Kan ikke flytte til det navn.',
+'bad-target-model' => 'Den ønskede destination bruger en anden indholdsmodel. Kan ikke konvertere fra $1 til $2.',
 'imagenocrossnamespace' => 'Filer kan ikke flyttes til et navnerum der ikke indeholder filer',
 'nonfile-cannot-move-to-file' => 'Kan ikke flytte ikke-filer til fil-navnerummet',
 'imagetypemismatch' => 'Den nye filendelse passer ikke til filtypen',
index 869b998..bfc89d4 100644 (file)
@@ -1166,6 +1166,15 @@ Sie wurde anscheinend gelöscht.',
 'edit-no-change' => 'Deine Bearbeitung wurde ignoriert, da keine Änderung an dem Text vorgenommen wurde.',
 'edit-already-exists' => 'Die neue Seite konnte nicht erstellt werden, da sie bereits vorhanden ist.',
 'defaultmessagetext' => 'Standardtext',
+'content-failed-to-parse' => 'Parsen des Inhalts $2 für Modell $1 fehlgeschlagen: $3',
+'invalid-content-data' => 'Ungültige Inhaltsdaten',
+'content-not-allowed-here' => 'Der Inhalt „$1“ ist auf der Seite [[$2]] nicht erlaubt',
+
+# Content models
+'content-model-wikitext' => 'Wikitext',
+'content-model-text' => 'Klartext',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Achtung''': Diese Seite enthält zu viele Aufrufe aufwändiger Parserfunktionen.
@@ -2602,7 +2611,7 @@ Der aktuelle Text der gelöschten Seite ist nur Administratoren zugänglich.',
 'undeletedrevisions' => '{{PLURAL:$1|1 Version wurde|$1 Versionen wurden}} wiederhergestellt',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 Version|$1 Versionen}} und {{PLURAL:$2|1 Datei|$2 Dateien}} wurden wiederhergestellt',
 'undeletedfiles' => '{{PLURAL:$1|1 Datei wurde|$1 Dateien wurden}} wiederhergestellt',
-'cannotundelete' => 'Wiederherstellung fehlgeschlagen:
+'cannotundelete' => 'Die Wiederherstellung ist fehlgeschlagen:
 $1',
 'undeletedpage' => "'''„$1“''' wurde wiederhergestellt.
 
@@ -2901,6 +2910,7 @@ Eine Seite kann nicht auf sich selbst verschoben werden.',
 'immobile-target-namespace-iw' => 'Interwiki-Link ist kein gültiges Ziel für Seitenverschiebungen.',
 'immobile-source-page' => 'Diese Seite ist nicht verschiebbar.',
 'immobile-target-page' => 'Es kann nicht auf diese Zielseite verschoben werden.',
+'bad-target-model' => 'Die gewünschte Zielseite verwendet ein abweichendes Inhaltsmodell. Das Inhaltsmodell $1 kann nicht in das Inhaltsmodell $2 umgewandelt werden.',
 'imagenocrossnamespace' => 'Dateien können nicht aus dem {{ns:file}}-Namensraum heraus verschoben werden',
 'nonfile-cannot-move-to-file' => 'Nichtdateien können nicht in den {{ns:file}}-Namensraum hinein verschoben werden',
 'imagetypemismatch' => 'Die neue Dateierweiterung ist nicht mit der alten identisch',
@@ -3166,6 +3176,7 @@ Das liegt wahrscheinlich an einem Link auf eine externe Seite.',
 
 # Info page
 'pageinfo-title' => 'Informationen zu „$1“',
+'pageinfo-not-current' => 'Die Information könnte nur für die aktuelle Version angezeigt werden.',
 'pageinfo-header-basic' => 'Basisinformationen',
 'pageinfo-header-edits' => 'Bearbeitungsgeschichte',
 'pageinfo-header-restrictions' => 'Seitenschutz',
index d945252..158e138 100644 (file)
@@ -1075,6 +1075,15 @@ Hewna kerde aseno.',
 'edit-already-exists' => 'Pelo newe nêvıraziyeno.
 Pel ca ra esto.',
 'defaultmessagetext' => 'Hesıbyaye metne mesaci',
+'content-failed-to-parse' => 'Qandê madela $3 zereyê $1, $2 sero nêagozyayo',
+'invalid-content-data' => 'Zerrey malumati nêravêrdeyo',
+'content-not-allowed-here' => '"$1" sero per da [[$2]] rê mısade nêdeyêno',
+
+# Content models
+'content-model-wikitext' => 'wikimetin',
+'content-model-text' => 'duz metin',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Hişyari: No pel de fonksiyoni zaf esti.
@@ -2527,7 +2536,8 @@ Revizyoni ya hewn a biyê ya arşiw ra veciyayê ya zi cıresayişê şımayi ş
 'undeletedrevisions' => 'pêro piya{{PLURAL:$1|1 qeyd|$1 qeyd}} tepiya anciya.',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 revizyon|$1 revizyon}} u {{PLURAL:$2|1 dosya|$2 dosya}} ameyê halê xo yê verıni',
 'undeletedfiles' => '{{PLURAL:$1|1 dosya|$1 dosya}} tepiya anciyayi.',
-'cannotundelete' => 'şıma ya ver yewna ten pel u medya tepiya ard u ê ra tepiya ardışê şıma meqbul niyo.',
+'cannotundelete' => 'Besternayışo nêbeno:
+$1',
 'undeletedpage' => "'''$1 pel tepiya anciya'''
 
 qey karê tepiya ardışi u qey karê hewn a kerdışê verıni bıewnê [[Special:Log/delete|qeydê hewn a kerdışi]].",
@@ -2833,6 +2843,7 @@ Yewna name bınus.',
 'immobile-target-namespace-iw' => 'xetê benatê wikiyan, hedefê pelkırıştış niyo',
 'immobile-source-page' => 'nameyê no peli nêvuriyeno',
 'immobile-target-page' => 'sernameyê no hedefi re nêkırışiyeno',
+'bad-target-model' => 'Hedefo ke waştiyayo zerreke cı babetna model karneno. Ke nêşeno $1 ra açarno $2.',
 'imagenocrossnamespace' => 'Dosya, ca yo ke qey nameyê dosyayan nêbıbo nêkırışiyeno',
 'nonfile-cannot-move-to-file' => 'Ekê dosya niyê, cade namande dosyaya nêahulneyênê',
 'imagetypemismatch' => 'tipa dosyaya neweyi re pênêgıneno/nêgıneno pê',
index bf2393c..cb60050 100644 (file)
@@ -898,6 +898,15 @@ Zda sem až jo wulašowany.',
 'edit-already-exists' => 'Njejo móžno było nowy bok napóraś.
 Eksistěrujo južo.',
 'defaultmessagetext' => 'Standardny tekst powěźeńki',
+'content-failed-to-parse' => 'Parsowanje wopśimjeśa $2 za model $1 jo se njeraźiło: $3',
+'invalid-content-data' => 'Njepłaśiwe wopśimjeśowe daty',
+'content-not-allowed-here' => 'Wopśimjeśe "$1" njejo na boku [[$2]] dowólone',
+
+# Content models
+'content-model-wikitext' => 'wikitekst',
+'content-model-text' => 'lutny tekst',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Warnowanje: Toś ten bok wopśimujo pśewjele wołanjow parserowych funkcijow wupominajucych wusoke wugbaśe.
@@ -2324,7 +2333,8 @@ W takich padach dejš nejnowše wulašowane wersije markěroanje abo schowanje w
 'undeletedrevisions' => '{{PLURAL:$1|1 wersija jo se nawrośiła|$1 wersiji stej se nawrośiłej|$1 wersije su se nawrośili}}.',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 wersija|$1 wersiji|$1 wersije}} a {{PLURAL:$2|1 dataja|$2 dataji|$2 dataje}} {{PLURAL:$2|jo se nawrośiła|stej se nawrośiłej|su se nawrośili}}.',
 'undeletedfiles' => '{{PLURAL:$1|1 dataja jo se nawrośiła|$1 dataji stej se nawrośiłej|$1 dataje su se nawrośili}}.',
-'cannotundelete' => 'Nawrośenje njejo se zglucyło; něchten drugi jo bok južo nawrośił.',
+'cannotundelete' => 'Wótnowjenje jo se njeraźiło:
+$1',
 'undeletedpage' => "Bok '''$1''' jo se nawrośił.
 
 W [[Special:Log/delete|log-lisćinje wulašowanjow]] namakajoš pśeglěd wulašowanych a nawrośonych bokow.",
@@ -2614,6 +2624,7 @@ Bok „[[:$1]]“ južo eksistěrujo. Coš jen wulašowaś, aby mógał toś ten
 'immobile-target-namespace-iw' => 'Interwiki-wótkaz njejo płaśiwy cel za pśesunjenja bokow.',
 'immobile-source-page' => 'Toś ten bok njedajo se pśesunuś.',
 'immobile-target-page' => 'Njejo móžno na toś ten celowy bok pśesunuś.',
+'bad-target-model' => 'Póžedany cel wužywa drugi wopśimjeśowy model. $1 njedajo se do $2 konwertěrowaś.',
 'imagenocrossnamespace' => 'Dataja njedajo se pśesunuś do mjenjowego ruma, kótarež njejo za dataje.',
 'nonfile-cannot-move-to-file' => 'Njedataje njedaje se do datajowego mjenjowego ruma pśesunuś',
 'imagetypemismatch' => 'Nowy datajowy sufiks swójomu typoju njewótpowědujo',
index 70c86bc..793e249 100644 (file)
@@ -893,7 +893,6 @@ $1',
 'portal-url'           => 'Project:Community portal',
 'privacy'              => 'Privacy policy',
 'privacypage'          => 'Project:Privacy policy',
-'content-failed-to-parse' => "Failed to parse $2 content for $1 model: $3",
 
 'badaccess'        => 'Permission error',
 'badaccess-group0' => 'You are not allowed to execute the action you have requested.',
@@ -1428,7 +1427,7 @@ If you save it, any changes made since this revision will be lost.",
 'yourdiff'                         => 'Differences',
 'copyrightwarning'                 => "Please note that all contributions to {{SITENAME}} are considered to be released under the $2 (see $1 for details).
 If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.<br />
-You are also promising us that you wrote this yourself, or copied editpageit from a public domain or similar free resource.
+You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
 '''Do not submit copyrighted work without permission!'''",
 'copyrightwarning2'                => "Please note that all contributions to {{SITENAME}} may be edited, altered, or removed by other contributors.
 If you do not want your writing to be edited mercilessly, then do not submit it here.<br />
@@ -1485,9 +1484,16 @@ It already exists.',
 'addsection-preload'               => '', # do not translate or duplicate this message to other languages
 'addsection-editintro'             => '', # do not translate or duplicate this message to other languages
 'defaultmessagetext'               => 'Default message text',
+'content-failed-to-parse'          => 'Failed to parse $2 content for $1 model: $3',
 'invalid-content-data'             => 'Invalid content data',
 'content-not-allowed-here'         => '"$1" content is not allowed on page [[$2]]',
 
+# Content models
+'content-model-wikitext'   => 'wikitext',
+'content-model-text'       => 'plain text',
+'content-model-javascript' => 'JavaScript',
+'content-model-css'        => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning'        => "'''Warning:''' This page contains too many expensive parser function calls.
 
@@ -2460,7 +2466,7 @@ Maybe you want to edit the description on its [$2 file description page] there.'
 'shared-repo'                       => 'a shared repository',
 'shared-repo-name-wikimediacommons' => 'Wikimedia Commons', # only translate this message to other languages if you have to change it
 'filepage.css'                      => '/* CSS placed here is included on the file description page, also included on foreign client wikis */', # only translate this message to other languages if you have to change it
-'upload-disallowed-here'            => 'Unfortunately you cannot overwrite this image.',
+'upload-disallowed-here'            => 'You cannot overwrite this file.',
 
 # File reversion
 'filerevert'                => 'Revert $1',
@@ -3737,6 +3743,7 @@ This is probably caused by a link to a blacklisted external site.',
 # Info page
 'pageinfo-header'              => '-', # do not translate or duplicate this message to other languages
 'pageinfo-title'               => 'Information for "$1"',
+'pageinfo-not-current'         => 'Information may only be displayed for the current revision.',
 'pageinfo-header-basic'        => 'Basic information',
 'pageinfo-header-edits'        => 'Edit history',
 'pageinfo-header-restrictions' => 'Page protection',
@@ -4947,10 +4954,4 @@ Otherwise, you can use the easy form below. Your comment will be added to the pa
 'duration-centuries' => '$1 {{PLURAL:$1|century|centuries}}',
 'duration-millennia' => '$1 {{PLURAL:$1|millennium|millennia}}',
 
-# Content model IDs for the ContentHandler facility; used by ContentHandler::getContentModel()
-'content-model-wikitext' => 'wikitext',
-'content-model-javascript' => 'JavaScript',
-'content-model-css' => 'CSS',
-'content-model-text' => 'plain text',
-
 );
index 29fe179..57f0ba9 100644 (file)
@@ -510,7 +510,7 @@ $messages = array(
 'faqpage' => 'Project:FAQ',
 
 # Vector skin
-'vector-action-addsection' => 'Añadir tema',
+'vector-action-addsection' => 'Nueva sección',
 'vector-action-delete' => 'Borrar',
 'vector-action-move' => 'Mover',
 'vector-action-protect' => 'Proteger',
@@ -1135,6 +1135,15 @@ Parece que ha sido borrada.',
 'edit-already-exists' => 'No se pudo crear una página nueva.
 Ya existe.',
 'defaultmessagetext' => 'Texto de mensaje predeterminado',
+'content-failed-to-parse' => 'No se pudo analizar el contenido $2 del modelo $1: $3',
+'invalid-content-data' => 'Datos de contenido inválidos',
+'content-not-allowed-here' => 'El contenido "$1" no está permitido en la página [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'texto wiki',
+'content-model-text' => 'Texto sin formato',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Aviso: Esta página contiene demasiadas llamadas a funciones sintácticas costosas (#ifexist: y similares)
@@ -1189,7 +1198,7 @@ El motivo dado por $3 es ''$2''",
 Leyenda: (act) = diferencias con la versión actual,
 (prev) = diferencias con la versión previa, M = edición menor",
 'history-fieldset-title' => 'Buscar en el historial',
-'history-show-deleted' => 'Solamente borrado',
+'history-show-deleted' => 'Solo ediciones ocultadas',
 'histfirst' => 'Primeras',
 'histlast' => 'Últimas',
 'historysize' => '({{PLURAL:$1|1 byte|$1 bytes}})',
@@ -2236,7 +2245,7 @@ Por favor note que otros sitios web pueden vincular a un archivo con un URL dire
 Puedes filtrar la vista seleccionando un tipo de registro, el nombre del usuario o la página afectada. Se distinguen mayúsculas de minúsculas.',
 'logempty' => 'No hay elementos en el registro con esas condiciones.',
 'log-title-wildcard' => 'Buscar títulos que empiecen con este texto',
-'showhideselectedlogentries' => 'Mostrar u ocultar las entradas del registro seleccionado',
+'showhideselectedlogentries' => 'Mostrar u ocultar las entradas seleccionadas del registro',
 
 # Special:AllPages
 'allpages' => 'Todas las páginas',
@@ -2582,8 +2591,8 @@ o a que la revisión haya sido restaurada o eliminada del archivo.',
 'undeletedrevisions' => '{{PLURAL:$1|Una edición restaurada|$1 ediciones restauradas}}',
 'undeletedrevisions-files' => '$1 {{PLURAL:$1|ediciones restauradas y $2 archivo restaurado|ediciones y $2 archivos restaurados}}',
 'undeletedfiles' => '$1 {{PLURAL:$1|archivo restaurado|archivos restaurados}}',
-'cannotundelete' => 'Ha fallado el deshacer el borrado;
-alguien más puede haber deshecho el borrado antes.',
+'cannotundelete' => 'Hubo un error durante la restauración:
+$1',
 'undeletedpage' => "'''Se ha restaurado $1'''
 
 Consulta el [[Special:Log/delete|registro de borrados]] para ver una lista de los últimos borrados y restauraciones.",
@@ -2638,7 +2647,7 @@ $1',
 A continuación se muestra la última entrada del registro de bloqueos para mayor referencia.',
 'sp-contributions-search' => 'Buscar contribuciones',
 'sp-contributions-username' => 'Dirección IP o nombre de usuario:',
-'sp-contributions-toponly' => 'Mostrar solamente revisiones top',
+'sp-contributions-toponly' => 'Solo mostrar últimas ediciones de página',
 'sp-contributions-submit' => 'Buscar',
 
 # What links here
@@ -2883,6 +2892,7 @@ no se puede trasladar una página sobre sí misma.',
 'immobile-target-namespace-iw' => 'Un enlace interwiki no es un destino válido para trasladar una página.',
 'immobile-source-page' => 'Esta página no se puede renombrar.',
 'immobile-target-page' => 'No se puede trasladar a tal título.',
+'bad-target-model' => 'El destino deseado utiliza un modelo diferente de contenido. No se puede realizar la conversión de $1 a $2.',
 'imagenocrossnamespace' => 'No se puede trasladar el fichero a otro espacio de nombres',
 'nonfile-cannot-move-to-file' => 'No es posible mover un no-archivo al espacio de nombres de archivo',
 'imagetypemismatch' => 'La nueva extensión de archivo no corresponde con su tipo',
@@ -3991,8 +4001,8 @@ Este sitio está experimentando dificultades técnicas.',
 'sqlite-no-fts' => '$1 sin soporte para búsqueda de texto completo',
 
 # New logging system
-'logentry-delete-delete' => '$1 borró la página $3',
-'logentry-delete-restore' => '$1 restauró la página $3',
+'logentry-delete-delete' => '$1 borró la página «$3»',
+'logentry-delete-restore' => '$1 restauró la página «$3»',
 'logentry-delete-event' => '$1 modificó la visibilidad de {{PLURAL:$5|un evento del registro|$5 eventos del registro}} en $3: $4',
 'logentry-delete-revision' => '$1 modificó la visibilidad de {{PLURAL:$5|una edición|$5 ediciones}} en la página $3: $4',
 'logentry-delete-event-legacy' => '$1 modificó la visibilidad de los eventos del registro en $3',
index 64bd2d4..19cb9c3 100644 (file)
@@ -589,7 +589,7 @@ $messages = array(
 'vector-action-protect' => 'محافظت',
 'vector-action-undelete' => 'احیا',
 'vector-action-unprotect' => 'تغییر سطح حفاظت',
-'vector-simplesearch-preference' => 'فعال کردن پیشنهادهای جستجوی پیشرفته (فقط در پوستهٔ برداری)',
+'vector-simplesearch-preference' => 'فعال کردن جستجوی ساده (فقط در پوستهٔ برداری)',
 'vector-view-create' => 'ایجاد',
 'vector-view-edit' => 'ویرایش',
 'vector-view-history' => 'نمایش تاریخچه',
@@ -674,7 +674,7 @@ $1',
 'disclaimerpage' => 'Project:تکذیب‌نامهٔ عمومی',
 'edithelp' => 'راهنمای ویرایش‌کردن',
 'edithelppage' => 'Help:ویرایش',
-'helppage' => 'Help:محتویات',
+'helppage' => 'Help:محتوا',
 'mainpage' => 'صفحهٔ اصلی',
 'mainpage-description' => 'صفحهٔ اصلی',
 'policy-url' => 'Project:سیاست‌ها',
@@ -1414,8 +1414,8 @@ $1",
 'mergehistory-fail' => 'ادغام تاریخچه ممکن نیست، لطفاً گزینه‌های صفحه و زمان را بازبینی کنید.',
 'mergehistory-no-source' => 'صفحهٔ مبدأ $1 وجود ندارد.',
 'mergehistory-no-destination' => 'صفحهٔ مقصد $1 وجود ندارد.',
-'mergehistory-invalid-source' => 'صفحهٔ مبدأ باید عنوان قابل قبولی داشته باشد.',
-'mergehistory-invalid-destination' => 'صفحهٔ مقصد باید عنوان قابل قبولی داشته باشد.',
+'mergehistory-invalid-source' => 'صفحهٔ مبدأ باید عنوانی معتبر داشته باشد.',
+'mergehistory-invalid-destination' => 'صفحهٔ مقصد باید عنوانی معتبر داشته باشد.',
 'mergehistory-autocomment' => '[[:$1]] را در [[:$2]] ادغام کرد',
 'mergehistory-comment' => '[[:$1]] را در [[:$2]] ادغام کرد: $3',
 'mergehistory-same-destination' => 'صفحهٔ مبدأ و مقصد نمی‌تواند یکی باشد',
@@ -1463,7 +1463,7 @@ $1",
 'searchmenu-legend' => 'گزینه‌های جستجو',
 'searchmenu-exists' => "'''صفحه‌ای با عنوان \"[[:\$1]]\" در این ویکی وجود دارد.'''",
 'searchmenu-new' => "'''صفحهٔ «[[:$1]]» را در این ویکی بسازید!'''",
-'searchhelp-url' => 'Help:راهنما',
+'searchhelp-url' => 'Help:محتوا',
 'searchmenu-prefix' => '[[Special:PrefixIndex/$1|مرور صفحه‌های با این پیشوند]]',
 'searchprofile-articles' => 'صفحه‌های محتوایی',
 'searchprofile-project' => 'صفحه‌های راهنما و پروژه',
@@ -3268,6 +3268,7 @@ $1',
 'pageinfo-magic-words' => '{{PLURAL:$1|حرف|حروف}} جادویی ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1| ردهٔ|ردهٔ}} پنهان ( $1 )',
 'pageinfo-templates' => '{{PLURAL:$1|الگو|الگو}} استفاده‌شده ($1)',
+'pageinfo-toolboxlink' => 'اطلاعات صفحه',
 
 # Skin names
 'skinname-standard' => 'کلاسیک',
@@ -3847,6 +3848,7 @@ $5
 # Scary transclusion
 'scarytranscludedisabled' => '[تراگنجانش بین‌ویکیانه فعال نیست]',
 'scarytranscludefailed' => '[فراخوانی الگو برای $1 میسر نشد]',
+'scarytranscludefailed-httpstatus' => '[فراخوانی الگو برای $1 میسر نشد: خطای اچ‌تی‌تی‌پی $2]',
 'scarytranscludetoolong' => '[نشانی اینترنتی مورد نظر (URL) بیش از اندازه بلند بود]',
 
 # Delete conflict
index 1910d80..23d307c 100644 (file)
@@ -673,8 +673,8 @@ Joku muu on saattanut poistaa sen.',
 'delete-hook-aborted' => 'Laajennuskoohdi esti muokkauksen antamatta syytä.',
 'badtitle' => 'Virheellinen otsikko',
 'badtitletext' => 'Pyytämäsi sivuotsikko oli virheellinen, tyhjä tai väärin linkitetty kieltenvälinen tai wikienvälinen linkki.',
-'perfcached' => 'Tiedot ovat välimuistista eivätkä välttämättä ole ajan tasalla. Välimuistissa on enintään {{PLURAL:$1|yksi tulos|$1 tulosta}}.',
-'perfcachedts' => 'Tiedot ovat välimuistista ja se päivitettiin viimeksi $1. Välimuistissa on enintään {{PLURAL:$4|yksi tulos|$4 tulosta}}.',
+'perfcached' => 'Tiedot ovat välimuistista eivätkä välttämättä ole ajan tasalla. Välimuistissa on saatavilla enintään {{PLURAL:$1|yksi tulos|$1 tulosta}}.',
+'perfcachedts' => 'Tiedot ovat välimuistista ja se päivitettiin viimeksi $1. Välimuistissa on saatavilla enintään {{PLURAL:$4|yksi tulos|$4 tulosta}}.',
 'querypage-no-updates' => 'Tämän sivun tietoja ei toistaiseksi päivitetä.',
 'wrong_wfQuery_params' => 'Virheelliset parametrit wfQuery()<br />Funktio: $1<br />Tiedustelu: $2',
 'viewsource' => 'Lähdekoodi',
@@ -994,7 +994,7 @@ Yritä uudelleen. Jos ongelma ei katoa, yritä [[Special:UserLogout|kirjautua ul
 'token_suffix_mismatch' => "'''Muokkauksesi on hylätty, koska asiakasohjelmasi ei osaa käsitellä välimerkkejä muokkaustarkisteessa. Syynä voi olla viallinen välityspalvelin.'''",
 'edit_form_incomplete' => "'''Osa muokkauslomakkeesta ei saavuttanut palvelinta. Tarkista, että muokkauksesi ovat vahingoittumattomia ja yritä uudelleen.'''",
 'editing' => 'Muokataan sivua $1',
-'creating' => 'Luodaan sivu $1',
+'creating' => 'Luodaan sivua $1',
 'editingsection' => 'Muokataan osiota sivusta $1',
 'editingcomment' => 'Muokataan uutta osiota sivulla $1',
 'editconflict' => 'Päällekkäinen muokkaus: $1',
@@ -1050,6 +1050,11 @@ Se on ilmeisesti poistettu.',
 'edit-already-exists' => 'Uuden sivun luominen ei onnistunut.
 Se on jo olemassa.',
 'defaultmessagetext' => 'Viestin oletusteksti',
+'content-not-allowed-here' => '$1 ei ole sallittua sisältöä sivulla [[$2]]',
+
+# Content models
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Tällä sivulla on liian monta hitaiden laajennusfunktioiden kutsua.
@@ -2465,7 +2470,8 @@ Tiedostoversioita, joihin sinulla ei ole katseluoikeutta (''häivytetyt versiot'
 'undeletedrevisions' => '{{PLURAL:$1|Yksi versio|$1 versiota}} palautettiin',
 'undeletedrevisions-files' => '{{PLURAL:$1|Yksi versio|$1 versiota}} ja {{PLURAL:$2|yksi tiedosto|$2 tiedostoa}} palautettiin',
 'undeletedfiles' => '{{PLURAL:$1|1 tiedosto|$1 tiedostoa}} palautettiin',
-'cannotundelete' => 'Palauttaminen epäonnistui; joku muu on voinut jo palauttaa sivun.',
+'cannotundelete' => 'Palauttaminen epäonnistui:
+$1',
 'undeletedpage' => "'''$1 on palautettu.'''
 
 [[Special:Log/delete|Poistolokista]] löydät listan viimeisimmistä poistoista ja palautuksista.",
@@ -3026,6 +3032,7 @@ Tallenna tiedot koneellesi ja tuo ne tällä sivulla.',
 'pageinfo-lastuser' => 'Viimeisin muokkaaja',
 'pageinfo-edits' => 'Muokkausten kokonaismäärä',
 'pageinfo-authors' => 'Sivun eri muokkaajien kokonaismäärä',
+'pageinfo-magic-words' => '{{PLURAL:$1|Taikasana|Taikasanat}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Piilotettu luokka|Piilotetut luokat}} ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|Sisällytetty malline|Sisällytetyt mallineet}} ($1)',
 'pageinfo-toolboxlink' => 'Sivun tiedot',
@@ -3595,6 +3602,7 @@ Varmennuskoodi vanhenee $4.',
 # Scary transclusion
 'scarytranscludedisabled' => '[Wikienvälinen sisällytys ei ole käytössä]',
 'scarytranscludefailed' => '[Mallineen hakeminen epäonnistui: $1]',
+'scarytranscludefailed-httpstatus' => '[Mallineen hakeminen epäonnistui: $1 HTTP $2]',
 'scarytranscludetoolong' => '[Verkko-osoite on liian pitkä]',
 
 # Delete conflict
index 0fa9a38..2410451 100644 (file)
@@ -1135,6 +1135,15 @@ Il semble qu’elle ait été supprimée.',
 'edit-already-exists' => 'La nouvelle page n’a pas pu être créée.
 Elle existe déjà.',
 'defaultmessagetext' => 'Message par défaut',
+'content-failed-to-parse' => "Échec de l'analyse du contenu de $2 pour le modèle $1: $3",
+'invalid-content-data' => 'Données du contenu non valides',
+'content-not-allowed-here' => 'Le contenu "$1" n\'est pas autorisé sur la page [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitexte',
+'content-model-text' => 'texte brut',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Attention : cette page contient de trop nombreux appels à des fonctions coûteuses de l’analyseur syntaxique.
@@ -2589,8 +2598,8 @@ Vous avez peut-être un mauvais lien, ou la version a pu être restaurée ou sup
 'undeletedrevisions' => '$1 {{PLURAL:$1|version restaurée|versions restaurées}}',
 'undeletedrevisions-files' => '$1 version{{PLURAL:$1||s}} et $2 fichier{{PLURAL:$2||s}} restauré{{PLURAL:$2||s}}',
 'undeletedfiles' => '$1 {{PLURAL:$1|fichier restauré|fichiers restaurés}}',
-'cannotundelete' => 'La restauration a échoué ;
-un autre utilisateur a probablement déjà restauré la page.',
+'cannotundelete' => 'Échec de la restauration:
+$1',
 'undeletedpage' => "'''La page $1 a été restaurée.'''
 
 Consultez le [[Special:Log/delete|journal des suppressions]] pour obtenir la liste des récentes suppressions et restaurations.",
@@ -2645,7 +2654,7 @@ $1',
 La dernière entrée du journal des blocages est indiquée ci-dessous à titre d’information :',
 'sp-contributions-search' => 'Rechercher les contributions',
 'sp-contributions-username' => 'Adresse IP ou nom d’utilisateur :',
-'sp-contributions-toponly' => 'Ne montrer que les articles dont je suis le dernier contributeur',
+'sp-contributions-toponly' => 'Ne montrer que les contributions qui sont les dernières des articles',
 'sp-contributions-submit' => 'Rechercher',
 
 # What links here
@@ -2889,6 +2898,7 @@ impossible de renommer une page sur elle-même.',
 'immobile-target-namespace-iw' => 'Les destinations interwikis ne sont pas une cible valide pour les déplacements.',
 'immobile-source-page' => 'Cette page n’est pas renommable.',
 'immobile-target-page' => 'Il n’est pas possible de renommer la page vers ce titre.',
+'bad-target-model' => 'La destination souhaitée utilise un autre modèle de contenu. Impossible de convertir de $1 vers $2.',
 'imagenocrossnamespace' => 'Impossible de renommer un fichier vers un espace de noms autre que fichier.',
 'nonfile-cannot-move-to-file' => "Impossible de renommer quelque chose d’autre qu'un fichier vers l’espace de noms fichier.",
 'imagetypemismatch' => 'La nouvelle extension de ce fichier ne correspond pas à son type.',
@@ -4155,18 +4165,18 @@ Sinon, vous pouvez utiliser le formulaire simplifié ci-dessous. Votre commentai
 'api-error-unknown-error' => 'Erreur interne : Quelque chose a mal tourné lors du versement de votre fichier.',
 'api-error-unknown-warning' => 'Avertissement inconnu : $1',
 'api-error-unknownerror' => 'Erreur inconnue : « $1 ».',
-'api-error-uploaddisabled' => 'Le versement est désactivé sur ce wiki.',
+'api-error-uploaddisabled' => 'Le téléversement est désactivé sur ce wiki.',
 'api-error-verification-error' => 'Ce fichier peut être corrompu, ou son extension est incorrecte.',
 
 # Durations
-'duration-seconds' => '$1 {{PLURAL:$1|seconde|secondes}}',
-'duration-minutes' => '$1 {{PLURAL:$1|minute|minutes}}',
-'duration-hours' => '$1 {{PLURAL:$1|heure|heures}}',
-'duration-days' => '$1 {{PLURAL:$1|jour|jours}}',
-'duration-weeks' => '$1 {{PLURAL:$1|semaine|semaines}}',
-'duration-years' => '$1 {{PLURAL:$1|année|années}}',
-'duration-decades' => '$1 {{PLURAL:$1|décennie|décennies}}',
-'duration-centuries' => '$1 {{PLURAL:$1|siècle|siècles}}',
-'duration-millennia' => '$1 {{PLURAL:$1|millénaire|millénaires}}',
+'duration-seconds' => '$1 seconde{{PLURAL:$1||s}}',
+'duration-minutes' => '$1 minute{{PLURAL:$1||s}}',
+'duration-hours' => '$1 heure{{PLURAL:$1||s}}',
+'duration-days' => '$1 jour{{PLURAL:$1||s}}',
+'duration-weeks' => '$1 semaine{{PLURAL:$1||s}}',
+'duration-years' => '$1 année{{PLURAL:$1||s}}',
+'duration-decades' => '$1 décennie{{PLURAL:$1||s}}',
+'duration-centuries' => '$1 siècle{{PLURAL:$1||s}}',
+'duration-millennia' => '$1 millénaire{{PLURAL:$1||s}}',
 
 );
index d994775..2186e5a 100644 (file)
@@ -16,6 +16,7 @@
  * @author Lameiro
  * @author Prevert
  * @author Toliño
+ * @author Vivaelcelta
  * @author Xosé
  * @author לערי ריינהארט
  */
@@ -375,7 +376,7 @@ $messages = array(
 'faqpage' => 'Project:FAQ',
 
 # Vector skin
-'vector-action-addsection' => 'Engadir un comentario',
+'vector-action-addsection' => 'Nova sección',
 'vector-action-delete' => 'Borrar',
 'vector-action-move' => 'Mover',
 'vector-action-protect' => 'Protexer',
@@ -489,7 +490,7 @@ $1',
 'newmessagesdifflink' => 'diferenzas coa revisión anterior',
 'youhavenewmessagesfromusers' => 'Ten $1 {{PLURAL:$3|doutro usuario|de $3 usuarios}} ($2).',
 'youhavenewmessagesmanyusers' => 'Ten $1 de moitos usuarios ($2).',
-'newmessageslinkplural' => '{{PLURAL:$1|unha mensaxe nova|$1 mensaxes novas}}',
+'newmessageslinkplural' => '{{PLURAL:$1|unha mensaxe nova|mensaxes novas}}',
 'newmessagesdifflinkplural' => '{{PLURAL:$1|última modificación|últimas modificacións}}',
 'youhavenewmessagesmulti' => 'Ten mensaxes novas en $1',
 'editsection' => 'editar',
@@ -587,8 +588,8 @@ Se cadra, xa a borrou alguén.',
 'delete-hook-aborted' => 'O borrado foi abortado polo asociador.
 Este non deu ningunha explicación.',
 'badtitle' => 'Título incorrecto',
-'badtitletext' => 'O título da páxina pedida non era válido, estaba baleiro ou proviña dunha ligazón interlingua ou interwiki incorrecta.
-Pode conter un ou máis caracteres dos que non se poden empregar nos títulos.',
+'badtitletext' => 'O título da páxina pedida non era válido, estaba baleiro ou proviña dunha ligazón interlingüística ou interwiki incorrecta.
+Poida que conteña un ou máis caracteres dos que non se poden empregar nos títulos.',
 'perfcached' => 'Esta información é da memoria caché e pode ser que non estea completamente actualizada. Hai un máximo de {{PLURAL:$1|$1 resultado dispoñible|$1 resultados dispoñibles}} na caché.',
 'perfcachedts' => 'Esta información é da memoria caché. Última actualización: $2 ás $3. Hai un máximo de {{PLURAL:$4|$4 resultado dispoñible|$4 resultados dispoñibles}} na caché.',
 'querypage-no-updates' => 'Neste momento están desactivadas as actualizacións nesta páxina. O seu contido non se modificará.',
@@ -874,7 +875,7 @@ A razón que deu foi a seguinte:
 
 Pode contactar con $1 ou con calquera outro [[{{MediaWiki:Grouppage-sysop}}|administrador]] para discutir este bloqueo.
 
-Teña en conta que non pode empregar "enviarlle un correo electrónico a este usuario" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e e que o seu uso non fose bloqueado.
+Teña en conta que non pode empregar a característica "Enviar un correo electrónico a este usuario" a non ser que dispoña dun enderezo electrónico válido rexistrado nas súas [[Special:Preferences|preferencias de usuario]] e e que o seu uso non fose bloqueado.
 
 O seu enderezo IP actual é $3 e o ID do bloqueo é #$5.
 Por favor, inclúa eses datos nas consultas que faga.',
@@ -1013,6 +1014,15 @@ Semella que foi borrada.',
 'edit-already-exists' => 'Non se pode crear a nova páxina.
 Esta xa existe.',
 'defaultmessagetext' => 'Texto predeterminado',
+'content-failed-to-parse' => 'Erro ao analizar o contido de "$2" para o modelo de $1: $3',
+'invalid-content-data' => 'Datos de contido inválidos',
+'content-not-allowed-here' => 'O contido "$1" non está permitido na páxina "[[$2]]"',
+
+# Content models
+'content-model-wikitext' => 'texto wiki',
+'content-model-text' => 'texto simple',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Aviso:''' Esta páxina contén demasiados analizadores de funcións de chamadas.
@@ -2141,7 +2151,8 @@ Pode precisar máis a vista seleccionando o tipo de rexistro, o nome do usuario
 'allpagesnext' => 'Seguinte',
 'allpagessubmit' => 'Mostrar',
 'allpagesprefix' => 'Mostrar as páxinas que comezan co prefixo:',
-'allpagesbadtitle' => 'O título dado á páxina non era válido ou contiña un prefixo inter-linguas ou inter-wikis. Pode que conteña un ou máis caracteres que non se poden empregar nos títulos.',
+'allpagesbadtitle' => 'O título dado á páxina non era válido ou tiña un prefixo interlingüístico ou interwiki.
+Poida que conteña un ou máis caracteres dos que non se poden empregar nos títulos.',
 'allpages-bad-ns' => '{{SITENAME}} carece do espazo de nomes "$1".',
 'allpages-hide-redirects' => 'Agochar as redireccións',
 
@@ -2481,7 +2492,8 @@ O texto destas revisións eliminadas só está á disposición dos administrador
 'undeletedrevisions' => '$1 {{PLURAL:$1|revisión restaurada|revisións restauradas}}',
 'undeletedrevisions-files' => '$1 {{PLURAL:$1|revisión|revisións}} e $2 {{PLURAL:$2|ficheiro restaurado|ficheiros restaurados}}',
 'undeletedfiles' => '$1 {{PLURAL:$1|ficheiro restaurado|ficheiros restaurados}}',
-'cannotundelete' => 'Non se restaurou a páxina porque alguén xa o fixo antes.',
+'cannotundelete' => 'Houbo un erro durante a restauración:
+$1',
 'undeletedpage' => "'''A páxina \"\$1\" foi restaurada'''
 
 Comprobe o [[Special:Log/delete|rexistro de borrados]] para ver as entradas recentes no rexistro de páxinas eliminadas e restauradas.",
@@ -2646,7 +2658,7 @@ O motivo do bloqueo de $1 é: "$2"',
 'blocklogpage' => 'Rexistro de bloqueos',
 'blocklog-showlog' => 'Este usuario xa foi bloqueado con anterioridade. Velaquí está o rexistro de bloqueos por se quere consultalo:',
 'blocklog-showsuppresslog' => 'Este usuario xa foi bloqueado e agochado con anterioridade. Velaquí está o rexistro de supresións por se quere consultalo:',
-'blocklogentry' => 'bloqueou a [[$1]] $3 cun tempo de duración de $2',
+'blocklogentry' => 'bloqueou a [[$1]] cun tempo de duración de $2 $3',
 'reblock-logentry' => 'cambiou as configuracións do bloqueo de "[[$1]]" cunha caducidade de $2 $3',
 'blocklogtext' => 'Este é o rexistro das accións de bloqueo e desbloqueo de usuarios.
 Non se listan os enderezos IP bloqueados automaticamente.
@@ -2784,6 +2796,7 @@ Quérea borrar para deixar sitio para facer o traslado?',
 'immobile-target-namespace-iw' => 'A ligazón interwiki non é válida para o movemento da páxina.',
 'immobile-source-page' => 'Esta páxina non se pode mover.',
 'immobile-target-page' => 'Non se pode mover a ese título.',
+'bad-target-model' => 'O destino desexado utiliza un modelo de contido diferente. Non se pode facer a conversión entre $1 e $2.',
 'imagenocrossnamespace' => 'Non se pode mover o ficheiro a un espazo de nomes que non o admite',
 'nonfile-cannot-move-to-file' => 'Non se pode mover algo que non é un ficheiro ao espazo de nomes reservado aos ficheiros',
 'imagetypemismatch' => 'A nova extensión do fiheiro non coincide co seu tipo',
index 2dac933..64978ba 100644 (file)
@@ -896,6 +896,15 @@ Si isch schyns glescht wore.',
 'edit-no-change' => 'Dyyni Bearbeitig isch ignoriert wore, wel kei Änderig am Täxt gmacht woren isch.',
 'edit-already-exists' => 'Di nej Syte het nid chenne aaglait wäre, wel s si scho git.',
 'defaultmessagetext' => 'Standardtext',
+'content-failed-to-parse' => 'Parse vum Inhalt $2 fir Modell $1 fählgschlaa: $3',
+'invalid-content-data' => 'Uugiltigi Inhaltsdate',
+'content-not-allowed-here' => 'Dr Inhalt „$1“ isch uf dr Syte [[$2]] nit erlaubt',
+
+# Content models
+'content-model-wikitext' => 'Wikitext',
+'content-model-text' => 'Klartext',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Achtig: In däre Syte het s z vyyl Ufruef vu ufwändige Parserfunktione.
@@ -2314,7 +2323,9 @@ In däm Fall darf di neijscht Version nit markiert wäre oder ihre Status muess
 'undeletedrevisions' => '{{PLURAL:$1|ei Revision|$1 Revisione}} wider zruckgholt.',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 Version|$1 Versione}} un {{PLURAL:$2|1 Datei|$2 Dateie}} sin widerhärgstellt wore',
 'undeletedfiles' => '{{PLURAL:$1|1 Datei isch|$1 Dateie sin}} widerhärgstellt wore',
-'cannotundelete' => 'Widerhärstellig isch nit gange; eber ander het villicht d Syte scho widerhärgstellt.',
+'cannotundelete' => 'D Widerhärstellig isch nit gange:
+
+$1',
 'undeletedpage' => "'''„$1“''' isch widerhärgstellt wore.
 
 Im [[Special:Log/delete|Lesch-Logbuech]] findsch e Ibersicht vu dr gleschte un widerhärgstellte Syte.",
@@ -2597,6 +2608,7 @@ D Syte „[[:$1]]“ gits scho. Wottsch du si lösche, zume Platz zum verschiebe
 'immobile-target-namespace-iw' => 'E Interwiki-Link isch kei gültigs Ziil für e Syteverschiebig.',
 'immobile-source-page' => 'Die Syte cha nüt verschobe werde.',
 'immobile-target-page' => 'Uf die Ziilsyte cha nüt verschobe werde.',
+'bad-target-model' => 'Di gwinsche Ziilsyte brucht e ander Inhaltsmodell. S Inhaltsmodell $1 cha nit in s Inhaltsmodell $2 umgwandlet wäre.',
 'imagenocrossnamespace' => 'Dateie chönne nüt ussem {{ns:file}}-Namensruum use verschobe werde',
 'nonfile-cannot-move-to-file' => 'Nit-Dateie chenne nit in dr Datei-Namensruum verschobe wäre',
 'imagetypemismatch' => 'D nöii Dateierwiiterig passt nüt zu sym Typ',
index e416c8c..eea796e 100644 (file)
@@ -820,8 +820,7 @@ $2
 તમે  [[Special:Search/{{PAGENAME}}|આ શબ્દ]] ધરાવતાં અન્ય લેખો શોધી શકો છો, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} સંલગ્ન માહિતિ પત્રકોમાં શોધી શકો છો],
 અથવા  [{{fullurl:{{FULLPAGENAME}}|action=edit}} આ પાનામાં ફેરફાર કરી] માહિતિ ઉમેરવાનું શરૂ કરી શકો છો</span>.',
 'noarticletext-nopermission' => 'આ પાનામાં હાલમાં કોઇ માહિતિ નથી.
-તમે  [[Special:Search/{{PAGENAME}}|આ શબ્દ]] ધરાવતાં અન્ય લેખો શોધી શકો છો, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} સંલગ્ન માહિતિ પત્રકોમાં શોધી શકો છો],
-અથવા  [{{fullurl:{{FULLPAGENAME}}|action=edit}} આ પાનામાં ફેરફાર કરી] માહિતિ ઉમેરવાનું શરૂ કરી શકો છો</span>.',
+તમે  [[Special:Search/{{PAGENAME}}|આ શબ્દ]] ધરાવતાં અન્ય લેખો શોધી શકો છો, અથવા <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} સંલગ્ન માહિતિ પત્રકોમાં શોધી શકો છો], પરંતુ તમને આ પાનું બનાવવાની મંજૂરી નથી.',
 'userpage-userdoesnotexist' => 'સભ્ય ખાતું "<nowiki>$1</nowiki>"ની નોંધણીનથી થઈ.
 શું તમે ખરેખર આ પાનાની રચના કે ફેરફાર કરવા માંગો છો',
 'userpage-userdoesnotexist-view' => 'સભ્યના ખાતા $1 ની નોંધણી નથી થઈ',
@@ -1953,18 +1952,19 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization. જુઓ',
 'wantedfiles' => 'ઇચ્છિત ફાઈલો',
 'wantedfiletext-cat' => 'નીચેની ફાઈલ વપરાઈ છે પણ તે વિહરમન નથી. ફાઈલ અહીં હોવા તેવી ફાઈલોને પણ પરદેશી રીપોસીટરીમાંથી ફાઈલો યાદીમાં જોઈ શકાય છે. આવા પુનરાવર્તનોને  <del>struck out</del> કાઢી નાખવામાં આવશે.વધારામાં, અસ્તિત્વમાં નહોય તેવી ફાઈલધરાવતાં પાનાની યાદી [[:$1]].',
 'wantedfiletext-nocat' => 'નીચેની ફાઈલ વપરાઈ છે પણ તે અસ્તિત્વમાં નથી. ફાઈલ અહીં હોવા તેવી ફાઈલોને પણ પરદેશી રીપોસીટરીમાંથી ફાઈલો યાદીમાં જોઈ શકાય છે. આવા પુનરાવર્તનોને  <del>struck out</del> કાઢી નાખવામાં આવશે.',
-'wantedtemplates' => 'àª\9cà«\8bàª\88તા ઢાંચા',
+'wantedtemplates' => 'àª\87àª\9aà«\8dàª\9bિત ઢાંચા',
 'mostlinked' => 'સૌથી વધુ કડીઓ દ્વારા જોડાયેલ પાનું',
 'mostlinkedcategories' => 'સૌથી વધુ શ્રેણીઓ દ્વારા જોડાયેલ પાનું',
 'mostlinkedtemplates' => 'સૌથી વધુ ઢાંચાઓ  દ્વારા જોડાયેલ પાનું',
 'mostcategories' => 'સૌથી વધુ શ્રેણીઓ ધરાવતાં પાનાં',
 'mostimages' => 'સૌથી વધુ કડીઓ દ્વારા જોડાયેલી ફાઇલ',
+'mostinterwikis' => 'સૌથી વધુ આંતરવિકી કડીઓ ધરાવતાં પાના',
 'mostrevisions' => 'સૌથી વધુ ફેરફાર થયેલા પાનાં',
 'prefixindex' => 'પૂર્વાક્ષર સૂચિ',
 'prefixindex-namespace' => 'શરૂઆતમાં ($1 namespace) ધરાવતા પાનાં',
 'shortpages' => 'નાનાં પાનાં',
 'longpages' => 'લાંબા પાનાઓ',
-'deadendpages' => 'લà«\87àª\96 àª¸àª®àª¾àªªà«\8dતિ પાના',
+'deadendpages' => 'મà«\83તાàª\82ત પાના',
 'deadendpagestext' => 'નીચેના પાના {{SITENAME}}ના અન્ય પાનાને કડીઓ દ્વારા નથી જોડતાં.',
 'protectedpages' => 'સંરક્ષિત પાનાઓ',
 'protectedpages-indef' => 'ફક્ત અનિશ્ચિત સુરક્ષા ધરાવતા પાના',
@@ -2052,8 +2052,8 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization. જુઓ',
 'sp-deletedcontributions-contribs' => 'યોગદાન',
 
 # Special:LinkSearch
-'linksearch' => 'બાહ્ય કડીઓ શોધ',
-'linksearch-pat' => 'શોધ આલેખ',
+'linksearch' => 'બાહ્ય કડીઓ શોધ',
+'linksearch-pat' => 'શોધ આલેખ',
 'linksearch-ns' => 'નામાવકાશ:',
 'linksearch-ok' => 'શોધ',
 'linksearch-text' => '"*.wikipedia.org" જેવા વાઈલ્ડાકાર્ડ અહીં વાપર્યા હોઈ શકે છે.
index 92cd9a5..6a0b5cb 100644 (file)
@@ -1135,6 +1135,15 @@ $2
 'edit-already-exists' => 'לא ניתן ליצור דף חדש.
 הוא כבר קיים.',
 'defaultmessagetext' => 'טקסט ההודעה המקורי',
+'content-failed-to-parse' => 'פענוח $2 כתוכן מסוג $1 נכשל: $3',
+'invalid-content-data' => 'מידע שגוי על התוכן',
+'content-not-allowed-here' => 'תוכן מסוג "$1" אינו מותר בדף [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'טקסט ויקי',
+'content-model-text' => 'טקסט פשוט',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''אזהרה:''' דף זה כולל יותר מדי קריאות לפונקציות מפענח שגוזלות משאבים.
@@ -2594,7 +2603,8 @@ $UNWATCHURL
 'undeletedrevisions' => '{{PLURAL:$1|שוחזרה גרסה אחת|שוחזרו $1 גרסאות}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|גרסה אחת|$1 גרסאות}} ו{{PLURAL:$2|קובץ אחד|־$2 קבצים}} שוחזרו',
 'undeletedfiles' => '{{PLURAL:$1|שוחזר קובץ אחד|שוחזרו $1 קבצים}}',
-'cannotundelete' => 'השחזור נכשל; ייתכן שמישהו אחר כבר שחזר את הדף.',
+'cannotundelete' => 'השחזור נכשל:
+$1',
 'undeletedpage' => "'''הדף $1 שוחזר בהצלחה.'''
 
 ראו את [[Special:Log/delete|יומן המחיקות]] לרשימה של מחיקות ושחזורים אחרונים.",
@@ -2897,6 +2907,7 @@ $1',
 'immobile-target-namespace-iw' => 'קישור בינוויקי אינו יעד תקין להעברת דף.',
 'immobile-source-page' => 'דף זה אינו ניתן להעברה.',
 'immobile-target-page' => 'לא ניתן להעביר אל כותרת יעד זו.',
+'bad-target-model' => 'היעד המבוקש משתמש בסוג תוכן שונה. לא ניתן להמיר $1 ל{{grammar:תחילית|$2}}.',
 'imagenocrossnamespace' => 'לא ניתן להעביר קובץ למרחב שם אחר',
 'nonfile-cannot-move-to-file' => 'לא ניתן להעביר דף שאינו קובץ למרחב קובץ',
 'imagetypemismatch' => 'סיומת הקובץ החדשה אינה מתאימה לסוג הקובץ',
@@ -3768,8 +3779,8 @@ $5
 
 # Scary transclusion
 'scarytranscludedisabled' => '[הכללת דפים בין אתרים מבוטלת]',
-'scarytranscludefailed' => '[×\94×\9b×\9c×\9cת ×\94ת×\91× ×\99ת × ×\9bש×\9c×\94 עבור $1]',
-'scarytranscludefailed-httpstatus' => '[×\94×\9b×\9c×\9cת ×\94ת×\91× ×\99ת × ×\9bש×\9c×\94 עבור $1&rlm;: HTTP $2]',
+'scarytranscludefailed' => '[×\90×\97×\96×\95ר ×\94ת×\91× ×\99ת × ×\9bש×\9c עבור $1]',
+'scarytranscludefailed-httpstatus' => '[×\90×\97×\96×\95ר ×\94ת×\91× ×\99ת × ×\9bש×\9c עבור $1&rlm;: HTTP $2]',
 'scarytranscludetoolong' => '[כתובת ה־URL ארוכה מדי]',
 
 # Delete conflict
index 5e89a2f..503beba 100644 (file)
@@ -192,7 +192,7 @@ $messages = array(
 'vector-action-protect' => 'Bachao',
 'vector-action-undelete' => 'Pahile jaise karo',
 'vector-action-unprotect' => 'Surakchha ke badlo',
-'vector-simplesearch-preference' => 'Aur achchhaa se khoje salah do (Khaali vector skin)',
+'vector-simplesearch-preference' => 'Aur achchhaa se khoje ke salah do (Khaali vector skin)',
 'vector-view-create' => 'Banao',
 'vector-view-edit' => 'Badlo',
 'vector-view-history' => 'Itihaas dekho',
@@ -298,6 +298,10 @@ $1',
 'youhavenewmessages' => 'Aapke pass hai $1 ($2).',
 'newmessageslink' => 'nawaa khabar',
 'newmessagesdifflink' => 'pahile waala badlao',
+'youhavenewmessagesfromusers' => 'Aap ke lage {{PLURAL:$3|duusra sadasya|$3 sadasya}} ke lage se $1 hae ($2).',
+'youhavenewmessagesmanyusers' => 'Aap ke lage dher sadasya se $1 hae ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|ek nawaa sandes|nawaa sandes}}',
+'newmessagesdifflinkplural' => 'pichhla {{PLURAL:$1|badlao}}',
 'youhavenewmessagesmulti' => 'Aap ke khatir $1 pe sandes hai',
 'editsection' => 'badlo',
 'editold' => 'badlao',
@@ -350,11 +354,11 @@ Sahi khaas panna ke suchi [[Special:SpecialPages|{{int:specialpages}}]]pe mili.'
 'error' => 'Galti',
 'databaseerror' => 'Database me galti hai',
 'dberrortext' => 'Database ke khoj me syntax error hoe gais hae.
-Saait software me bug hoi.
+Iske matlab ii hoe sake hae ki saait software me bug hoi.
 Pahile waala database ke khoj ke kosis rahaa:
-<blockquote><tt>$1</tt></blockquote>
-"<tt>$2</tt>" function ke bhitar se.
-Database ke galti sandes rahaa "<tt>$3: $4</tt>".',
+<blockquote><code>$1</code></blockquote>
+"<code>$2</code>" function ke bhitar se.
+Database ke galti sandes rahaa "<samp>$3: $4</samp>".',
 'dberrortextcl' => 'Database ke khoj me syntax error hoe gais hae.
 Pahile waala database ke khoj ke kosis rahaa:
 "$1"
@@ -408,10 +412,11 @@ Kuch deri be baad fir se kosis karna.',
 'protectedpagetext' => 'Ii panna ke badlao ke roke ke khatir band kar dewa gais hai.',
 'viewsourcetext' => 'Aap ii panna ke source ke dekhe aur nakal utare kare sakta hai:',
 'viewyourtext' => "Aap '''aapan badlao''' ke source ke dekhe aur copy kare saktaa hae",
-'protectedinterface' => 'Ii panna software ke interface text dewe hai, aur iske barbaadi se roke ke khatir band kar dewa gais hai.',
+'protectedinterface' => 'Ii panna, ii wiki ke khatir, software ke interface text dewe hai, aur iske barbaadi se roke ke khatir band kar dewa gais hai.
+Sab wiki me anuwaad ke jorre nai to badle ke khatir, meharbaani kar ke [//translatewiki.net/ translatewiki.net], the MediaWiki localisation project ke kaam me laao.',
 'editinginterface' => "'''Chetawani:''' Aap ek panna ke badaltaa hai jon ki software ke interface text dewe hae.
-Ii panna me badlao ke asar duusra sadasya ke interface ke bhi hoi.
-Translation khatir [//translatewiki.net/wiki/Main_Page?setlang=en translatewiki.net], the MediaWiki localisation project, ke kaam me lao.",
+Ii panna me badlao ke asar duusra sadasya ke interface pe bhi hoi.
+Translation khatir [//translatewiki.net/ translatewiki.net], the MediaWiki localisation project, ke kaam me lao.",
 'sqlhidden' => '(SQL query lukawal hai)',
 'cascadeprotected' => 'Ii panna ke badlao se bachawa gais hai, kahe ki iske {{PLURAL:$1|panna, jon ki|panna, jon ki}} surakchhit hae "cascading" option turned on ke saathe me rakkhaa gais hai:
 $2',
@@ -447,6 +452,7 @@ Aapan [[Special:Preferences|{{SITENAME}} pasand]]  ke badle nai bhulna.',
 'remembermypassword' => 'Ii computer pe hamaar login yaad rakho (jaada se jaada $1 {{PLURAL:$1|din|din}} talak)',
 'securelogin-stick-https' => 'Login kare ke baad HTTPS se connected raho',
 'yourdomainname' => 'Aap ke domain:',
+'password-change-forbidden' => 'Aap ii wiki me password nai badle saktaa hae.',
 'externaldberror' => 'Koi bahaari database authentication error hai, nai to aap ke bahaari account badle ke adhikar nai hai.',
 'login' => 'Log in karo',
 'nav-login-createaccount' => 'Log in karo/ nawaa account banao',
@@ -692,20 +698,21 @@ Agar aap ek anonymous user hai aur ii sochta hai ki bekar baat aap ke baare me k
 Aap saktaa hai [[Special:Search/{{PAGENAME}}|ii panna ke title khoje]] duusra panna me,
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs],
 nai to [{{fullurl:{{FULLPAGENAME}}|action=edit}} ii panna ke badlo]</span>.',
-'noarticletext-nopermission' => 'Abhi ii panna pe koi chij likha nai hae.
+'noarticletext-nopermission' => 'Abhi ii panna me koi chij likha nai hae.
 Aap sakta hae [[Special:Search/{{PAGENAME}}|ii panna ke title ke khoje]] duusra panna me,
-nai to <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>.',
+nai to <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} search the related logs]</span>, lekin aap ke ii panna ke banae ke ijaaja tnai hae.',
+'missing-revision' => 'Panna "{{PAGENAME}}" me #$1 badlao nai hae.
+Iske kaaran ii hoe sake hae ki ek mitawa gais panna se link karaa jaawe hae.
+Iske baare me aur jaankari [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} deletion log] me paawa jaae sake hae.',
 'userpage-userdoesnotexist' => 'User account "<nowiki>$1</nowiki>" abi registered nai hai.
 Check karo ki Ii panna ke aap banae/badle mangta hai.',
 'userpage-userdoesnotexist-view' => 'User account "$1" abhi register nai karaa gais hae',
 'blocked-notice-logextract' => 'Ii sadasya ke abhi rok dewa gais hae.
 Sab se nawaa block log entry, aap ke reference ke khatir,  niche dewa gais hae:',
 'clearyourcache' => "'''Note:''' - Save kare ke baad, aap ke sait browser ke cache ke bypass kare ke parri badlao ke dekhe khatir.
-* '''Mozilla / Firefox / Safari:'''  ''Shift'' ke dabae ke ''Reload,'' pe click karo, nai to chaahe ''Ctrl-F5'' nai to ''Ctrl-R'' (''Command-R''  Mac pe)
-* '''Google Chrome:'''  ''Ctrl-Shift-R'' dabao (''Command-Shift-R'' Mac pe)
-*  '''Internet Explorer:'''  ''Ctrl'' dabae ke  ''Refresh'' pe click karo, nai to  ''Ctrl-F5'' dabao
-*  '''Konqueror: ''' ''Reload''  click karo nai to  ''F5 dabao;'' 
-* '''Opera:'''  ''Tools → Preferences''  me se cache ke safaa karo",
+* '''Firefox / Safari:''' me ''Shift'' ke dabae ke ''Reload,'' pe click karo, nai to chaahe ''Ctrl-F5'' nai to ''Ctrl-R'' (''⌘-R''  Mac pe)
+* '''Google Chrome:''' me ''Ctrl-Shift-R'' dabao (''⌘-Shift-R'' Mac pe)
+*  '''Internet Explorer:''' me ''Ctrl'' dabae ke  ''Refresh'' pe click karo, nai to  ''Ctrl-F5'' dabao",
 'usercssyoucanpreview' => "'''Salah:''' Bachae se pahile \"{{int:showpreview}}\"  button ke kaam me laae ke aapan nawaa CSS ke test karo.",
 'userjsyoucanpreview' => "'''Salah:''' Bachae se pahile  \"{{int:showpreview}}\"  button ke kaam me laae ke aapan nawaa JavaScript ke test karo.",
 'usercsspreview' => "'''Yaad rakhna ki aap khali aapan CSS ke jhalak dekhta hai.
@@ -805,6 +812,9 @@ Janae hai ki iske koi mitae dii hai.',
 'edit-already-exists' => 'Nawaa panna nai banae sakaa hai.
 Ii naam ke panna abhi hai.',
 'defaultmessagetext' => 'Default message text',
+'content-failed-to-parse' => '$1 model ke khatir $2 ke parse nai kare sakaa hae: $3',
+'invalid-content-data' => 'Panna me likha gais chij right nai hae',
+'content-not-allowed-here' => 'Panna [[$2]] me "$1" likhe ke ijaajat nai hae',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Chetauni''': Ii panna me bahut jaada expensive parser function calls hai.
@@ -826,6 +836,7 @@ Ii sab arguments ke omit kar dewa gais hai.',
 'expansion-depth-exceeded-warning' => 'Panna expansion depth ke exceed karis hae',
 'parser-unstrip-loop-warning' => 'Unstrip loop ke pawa gai shae',
 'parser-unstrip-recursion-limit' => 'Unstrip recursion limit ke exceed karaa gais hae ($1)',
+'converter-manual-rule-error' => 'Bhasa ke anuwaad kare waala niyam me galti hae',
 
 # "Undo" feature
 'undo-success' => 'Ii badlao ke pahile jaise karaa jaae sake hai.
@@ -959,8 +970,9 @@ Aap ke ispe adhikar nai hai.',
 Meharbani ka ke logs ke check karo.',
 'revdelete-only-restricted' => 'Jon chij aap $2, $1 ke lukae mangta rahaa me galti hoe gais hae: aap administrator log se koi chij lukae nai saktaa hae bina duursa dekhe waala option ke chune.',
 'revdelete-reason-dropdown' => '*Mitae ke jaada kar ke kaaran
-** Bina chhape ke adikar se
+** Bina chhape ke adikar nai
 ** Aapan baare me fajuul jankari
+** Kharaab sadasya ke naam
 ** Ninda kare waala jankari',
 'revdelete-otherreason' => 'Duusra/aur kaaran:',
 'revdelete-reasonotherlist' => 'Duusra kaaran',
@@ -1154,7 +1166,7 @@ Hian pe ek, apne se banaa sabd hae, jiske aap kaam me laae saktaa hae: $1',
 'timezoneregion-indian' => 'Indian Ocean',
 'timezoneregion-pacific' => 'Pacific Ocean',
 'allowemail' => 'Aur sadasya se e-mail enable karo',
-'prefs-searchoptions' => 'Khoje ke option',
+'prefs-searchoptions' => 'Khojo',
 'prefs-namespaces' => 'Naam:',
 'defaultns' => 'Default se ii namespaces me khojo:',
 'default' => 'baaki',
@@ -1280,6 +1292,7 @@ Iske $1 {{PLURAL:$1|character|characters}} se kamti rahe ke chaahi.',
 'right-writeapi' => 'Likhe waala API ke kaam me lawa jaawe hae',
 'right-delete' => 'Panna ke mitao',
 'right-bigdelete' => 'Barraa itihaas waala panna ke mitao',
+'right-deletelogentry' => 'Mitawa aur khola gais panna ke baare me log entires',
 'right-deleterevision' => 'Panna ke khaas badlao ke mitao nai to bachao',
 'right-deletedhistory' => 'Mitawa gais itihass ke entry ke binaa saathe waala text ke dekho',
 'right-deletedtext' => 'Mitawa gais text aur mitawa gais badlao ke biich waala badlao ke dekho',
@@ -1568,7 +1581,7 @@ Agar jo problem fir nai khatam hoe tab [[Special:ListUsers/sysop|administrator]]
 'backend-fail-internal' => 'Storage backend "$1" me ek unknown error hoe gais hae.',
 'backend-fail-contenttype' => 'Ii nai pataa lagae sakaa hae ki "$1" me bachae ke khaatir file kon rakam ke hae.',
 'backend-fail-batchsize' => 'Storage backend ke  $1 file {{PLURAL:$1|operation|operations}} ke ek batch ke dewa gais hae ; limit  $2 {{PLURAL:$2|operation|operation}} hae.',
-'backend-fail-usable' => 'File $1 ke nai likhe sakaa hae kaahe ki iske khatir jaruri ijajat nai hae, nai to directories/containers nai hae.',
+'backend-fail-usable' => 'File $1 me nai likhe, nai to nai parrhe, sakaa hae kaahe ki iske khatir jaruri ijajat nai hae, nai to directories/containers nai hae.',
 
 # File journal errors
 'filejournal-fail-dbconnect' => 'Storage backend "$1" ke khatir journal database se nai jorre sakaa hae.',
@@ -1764,8 +1777,8 @@ Templates ke delete kare se pahile duusra links ke bhi check kare ke nai bhulna.
 'disambiguations' => 'Garrbarri ke sudhare waala panna',
 'disambiguationspage' => 'Template:disambig',
 'disambiguations-text' => "Niche ke panna '''disambiguation panna''' se link hoe hai.
-They should link to the appropriate topic instead.<br />
-A page is treated as disambiguation page if it uses a template which is linked from [[MediaWiki:Disambiguationspage]]",
+Saait isse aur achchha panna se link hoi. <br />
+Ek panna ke disambiguation panna maana jaae hae jab ki ii ek template ke kaam me laae hae jon ki [[MediaWiki:Disambiguationspage]] se link hoe hae.",
 
 'doubleredirects' => 'Dugna redirects',
 'doubleredirectstext' => 'Ii panna uu panna ke suchi de hai jon ki duusra redirect panna pe redirect kare hai.
index a775eef..0c59316 100644 (file)
@@ -897,6 +897,15 @@ Zda so, zo je hîžo wušmórnjena.',
 'edit-already-exists' => 'Njebě móžno nowu stronu wutworić.
 Eksistuje hižo.',
 'defaultmessagetext' => 'Standardny tekst zdźělenki',
+'content-failed-to-parse' => 'Parsowanje wobsaha $2 za model $1 je so njeporadźiło: $3',
+'invalid-content-data' => 'Njepłaćiwe wobsahowe daty',
+'content-not-allowed-here' => 'Wobsah "$1" njeje na stronje [[$2]] dowoleny',
+
+# Content models
+'content-model-wikitext' => 'wikitekst',
+'content-model-text' => 'luty tekst',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Warnowanje: Tuta strona wobsahuje přewjele parserowych wołanjow.
@@ -2327,7 +2336,8 @@ W tutym padźe dyrbiš najnowšu wušmórnjenu wersiju znjemóžnić abo pokaza
 'undeletedrevisions' => '$1 {{PLURAL:$1|wersija|wersiji|wersije|wersijow}} {{PLURAL:$1|wobnowjena|wobnowjenej|wobnowjene|wobnowjene}}',
 'undeletedrevisions-files' => '$1 {{PLURAL:$1|wersija|wersiji|wersije|wersijow}} a $2 {{PLURAL:$2|dataja|dataji|dataje|datajow}} {{PLURAL:$2|wobnowjena|wobnowjenej|wobnowjene|wobnowjene}}',
 'undeletedfiles' => '$1 {{PLURAL:$1|dataja|dataji|dataje|datajow}} {{PLURAL:$1|wobnowjena|wobnowjenej|wobnowjene|wobnowjene}}.',
-'cannotundelete' => 'Wobnowjenje zwrěšćiło; něchtó druhi je stronu prjedy wobnowił.',
+'cannotundelete' => 'Wobnowjenje zwrěšćiło:
+$1',
 'undeletedpage' => "'''Strona $1 bu z wuspěchom wobnowjena.'''
 
 Hlej [[Special:Log/delete|protokol]] za lisćinu aktualnych wušmórnjenjow a wobnowjenjow.",
@@ -2613,6 +2623,7 @@ Cilowa strona „[[:$1]]” hižo eksistuje. Chceš ju wušmórnyć, zo by so p
 'immobile-target-namespace-iw' => 'Interwiki-wotkaz njeje płaćiwy cil za přesunjenja stronow.',
 'immobile-source-page' => 'Strona njeda so přesunyć.',
 'immobile-target-page' => 'Njemóžno do teje ciloweje strony přesunyć.',
+'bad-target-model' => 'Požadany cil wužiwa druhi wobsahowy model. $1 njeda so do $2 konwertować.',
 'imagenocrossnamespace' => 'Wobraz njeda so do druheho mjenoweho ruma hač wobraz přesunyć',
 'nonfile-cannot-move-to-file' => 'Njedataje njedadźa so do datajoweho mjenoweho ruma přesunyć',
 'imagetypemismatch' => 'Nowa dataja swojemu typej njewotpowěduje',
index 4efc521..351b23b 100644 (file)
@@ -469,7 +469,7 @@ $messages = array(
 'vector-action-protect' => 'Lapvédelem',
 'vector-action-undelete' => 'Visszaállítás',
 'vector-action-unprotect' => 'Védelem módosítása',
-'vector-simplesearch-preference' => 'Továbbfejlesztett keresési javaslatok engedélyezése (csak Vector felületen)',
+'vector-simplesearch-preference' => 'Egyszerűsített keresési sáv engedélyezése (csak Vector felületen)',
 'vector-view-create' => 'Létrehozás',
 'vector-view-edit' => 'Szerkesztés',
 'vector-view-history' => 'Laptörténet',
@@ -576,6 +576,7 @@ További információkat a [[Special:Version|verzióinformációs lapon]] talál
 'youhavenewmessages' => '$1 a vitalapodon! ($2 külön is megtekintheted.)',
 'newmessageslink' => 'új üzenet vár',
 'newmessagesdifflink' => 'az utolsó üzenetet',
+'youhavenewmessagesfromusers' => '$1 a vitalapodon {{PLURAL:$3|egy|$3}} szerkesztőtől! ($2 külön is megtekintheted.)',
 'youhavenewmessagesmanyusers' => '$1ed van több szerkesztőtől ($2).',
 'newmessageslinkplural' => '{{PLURAL:$1|Új üzenet vár|Új üzenetek várnak}}',
 'newmessagesdifflinkplural' => 'Az utolsó {{PLURAL:$1|változtatást|változtatásokat}}',
@@ -671,6 +672,8 @@ Jelezd ezt egy [[Special:ListUsers/sysop|adminiszttrátornak]] az URL megadásá
 'cannotdelete' => 'A(z) $1 lapot vagy fájlt nem lehet törölni.
 Talán már valaki más törölte.',
 'cannotdelete-title' => 'Nem lehet törölni a(z) „$1” lapot',
+'delete-hook-aborted' => 'A törlés meg lett szakítva egy hook által.
+Nem lett magyarázat csatolva.',
 'badtitle' => 'Hibás cím',
 'badtitletext' => 'A kért oldal címe érvénytelen, üres, vagy rosszul hivatkozott nyelvközi vagy wikiközi cím volt. Olyan karaktereket is tartalmazhatott, melyek a címekben nem használhatóak.',
 'perfcached' => "Az alábbi adatok gyorsítótárból (''cache''-ből) származnak, és ezért lehetséges, hogy nem a legfrissebb változatot mutatják. Legfeljebb {{PLURAL:$1|egy|$1 }} eredmény áll rendelkezésre a gyorsítótárban.",
@@ -1406,7 +1409,7 @@ Itt van egy véletlenszerűen generált érték, amit használhatsz: $1',
 'timezoneregion-indian' => 'Indiai-óceán',
 'timezoneregion-pacific' => 'Csendes-óceán',
 'allowemail' => 'E-mail engedélyezése más szerkesztőktől',
-'prefs-searchoptions' => 'A keresés beállításai',
+'prefs-searchoptions' => 'Keresés',
 'prefs-namespaces' => 'Névterek',
 'defaultns' => 'Egyébként a következő névterekben keressen:',
 'default' => 'alapértelmezett',
@@ -1531,6 +1534,7 @@ A műveletet nem lehet visszavonni.',
 'right-writeapi' => 'a szerkesztő-API használata',
 'right-delete' => 'lapok törlése',
 'right-bigdelete' => 'nagy történettel rendelkező fájlok törlése',
+'right-deletelogentry' => 'bizonyos napló bejegyzések törlése és visszaállítása',
 'right-deleterevision' => 'lapok adott változatainak törlése és helyreállítása',
 'right-deletedhistory' => 'törölt lapváltozatok megtekintése, a szövegük nélkül',
 'right-deletedtext' => 'törölt változatok szövegének és a változatok közötti eltérés megtekintése',
@@ -1614,7 +1618,7 @@ A műveletet nem lehet visszavonni.',
 # Recent changes
 'nchanges' => '{{PLURAL:$1|egy|$1}} változtatás',
 'recentchanges' => 'Friss változtatások',
-'recentchanges-legend' => 'A friss változások beállításai',
+'recentchanges-legend' => 'A friss változtatások beállításai',
 'recentchanges-summary' => 'Ezen a lapon a wikiben történt legutóbbi fejleményeket lehet nyomon követni.',
 'recentchanges-feed-description' => 'Kövesd a wiki friss változtatásait ezzel a hírcsatornával.',
 'recentchanges-label-newpage' => 'Ezzel a szerkesztéssel egy új lap jött létre',
@@ -1622,8 +1626,8 @@ A műveletet nem lehet visszavonni.',
 'recentchanges-label-bot' => 'Ezt a szerkesztést egy bot hajtotta végre',
 'recentchanges-label-unpatrolled' => 'Ezt a szerkesztést még nem ellenőrizték',
 'rcnote' => "Alább az utolsó '''{{PLURAL:$2|egy|$2}}''' nap utolsó '''{{PLURAL:$1|egy|$1}}''' változtatása látható. A lap generálásának időpontja $4, $5.",
-'rcnotefrom' => 'Alább a <b>$2</b> óta történt változások láthatóak (<b>$1</b> db).',
-'rclistfrom' => '$1 után történt változások megtekintése',
+'rcnotefrom' => 'Alább a <b>$2</b> óta történt változtatások láthatóak (<b>$1</b> db).',
+'rclistfrom' => '$1 után történt változtatások megtekintése',
 'rcshowhideminor' => 'apró szerkesztések $1',
 'rcshowhidebots' => 'botok szerkesztéseinek $1',
 'rcshowhideliu' => 'bejelentkezett felhasználók szerkesztéseinek $1',
@@ -1652,7 +1656,7 @@ A műveletet nem lehet visszavonni.',
 'recentchangeslinked-feed' => 'Kapcsolódó változtatások',
 'recentchangeslinked-toolbox' => 'Kapcsolódó változtatások',
 'recentchangeslinked-title' => 'A(z) $1 laphoz kapcsolódó változtatások',
-'recentchangeslinked-noresult' => 'A megadott időtartam alatt nem történt változás a kapcsolódó lapokon.',
+'recentchangeslinked-noresult' => 'A megadott időtartam alatt nem történt változtatás a kapcsolódó lapokon.',
 'recentchangeslinked-summary' => "Alább azon lapoknak a legutóbbi változtatásai láthatóak, amelyekre hivatkozik egy megadott lap (vagy tagjai a megadott kategóriának).
 A [[Special:Watchlist|figyelőlistádon]] szereplő lapok '''félkövérrel''' vannak jelölve.",
 'recentchangeslinked-page' => 'Lap neve:',
@@ -2055,6 +2059,7 @@ Az <del>áthúzott</del> sorok a lista elkészülése óta javítva lettek.',
 # Miscellaneous special pages
 'nbytes' => '{{PLURAL:$1|egy|$1}} bájt',
 'ncategories' => '{{PLURAL:$1|egy|$1}} kategória',
+'ninterwikis' => '{{PLURAL:$1|egy|$1}} interwiki',
 'nlinks' => '{{PLURAL:$1|egy|$1}} hivatkozás',
 'nmembers' => '{{PLURAL:$1|egy|$1}} elem',
 'nrevisions' => '{{PLURAL:$1|egy|$1}} változat',
@@ -2083,6 +2088,7 @@ Az <del>áthúzott</del> sorok a lista elkészülése óta javítva lettek.',
 'mostlinkedtemplates' => 'Legtöbbet hivatkozott sablonok',
 'mostcategories' => 'Legtöbb kategóriába tartozó lapok',
 'mostimages' => 'Legtöbbet hivatkozott fájlok',
+'mostinterwikis' => 'Legtöbb interwikit tartalmazó lapok',
 'mostrevisions' => 'Legtöbbet szerkesztett lapok',
 'prefixindex' => 'Keresés előtag szerint',
 'prefixindex-namespace' => 'Összes lap adott előtaggal ($1 névtér)',
@@ -2489,7 +2495,7 @@ változatot visszaállították vagy eltávolították az archívumból.',
 'undeletedrevisions' => '{{PLURAL:$1|egy|$1}} változat helyreállítva',
 'undeletedrevisions-files' => '{{PLURAL:$1|egy|$1}} változat és {{PLURAL:$2|egy|$2}} fájl visszaállítva',
 'undeletedfiles' => '{{PLURAL:$1|egy|$1}} fájl visszaállítva',
-'cannotundelete' => 'Nem lehet a lapot visszaállítani; lehet, hogy azt már valaki visszaállította.',
+'cannotundelete' => 'Lap visszaállítása sikertelen: $1',
 'undeletedpage' => "'''$1 helyreállítva'''
 
 Lásd a [[Special:Log/delete|törlési naplót]] a legutóbbi törlések és helyreállítások listájához.",
@@ -2872,6 +2878,7 @@ Valamennyi transwiki importálási művelet az [[Special:Log/import|importálás
 'import-interwiki-templates' => 'Az összes sablon hozzáadása',
 'import-interwiki-submit' => 'Importálás',
 'import-interwiki-namespace' => 'Célnévtér:',
+'import-interwiki-rootpage' => 'Cél gyökér lap (opcionális):',
 'import-upload-filename' => 'Fájlnév:',
 'import-comment' => 'Megjegyzés:',
 'importtext' => 'Exportáld a fájlt a forráswikiből az [[Special:Export|exportáló eszköz]] segítségével.
@@ -2904,6 +2911,8 @@ Mentsd el a számítógépedre, majd töltsd fel ide.',
 'import-error-interwiki' => '„$1” lap nem került importálásra, mert a név külső hivatkozásokra van fenntartva (interwiki).',
 'import-error-special' => '„$1” lap nem került importálásra, mert olyan speciális névtérbe tartozik, amelyen nem engedélyezettek a lapok.',
 'import-error-invalid' => '„$1” lap nem került importálásra, mert a neve nem érvényes.',
+'import-options-wrong' => 'Rossz {{PLURAL:$2|opció|opciók}}: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'A megadott gyökér oldal címe érvénytelen.',
 
 # Import log
 'importlogpage' => 'Importnapló',
@@ -3053,11 +3062,33 @@ Ez valószínűleg egy olyan link miatt van, ami egy feketelistán lévő oldalr
 
 # Info page
 'pageinfo-title' => 'Információk a(z) „$1” lapról',
+'pageinfo-header-basic' => 'Alapinformációk',
 'pageinfo-header-edits' => 'Szerkesztések története',
+'pageinfo-header-restrictions' => 'Lapvédelem',
+'pageinfo-header-properties' => 'Lap tulajdonságok',
+'pageinfo-display-title' => 'Megjelenített cím',
+'pageinfo-default-sort' => 'Alapértelmezett rendezési kulcs',
+'pageinfo-length' => 'Lap hossza (bájtokban)',
+'pageinfo-article-id' => 'Lapazonosító',
+'pageinfo-robot-policy' => 'Kereső motor státusz',
+'pageinfo-robot-index' => 'Indexelhető',
+'pageinfo-robot-noindex' => 'Nem indexelhető',
 'pageinfo-views' => 'Megtekintések száma',
 'pageinfo-watchers' => 'Figyelők száma',
+'pageinfo-redirects-name' => 'Átirányítások erre a lapra',
+'pageinfo-subpages-name' => 'Az lap allapjai',
+'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|átirányítás}}; $3 {{PLURAL:$3|nem átirányítás}})',
+'pageinfo-firstuser' => 'Lap létrehozója',
+'pageinfo-firsttime' => 'A lap létrehozás ideje',
+'pageinfo-lastuser' => 'Utolsó szerkesztő',
+'pageinfo-lasttime' => 'Az utolsó szerkesztés ideje',
 'pageinfo-edits' => 'Szerkesztések teljes száma',
 'pageinfo-authors' => 'Egyedi szerkesztők teljes száma',
+'pageinfo-recent-edits' => 'Friss változtatások száma (elmúlt $1 alatt)',
+'pageinfo-recent-authors' => 'Friss változtatások szerkesztőinek száma',
+'pageinfo-magic-words' => 'Varázs{{PLURAL:$1|szó|szavak}} ($1)',
+'pageinfo-hidden-categories' => 'Rejtett {{PLURAL:$1|kategória|kategóriák}} ($1)',
+'pageinfo-templates' => 'Felhasznált {{PLURAL:$1|sablon|sablonok}} ($1)',
 
 # Skin names
 'skinname-standard' => 'Klasszikus',
@@ -3111,6 +3142,7 @@ A futtatása során kárt tehet a számítógépedben.",
 'file-info-size-pages' => '$1 × $2 képpont, fájlméret: $3, MIME típus: $4, $5 oldal',
 'file-nohires' => 'Nem érhető el nagyobb felbontású változat.',
 'svg-long-desc' => 'SVG fájl, névlegesen $1 × $2 képpont, fájlméret: $3',
+'svg-long-desc-animated' => 'Animált SVG fájl, névlegesen $1 × $2 képpont, fájlméret: $3',
 'show-big-image' => 'A kép nagyfelbontású változata',
 'show-big-image-preview' => 'Az előnézet mérete: $1',
 'show-big-image-other' => 'További {{PLURAL:$2|felbontás|felbontások}}: $1.',
@@ -3120,6 +3152,8 @@ A futtatása során kárt tehet a számítógépedben.",
 'file-info-png-looped' => 'ismétlődik',
 'file-info-png-repeat' => 'lejátszva {{PLURAL:$1|egy|$1}} alkalommal',
 'file-info-png-frames' => '{{PLURAL:$1|egy|$1}} képkocka',
+'file-no-thumb-animation' => "'''Megjegyzés: technikai korlátok miatt a fájl bélyegképe nem lesz animált.'''",
+'file-no-thumb-animation-gif' => "'''Megjegyzés: technikai korlátok miatt a nagy felbontású GIF képekből készített bélyegkép nem lesz animált.'''",
 
 # Special:NewFiles
 'newimages' => 'Új fájlok galériája',
index 903e2f0..cccd468 100644 (file)
@@ -300,7 +300,7 @@ $messages = array(
 'vector-action-protect' => 'Proteger',
 'vector-action-undelete' => 'Restaurar',
 'vector-action-unprotect' => 'Cambiar protection',
-'vector-simplesearch-preference' => 'Activar le suggestiones de recerca meliorate (solmente in apparentia Vector)',
+'vector-simplesearch-preference' => 'Activar le barra de recerca simplificate (solmente in apparentia Vector)',
 'vector-view-create' => 'Crear',
 'vector-view-edit' => 'Modificar',
 'vector-view-history' => 'Vider historia',
@@ -941,6 +941,7 @@ Pare que illo ha essite delite.',
 'edit-already-exists' => 'Non poteva crear un nove pagina.
 Illo existe ja.',
 'defaultmessagetext' => 'Texto predefinite del message',
+'content-failed-to-parse' => 'Impossibile processar le contento $2 pro le modello $1: $3',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Attention: Iste pagina contine troppo de appellos costose al functiones del analysator syntactic.
index 7551df8..38142e0 100644 (file)
@@ -46,7 +46,7 @@ $messages = array(
 'tog-numberheadings' => 'Automatiko a pabilangan dagiti paulo',
 'tog-showtoolbar' => 'Ipakita ti ramit ti panag-urnos (masapul ti JavaScript)',
 'tog-editondblclick' => 'Urnosen dagiti panid iti mamindua a panagtakla (masapul ti JavaScript)',
-'tog-editsection' => 'Pakabaelan ti panag-urnos iti paset babaen kadagiti [urnosen] a  panilpo',
+'tog-editsection' => 'Pakabaelan ti paset a panag-urnos babaen kadagiti [urnosen] a  panilpo',
 'tog-editsectiononrightclick' => 'Pakabaelan ti paset  a panag-urnos babaen ti agtakla ti kanawan kadagiti paset a titulo (masapul ti JavaScript)',
 'tog-showtoc' => 'Ipakita ti tabla dagiti linaon (para kadagiti panid nga adda ti ad-adu ngem dagiti 3 a paulo)',
 'tog-rememberpassword' => 'Laglagipem ti iseserrekko iti daytoy a pagbasabasa (iti kapaut nga $1 {{PLURAL:$1|aldaw|al-aldaw}})',
@@ -152,7 +152,7 @@ $messages = array(
 'category-empty' => "''Daytoy a kategoria ket agdama a saan nga aglaon kadagiti panid wenno midia.''",
 'hidden-categories' => '{{PLURAL:$1|Nailemmeng a kategoria|Nailemmeng a katkategoria}}',
 'hidden-category-category' => 'Nailemmeng a katkategoria',
-'category-subcat-count' => '{{PLURAL:$2|Daytoy a kategoria ket adda laeng ti sumaganad nga apo ti kategoria.|Daytoy a kategoria ket adda kadagiti sumaganad nga {{PLURAL:$1|nga apo ti kategoria|$1 nga apo dagiti kategoria}}, manipud ti dagup nga $2.}}',
+'category-subcat-count' => '{{PLURAL:$2|Daytoy a kategoria ket adda laeng ti sumaganad nga apo ti kategoria.|Daytoy a kategoria ket adda kadagiti sumaganad  {{PLURAL:$1|nga apo ti kategoria|$1 nga apo dagiti kategoria}}, manipud ti dagup nga $2.}}',
 'category-subcat-count-limited' => 'Daytoy a kategoria ket adda ti sumaganad  {{PLURAL:$1|nga apo ti kategoria|$1 nga apo dagiti kategoria}}.',
 'category-article-count' => '{{PLURAL:$2|Daytoy a kategoria ket aglaon laeng ti sumaganad a panid.|Ti sumaganad  {{PLURAL:$1|a panid|$1 a pampanid}} ket adda iti daytoy a kategoria, manipud ti dagup nga $2.}}',
 'category-article-count-limited' => 'Ti sumaganad {{PLURAL:$1|a panid |$1 a pampanid}} ket adda iti agdama a kategoria.',
@@ -192,7 +192,7 @@ $messages = array(
 'vector-action-protect' => 'Salakniban',
 'vector-action-undelete' => 'Isubli ti inikkat',
 'vector-action-unprotect' => 'Sukatan ti salaknib',
-'vector-simplesearch-preference' => 'Pakabaelan ti napasayaat a singasing ti panagbiruk (Kudil a Vector laeng)',
+'vector-simplesearch-preference' => 'Pakabaelan ti napalaka a baras ti panagbiruk (Kudil a Vector laeng)',
 'vector-view-create' => 'Agaramid',
 'vector-view-edit' => 'Urnosen',
 'vector-view-history' => 'Kitaen ti pakasaritaan',
@@ -366,7 +366,7 @@ naggapu ti uneg ti opisio "$2".
 Ti database ket nangipatulod ti biddut "$3: $4".',
 'laggedslavemode' => 'Ballaag: Mabalin a ti panid ket saan nga aglaon kadagiti naudi a panagpabaro.',
 'readonly' => 'Nakandadoan ti database',
-'enterlockreason' => 'Agikabil ti maysa a rasaon para iti kandado, agraman ti karkulo no kaano a maluktan ti kandado',
+'enterlockreason' => 'Agikabil ti maysa a rason para iti kandado, agraman ti karkulo no kaano a malukatan ti kandado',
 'readonlytext' => 'Ti database ket agdama a naikandado kadagiti baro a panagikabil ken panagbaliw, mabalin a gapu dagiti kanayon a pagsimpa, ket no malpas kadawyanto nga agsubli.
 
 Ti administrador a nangkandado ket nangited ti daytoy a palawag: $1',
@@ -746,7 +746,7 @@ Ti naudi a listaan ti panaka-serra ket adda dita baba tapno mausar a reperensia:
 'sitejspreview' => "'''Laglagipem nga ipadpadasmo laeng ti kodigo daytoy a JavaScript.'''
 '''Saan pay nga naidulin!'''",
 'userinvalidcssjstitle' => "'''Ballaag:''' Awan ti kudil a \"\$1\".
-Annawid a .css ken .js dagiti titulo ket agususar ti napababa a letra, a kas dagiti {{ns:user}}:Foo/vector.css saan ket a {{ns:user}}:Foo/Vector.css.",
+Annawid a .css ken .js dagiti titulo ket agususar ti babassit a letra, a kas dagiti {{ns:user}}:Foo/vector.css saan ket a {{ns:user}}:Foo/Vector.css.",
 'updated' => '(Napabaro)',
 'note' => "'''Paammo:'''",
 'previewnote' => "'''Laglagipem a daytoy ket panagipadas laeng.'''
@@ -783,11 +783,11 @@ Adda sabali a mausar tapno makaurnoska kadagiti panid: Ti saan nga-ASCII a kabab
 'editingold' => "'''Ballag: Ururnosem ti daan a panag-baliw iti daytoy a panid.'''
 No idulinmo, mapukaw amin a sinukatam iti daytoy a panag-baliw.",
 'yourdiff' => 'Dagiti nagdudumaan',
-'copyrightwarning' => "Laglagipenyo koma, apo, nga amin a parawad iti {{SITENAME}} ket maibilang a mairuar iti babaen ti $2 (kitaen ti $1 para kadagiti salaysay). 
+'copyrightwarning' => "Laglagipenyo koma, apo, nga amin a maiparawad iti {{SITENAME}} ket maibilang a mairuar babaen ti $2 (kitaen ti $1 para kadagiti salaysay). 
 No dimo kayat a ti sinuratmo ket maurnos nga awanan-asi ken maiwaras nga awan sungsungbatan kenka, saanmo laengen nga ip-ipan wenno ipabpablaak ditoy.<br />
-Kasta met nga ikarim kadakami a bukodmo a sinurat wenno gapuanan daytoy, wenno tinuladmo manipud ti maysa a nawaya a pagturayan ti publiko wenno ti kapadpadana a lnawaya a nagtaudan.
+Kasta met nga ikarim kadakami a bukodmo a sinurat wenno gapuanan daytoy, wenno tinuladmo manipud ti maysa a nawaya a pagturayan ti publiko wenno ti kapadpadana a nawaya a nagtaudan.
  '''Saan a mangited ti adda karbenganna a panagipablaak nga obra no awan ti  pammalubos!'''",
-'copyrightwarning2' => "Pangngaasiyo, apo, a laglagipen nga amin a parawad iti {{SITENAME}} ket mabalin a maurnos, masuktan, wenno ikkaten dagiti sabali pay nga agar-aramat.
+'copyrightwarning2' => "Pangngaasiyo, apo, a laglagipen nga amin a maiparawad iti {{SITENAME}} ket mabalin a maurnos, masuktan, wenno ikkaten dagiti sabali pay nga agar-aramat.
 No dimo kayat a ti sinuratmo ket maurnos nga awanan-asi ken maiwaras nga awan sungsungbatan kenka, saanmo laengen nga ip-ipan wenno ipabpablaak ditoy.<br />
 Kasta met nga ikarim kadakami a bukodmo a sinurat wenno gapuanan daytoy, wenno tinuladmo manipud ti maysa a nawaya a pagturayan ti publiko wenno ti kapadpadana a nawaya a pagtaudan (kitaen ti $1 para iti salaysay).
 '''Saan a mangipan iti adda ti karbenganna a panagpablaak nga obra no awan ti  pammalubos!'''",
@@ -1058,7 +1058,7 @@ Dagiti salaysay ket mabalin a mabirukan idiay [{{fullurl:{{#Special:Log}}/delete
 'searchresults-title' => 'Dagiti nabirukan a nagbanagan para iti "$1"',
 'searchresulttext' => 'Para iti adu pay a pakaammo a maipanggep ti panagbiruk {{SITENAME}}, kitaem ti [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => 'Nagbirukka  para iti \'\'\'[[:$1]]\'\'\' ([[Special:Prefixindex/$1|amin a panid a mangrugi iti "$1"]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|amin a panid nga agsilpo iti "$1"]])',
-'searchsubtitleinvalid' => "Nagbiruk ka para  iti '''$1'''",
+'searchsubtitleinvalid' => "Nagbirukka para  iti '''$1'''",
 'toomanymatches' => 'Adu unay ti napasubli  nga agpapada, pangngaasi a padasem ti sabali a panagsapul',
 'titlematches' => 'Dagiti kapadpada a titulo ti panid',
 'notitlematches' => 'Awan dagiti kapadpada a titulo ti panid',
@@ -1195,7 +1195,7 @@ Adda ditoy ti pugto a pateg a mausarmo: $1',
 'allowemail' => 'Pakabaelam ti e-surat a naggapu kadagiti sabali nga agar-aramat',
 'prefs-searchoptions' => 'Biruken',
 'prefs-namespaces' => 'Nagan ti luglugar',
-'defaultns' => 'Wenno no saan agbirukka kadagitoy a nagan ti luglugar:',
+'defaultns' => 'Wenno saan agbirukka kadagitoy a nagan ti luglugar:',
 'default' => 'kasisigud',
 'prefs-files' => 'Dagiti papeles',
 'prefs-custom-css' => 'Naiduma a CSS',
@@ -1454,7 +1454,7 @@ Dagiti panid iti [[Special:Watchlist|listaan ti bambantayam]] ket '''napuskol'''
 # Upload
 'upload' => 'Mangipan iti papeles',
 'uploadbtn' => 'Mangipan iti papeles',
-'reuploaddesc' => 'Ukasen ti pag-ipan ken absubli idiay kabuklan ti pag-ipan',
+'reuploaddesc' => 'Ukasen ti pag-ipan ken agsubli idiay kabuklan ti pag-ipan',
 'upload-tryagain' => 'Ited ti napabaro a panagipalawag ti papeles',
 'uploadnologin' => 'Saan a nakastrek',
 'uploadnologintext' => 'Masapul a [[Special:UserLogin|nakaserrekka]] tapno makaipanka iti papeles.',
@@ -1520,7 +1520,7 @@ Pangngaasi ta kitaem no kayatmo latta nga ipapan daytoy a papeles.',
 'windows-nonascii-filename' => 'Daytoy a wiki ket saanna a tapayaen dagiti nagan ti papeles nga adda ti kangrunaan a kababalin',
 'fileexists' => 'Adda ti papeles nga agnagan ti kastoy, pangngaasi a kitaemti  <strong>[[:$1]]</strong> no saanka a sigurado a mangsukat.
 [[$1|thumb]]',
-'filepageexists' => 'Ti panangipalpalawag a panid ti daytoy a papeles ket naaramiden idiay <strong>[[:$1]]</strong>, mgem awan ti agnagan ti katoy a papeles.
+'filepageexists' => 'Ti panangipalpalawag a panid ti daytoy a papeles ket naaramiden idiay <strong>[[:$1]]</strong>, ngem awan ti agnagan ti katoy a papeles.
 Ti pakabuklan nga inkabilmo ket saan nga agparang idiay panid ti panangipalpalawag.
 Tapno ti pakabuklan ket agparang idiay, masapul  a baliwam idiay.
 [[$1|thumb]]',
@@ -1687,9 +1687,9 @@ Para iti kangatuan a talinaay, nabaldado ti img_auth.php.',
 'upload-curl-error6-text' => 'Ti URL a naited ket saan a madanon.
 Pangngaasi ta kitaem manen no husto ti URL ken adda dayta a pagsaadan.',
 'upload-curl-error28' => 'Nagsardeng ti panag-ipan',
-'upload-curl-error28-text' => 'Ti pagsaadan ket nabayag unay nga simmungbat.
-Pangngaasi ti kitaen no naipatakder ti pagsaadan, aguray no madamdama ket padasem manen.
-Baka kayatmo a padasen no saan da a makumikom.',
+'upload-curl-error28-text' => 'Ti pagsaadan ket nabayag unay a simmungbat.
+Pangngaasi a kitaen no naipatakder ti pagsaadan, aguray no madamdama ket padasem manen.
+Baka kayatmo a padasen no saan a makumikom nga oras.',
 
 'license' => 'Lisensia:',
 'license-header' => 'Lisensia',
@@ -1748,7 +1748,7 @@ Baka kayatmo nga urnosen ti bukodna a deskripsion idiay [$2 deskripsion ti papel
 'sharedupload-desc-create' => 'Daytoy a papeles ket naggapu manipud idiay  $1  ken mabalin a mausar babaen dagiti sabali a gandat.
 Baka kayatmo nga urnosen ti bukodna a deskripsionna idiay [$2 deskripsion ti papeles a panid].',
 'filepage-nofile' => 'Awan ti agnagan ti kasta a papeles.',
-'filepage-nofile-link' => 'Awan ti agnagan ti kastoy a papeles, ngem mabalin mo ti [$1 mangipan].',
+'filepage-nofile-link' => 'Awan ti agnagan ti kastoy a papeles, ngem mabalinmo ti [$1 mangipan].',
 'uploadnewversion-linktext' => 'Mangipan ti kabarbaro a bersion iti daytoy a papeles',
 'shared-repo-from' => 'Naggapo iti $1',
 'shared-repo' => 'iti pagbingbingayan a nagikabilan',
@@ -1762,7 +1762,7 @@ Baka kayatmo nga urnosen ti bukodna a deskripsionna idiay [$2 deskripsion ti pap
 'filerevert-defaultcomment' => 'Naisubli ti bersion manipud idi $2, $1',
 'filerevert-submit' => 'Isubli',
 'filerevert-success' => "Ti '''[[Media:$1|$1]]''' ket naipasubli idiay [$4 bersion ti oras ken petsa $3, $2].",
-'filerevert-badversion' => 'Awan ti dati a lokal a bersion daytoy a papelesa naited ti dayta nga oras ken petsa.',
+'filerevert-badversion' => 'Awan ti dati a lokal a bersion daytoy a papeles a naited ti dayta nga oras ken petsa.',
 
 # File deletion
 'filedelete' => 'Ikkaten ti $1',
@@ -1780,7 +1780,7 @@ Baka kayatmo nga urnosen ti bukodna a deskripsionna idiay [$2 deskripsion ti pap
 'filedelete-reason-dropdown' => '*Kadawyan a rasrason ti pannakaikkat
 ** Panagsalungasing iti karbengan ti panagkopia
 ** Nadoble a papeles',
-'filedelete-edit-reasonlist' => 'Unosen dagiti rason ti panagikkat',
+'filedelete-edit-reasonlist' => 'Urnosen dagiti rason ti panagikkat',
 'filedelete-maintenance' => 'Ti panagikkat ken panagisubli kadagiti papaeles ket nabaldado iti las-ud ti panagtartaripatu.',
 'filedelete-maintenance-title' => 'Saan a maikkat daytoy a papeles',
 
@@ -1822,14 +1822,14 @@ Laglagipem ti agkita kadagiti sabsabali a panilpo ti plantilia sakbay nga ikkate
 'statistics-pages' => 'Pampanid',
 'statistics-pages-desc' => 'Dagiti amin a panid ti wiki, a mairaman dagiti tungtungan a panid, dagiti baw-ing, ken dadduma pay',
 'statistics-files' => 'Ti naipapan a papeles',
-'statistics-edits' => 'Dagit naurnos a panid manipud idi nairugi ti {{SITENAME}}',
-'statistics-edits-average' => 'Pagtengngaan nga urnos tungal maysa a panid',
+'statistics-edits' => 'Dagiti naurnos a panid manipud idi nairugi ti {{SITENAME}}',
+'statistics-edits-average' => 'Pagtengngaan nga urnos ti tunggal maysa a panid',
 'statistics-views-total' => 'Dagiti dagup ti panagkita',
 'statistics-views-total-desc' => 'Saan a naikabil ti panagkita dagiti awan a panid ken dagiti espesial a panid',
-'statistics-views-peredit' => 'Mano a panagkita tunggal maysa nga urnos',
+'statistics-views-peredit' => 'Mano a panagkita ti tunggal maysa nga urnos',
 'statistics-users' => 'Dagiti nakarehistro nga [[Special:ListUsers|agar-aramat]]',
 'statistics-users-active' => 'Dagiti nasiglat nga agar-aramat',
-'statistics-users-active-desc' => 'Dagiti agar-aramat a nagtungpal iti aramid idi napalubos nga {{PLURAL:$1|aldaw|$1 al-aldaw}}',
+'statistics-users-active-desc' => 'Dagiti agar-aramat a nagtungpal ti aramid ti napalabas nga {{PLURAL:$1|aldaw|$1 nga al-aldaw}}',
 'statistics-mostpopular' => 'Kaaduan a nabuya a pampanid',
 
 'disambiguations' => 'Dagiti panid a nakasilpo kadagiti panangilawlawag',
@@ -1934,7 +1934,7 @@ Pangngaasi a laglagipen a dagiti sabali a sapot ti pagsaadan  ket makasilpoda ti
 'booksources-search-legend' => 'Agsapul kadagiti nagtaudan ti liblibro',
 'booksources-go' => 'Inkan',
 'booksources-text' => 'Dita baba ket listaan dagiti panilpo ti sabsali a lugar nga aglaklako ti liblibro, ken baka adda pay adu a pakaammo da kadagiti liblibro a kitkitaem:',
-'booksources-invalid-isbn' => 'Ti naited nga ISBN ket kasla saan nga umisu; kitaen dagiti biddut ti pinagtulad kadagiti naggappuanna a taudan.',
+'booksources-invalid-isbn' => 'Ti naited nga ISBN ket kasla saan nga umisu; kitaen dagiti biddut ti panagtulad kadagiti naggappuanna a taudan.',
 
 # Special:Log
 'specialloguserlabel' => 'Ti nagtungpal:',
@@ -2193,7 +2193,7 @@ ti naudi a nakaaramid ket iti laeng nagsurat daytoy a panid..',
 'alreadyrolled' => 'Saan a maipasubli ti kinaudi a panagurnos iti [[:$1]] babaen ni [[User:$2|$2]] ([[User talk:$2|tungtungan]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]);
 adda sabali a naurnos wenno nagipasubli ti panid.
 
-Ti kinaudi a panagurnos daytoy a panid ket babaen ni [[User:$3|$3]] ([[User talk:$3|tungtungan]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
+Ti kinaudi a panagurnos ti daytoy a panid ket babaen ni [[User:$3|$3]] ([[User talk:$3|tungtungan]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
 'editcomment' => "Ti panagurnos a pakabuklan idi ket: \"''\$1''\".",
 'revertpage' => 'Insubli ti panagurnos babaen ni [[Special:Contributions/$2|$2]] ([[User talk:$2|tungtungan]]), naisubli ti kinaudi a panagbaliw babaen ni [[User:$1|$1]]',
 'revertpage-nouser' => 'Naisubli ti panagurnos babaen ni (naikkat ti nagan ti agar-aramat) ti kinaudi a panagbaliw babaen ni [[User:$1|$1]]',
@@ -2431,7 +2431,7 @@ Kitaen ti [[Special:BlockList|listaan ti lapden nga IP ]] tapno marepaso dagiti
 'ipb-blocklist' => 'Kitaen dagiti adda a serra',
 'ipb-blocklist-contribs' => 'Dagiti naaramidan ni $1',
 'unblockip' => 'Lukatan ti serra ti agar-aramat',
-'unblockiptext' => 'Usaren ti kinabuklan dita baba ti pinagisubli ti pinagserrek nga agsurat ti napalubos a naserran nga IP a pagtaengan wenno nagan ti agar-aramat.',
+'unblockiptext' => 'Usaren ti kinabuklan dita baba ti pinagisubli ti pinagserrek nga agsurat ti napalabas a naserran nga IP a pagtaengan wenno nagan ti agar-aramat.',
 'ipusubmit' => 'Ikkaten daytoy a serra',
 'unblocked' => 'Naikkat ti panakaserra ni [[User:$1|$1]]',
 'unblocked-range' => '$1 naikkaten ti serra na',
@@ -2588,7 +2588,7 @@ Pangngaasim a mangpilika iti sabali a nagan.',
 'talkexists' => "'''Sibaballigi a naiyalis ti panid, nupay kasta saan a maiyalis ti panid ti tungtongan gapu ta addan panid-tungtongan iti baro a titulo.
 Pangngaasim ta i-manualmo lattan a pagtiponem ida.'''",
 'movedto' => 'naiyalis iti',
-'movetalk' => 'Iyalis ti mainaig a panid ti tungtongan',
+'movetalk' => 'Iyalis ti mainaig a panid ti tungtungan',
 'move-subpages' => 'Iyalis dagiti apo ti panid (aginggana ti $1)',
 'move-talk-subpages' => 'Iyalis dagiti apo ti panid iti tungtungan ti panid (aginggana ti $1)',
 'movepage-page-exists' => 'Ti panid ti $1 ket addan ken saan a mautomatiko a suratan manen.',
@@ -2606,7 +2606,7 @@ Pangngaasim ta i-manualmo lattan a pagtiponem ida.'''",
 'delete_and_move_text' => '== Masapul nga ikkaten ==
 Ti pangipanan ti panid ket "[[:$1]]" addan.
 Kayatmo nga ikkaten  tapno makaiyalis ka?',
-'delete_and_move_confirm' => 'Wen, ikkatenen ti panid',
+'delete_and_move_confirm' => 'Wen, ikkaten ti panid',
 'delete_and_move_reason' => 'Naikkat tapno mawayaan ti panaka-iyalis idiay "[[$1]]"',
 'selfmove' => 'Ti titulo ti taudan ken ti pangipanan ket agpadpada;
 saanmo a maiyalis ti panid ti isu met laeng a panid.',
@@ -2626,7 +2626,7 @@ Ti kinaudi a naikabil ti listaan ket adda dita baba tapno mausar a reperensia:",
 'semiprotectedpagemovewarning' => "'''Pakaammo:''' Nasalakniban daytoy a panid tapno dagiti laeng nakarehistro nga agar-aramat ti makaiyalis daytoy.
 Ti kinaudi a naikabil ti listaan ket adda iti baba tapno mausar a reperensia:",
 'move-over-sharedrepo' => '== Addaan ti papeles ==
-[[:$1]] addaan idiay pagbingayan a nagikabilan. Ti panagiyalis ti papeles iti titulo nga itoy ket paawanen na ti pagbingayan a papeles.',
+[[:$1]] addaan idiay pagbingayan a nagikabilan. Ti panagiyalis ti papeles iti titulo nga itoy ket paawanenna ti pagbingayan a papeles.',
 'file-exists-sharedrepo' => 'Ti napilim a nagan ti papeles ket naususaren idiay pagbingayan a pagikabilan.
 Pangngaasi nga agpilika ti sabali a nagan.',
 
@@ -2635,13 +2635,13 @@ Pangngaasi nga agpilika ti sabali a nagan.',
 'exporttext' => 'Maipanmo ti testo ken pakasaritaan ti inurnos iti maysa a panid wenno pampanid a nabalkut ti XML.
 Daytoy ket mabalin a maikabil iti sabali a wiki nga agususar ti MediaWiki nga usaren ti [[Special:Import|pinagala ti panid]].
 
-Ti pinagipan ti panid, ikabil ti titulo dita kahon ti testo dita baba, maysa a titulo iti maysa a linia, ken agpili ka no ti kayatmo ket ti agdama a pinagbaliw ken amin nga daan a pinagbalbaliw, nga addaan ti linia ti pakasaritaan ti pampanid, wenno ti agdama a pinagbaliw nga addaan ti pakaammo a maipapan ti kinaudi a pinagurnos.
+Ti pinagipan ti panid, ikabil ti titulo dita kahon ti testo dita baba, maysa a titulo iti maysa a linia, ken agpili ka no ti kayatmo ket ti agdama a pinagbaliw ken amin nga daan a panagbalbaliw, nga addaan ti linia ti pakasaritaan ti pampanid, wenno ti agdama a panagbaliw nga addaan ti pakaammo a maipapan ti kinaudi a panagurnos.
 
 No iti kinaudi a kaso mabalinmo nga usaren ti panilpo, a kas pagarigan [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] para iti panid "[[{{MediaWiki:Mainpage}}]]".',
 'exportall' => 'Ipan amin a pampanid',
 'exportcuronly' => 'Iraman laeng ti kinaudi a panagbaliw, saan a ti napno a pakasaritaan',
 'exportnohistory' => "----
-'''Palagip:''' Ti pagipapan dagiti punno a pakasaritaan dagiti panid iti daytoy a kinabuklan ket nabaldado gapu dagiti pinakalaing ti pinagandar a rason.",
+'''Palagip:''' Ti pagipapan dagiti punno a pakasaritaan dagiti panid iti daytoy a kinabuklan ket nabaldado gapu dagiti panakalaing ti panagandar a rason.",
 'exportlistauthors' => 'Iraman ti amin a listaan kadagiti nagaramid iti tunggal a maysa a panid',
 'export-submit' => 'Agipan',
 'export-addcattext' => 'Agnayon kadagiti panid a naggapu idiay kategoria:',
@@ -2658,10 +2658,10 @@ No iti kinaudi a kaso mabalinmo nga usaren ti panilpo, a kas pagarigan [[{{#Spec
 'allmessagesdefault' => 'Kasisigud a testo ti mensahe',
 'allmessagescurrent' => 'Agdama a testo ti mensahe',
 'allmessagestext' => 'Daytoy ti listaan dagiti mensahe ti sistema a magun-od idiay MediaWiki a nagan ti lugar.
-Pangngaasi a bisitaeen ti [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] ken [//translatewiki.net translatewiki.net] no kayatmo ti agparawad kadagiti sapasap a panagipatarus ti MediaWiki.',
+Pangngaasi a bisitaen ti [//www.mediawiki.org/wiki/Localisation Lokalisasion ti MediaWiki] ken [//translatewiki.net translatewiki.net] no kayatmo ti agparawad kadagiti sapasap a panagipatarus ti MediaWiki.',
 'allmessagesnotsupportedDB' => "Saan a mausar daytoy a panid ngamin ket ti '''\$wgUseDatabaseMessages''' ket nabaldado.",
 'allmessages-filter-legend' => 'Sagat',
-'allmessages-filter' => 'Sagaten ti naiduma a estado:',
+'allmessages-filter' => 'Sagaten babaen ti naipaduma nga estado:',
 'allmessages-filter-unmodified' => 'Saan a nabaliwan',
 'allmessages-filter-all' => 'Amin',
 'allmessages-filter-modified' => 'Napabaro',
@@ -2680,7 +2680,7 @@ Pangngaasi a bisitaeen ti [//www.mediawiki.org/wiki/Localisation MediaWiki Local
 'thumbnail_invalid_params' => 'Imbalido a parametro ti imahen',
 'thumbnail_dest_directory' => 'Saan a nakaaramid ti pangipanan a direktoria.',
 'thumbnail_image-type' => 'Daytoy a kita ti imahen ket saan a nasuportaran.',
-'thumbnail_gd-library' => 'Saan a kompleto a GD bibliotika a pinakaaramid: Awan ti opisio $1',
+'thumbnail_gd-library' => 'Saan a kompleto a GD biblioteka a panakaaramid: Awan ti opisio $1',
 'thumbnail_image-missing' => 'Daytoy a papeles ket  kasla napukaw: $1',
 
 # Special:Import
@@ -2706,7 +2706,7 @@ Amin a transwiki nga alaem ket mailista idiay [[Special:Log/import|listaan ti pi
 'importunknownsource' => 'Di amammo a kita ti taudan ti innala',
 'importcantopen' => 'Saan a maluktan ti innala a papeles',
 'importbadinterwiki' => 'Saan a nasayaat a panilpo nga interwiki',
-'importnotext' => 'Awanan linaon wenno awanan testo',
+'importnotext' => 'Awan linaon wenno awan ti testo',
 'importsuccess' => 'Nalpasen ti pinagala!',
 'importhistoryconflict' => 'Adda kasinnungat a pinagbaliw ti pakasaritaan (baka naala daytoy a panid idi)',
 'importnosources' => 'Awan ti innala a taudan ti transwiki ti naipalawag ken ti dagus a pakasaritaan ti pinag-ipan ket nabaldado.',
@@ -2722,11 +2722,11 @@ Awan ti saan nga agnayon a polder.',
 'import-nonewrevisions' => 'Amin a panagbalbaliw ket dati a naala.',
 'xml-error-string' => '$1 iti linia $2, tukol $3 (byte $4): $5',
 'import-upload' => 'Ipan ti XML data',
-'import-token-mismatch' => 'Napukaw ti gimong ti data.
-Pangngaasi ta padasem manen.',
+'import-token-mismatch' => 'Napukaw ti gimong ti datos.
+Pangngaasi a padasem manen.',
 'import-invalid-interwiki' => 'Saan a makaala dita naited a wiki.',
-'import-error-edit' => 'Ti panid ti "$1" ket saan a naala ngamin ket saan mo a mabalin nga urnosen.',
-'import-error-create' => 'Ti panid ti "$1" ket saan a naala ngamin ket saan mo a mabalin nga aramiden.',
+'import-error-edit' => 'Ti panid ti "$1" ket saan a naala ngamin ket saanmo a mabalin nga urnosen.',
+'import-error-create' => 'Ti panid ti "$1" ket saan a naala ngamin ket saanmo a mabalin nga aramiden.',
 'import-error-interwiki' => 'Ti panid ti "$1" ket saan a naala ngamin ket ti nagan ket nailasin para iti ruar a panagsilpo (interwiki).',
 'import-error-special' => 'Ti panid ti "$1" ket saan a naala ngamin ket bukod ti  espesial a nagan a lugar a saan nga agpalubos ti pampanid.',
 'import-error-invalid' => 'Ti panid ti "$1" ket saan a naala ngamin ket ti nagan ket imbalido.',
@@ -2809,9 +2809,9 @@ Mabalinmo a kitaen ti taudanna.',
 'tooltip-ca-nstab-category' => 'Kitaen ti panid ti kategoria',
 'tooltip-minoredit' => 'Markaan daytoy a kas bassit a panag-urnos',
 'tooltip-save' => 'Idulin dagiti sinukatam',
-'tooltip-preview' => 'Ipadas dagiti sinukatam, pangngaasimnga usarem daytoy sakbay nga idulinmo ti panid!',
+'tooltip-preview' => 'Ipadas dagiti sinukatam, pangngaasim nga usarem daytoy sakbay nga idulinmo ti panid!',
 'tooltip-diff' => 'Ipakita no ania dagiti sinukatan nga inaramidmo iti testo',
-'tooltip-compareselectedversions' => 'Kitaen ti naggidiatan dagiti dua a napili a bersion daytoy a panid.',
+'tooltip-compareselectedversions' => 'Kitaen ti naggidiatan dagiti dua a napili a bersion ti daytoy a panid.',
 'tooltip-watch' => 'Inayon daytoy a panid idiay listaan dagiti bambantayam',
 'tooltip-watchlistedit-normal-submit' => 'Ikkaten dagiti titulo',
 'tooltip-watchlistedit-raw-submit' => 'Pabaruen ti listaan ti bambantayan',
@@ -2876,6 +2876,7 @@ Daytoy ket mabalin a gapuanan babaen ti panilpo a naiparit ti akin ruar a pagsaa
 'pageinfo-magic-words' => 'Salamangka  {{PLURAL:$1|a balikas|a balbalikas}} ($1)',
 'pageinfo-hidden-categories' => 'Nailemmeng {{PLURAL:$1|a kategoria|a katkategoria}} ($1)',
 'pageinfo-templates' => 'Nailak-am  {{PLURAL:$1|a plantilia|a planplantilia}} ($1)',
+'pageinfo-toolboxlink' => 'Pakaammo ti panid',
 
 # Patrolling
 'markaspatrolleddiff' => 'Markaan a kas napatruliaan',
@@ -3411,11 +3412,11 @@ ta pasardengem ti pinakasingkedan ti e-surat a  pagtaengam:
 $5
 
 Daytoy a pammasingked a kodigo ket agpaso iti $4.',
-'confirmemail_body_changed' => 'Addaan, baka sika, ti naggapu ti IP a apagtaengam $1,
+'confirmemail_body_changed' => 'Addaan, baka sika, ti naggapu ti IP a pagtaengam $1,
 ket nangsukat ti e-surat a pagtaengan ti pakabilangan "$2" iti daytoy a pagtaengan idiay {{SITENAME}}
 
 Tapno mapasingkedan daytoy a pakabilangan ket kukuam ken ti 
-pinagpabalin ti e-surat a kita idiay {{SITENAME}}, lukatam daytoy a panilpo dita pabasabasam:
+panagpabalin ti e-surat a kita idiay {{SITENAME}}, lukatam daytoy a panilpo dita pabasabasam:
 
 $3
 
index 817262b..45cad9a 100644 (file)
@@ -1021,6 +1021,15 @@ Sembra che sia stata cancellata.',
 'edit-already-exists' => 'Impossibile creare una nuova pagina.
 Esiste già.',
 'defaultmessagetext' => 'Testo predefinito',
+'content-failed-to-parse' => 'Impossibile analizzare $2 per il modello $1: $3',
+'invalid-content-data' => 'Dati contenuti non validi',
+'content-not-allowed-here' => 'Contenuto in "$1" non consentito nella pagine [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitesto',
+'content-model-text' => 'testo normale',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Attenzione:''' Questa pagina contiene troppe chiamate alle parser functions.
@@ -2442,7 +2451,8 @@ Il testo contenuto nelle revisioni cancellate è disponibile solo agli amministr
 'undeletedrevisions' => '{{PLURAL:$1|Una revisione recuperata|$1 revisioni recuperate}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|Una revisione|$1 revisioni}} e $2 file recuperati',
 'undeletedfiles' => '{{PLURAL:$1|Un file recuperato|$1 file recuperati}}',
-'cannotundelete' => 'Ripristino non riuscito; è possibile che la pagina sia già stata recuperata da un altro utente.',
+'cannotundelete' => 'Ripristino non riuscito:
+$1',
 'undeletedpage' => "'''La pagina $1 è stata recuperata'''
 
 Consultare il [[Special:Log/delete|log delle cancellazioni]] per vedere le cancellazioni e i recuperi più recenti.",
@@ -2730,6 +2740,7 @@ La pagina specificata come destinazione "[[:$1]]" esiste già. Vuoi cancellarla
 'immobile-target-namespace-iw' => 'Un collegamento interwiki non è una destinazione valida per spostare la pagina.',
 'immobile-source-page' => 'Questa pagina non può essere spostata.',
 'immobile-target-page' => 'Non è possibile spostare sul titolo indicato.',
+'bad-target-model' => 'La destinazione desiderata utilizza un modello di contenuti diverso. Non è possibile convertire da $1 a $2.',
 'imagenocrossnamespace' => 'Non è possibile spostare un file fuori dal relativo namespace.',
 'nonfile-cannot-move-to-file' => 'Non è possibile spostare un file fuori dal relativo namespace.',
 'imagetypemismatch' => 'La nuova estensione del file non corrisponde al tipo dello stesso',
index 37cf5f9..15c9173 100644 (file)
@@ -749,7 +749,7 @@ URL を間違って入力したか、正しくないリンクをたどった可
 'viewyourtext' => "このページへの'''あなたの編集'''のソースの閲覧やコピーができます:",
 'protectedinterface' => 'このページにはこのウィキのソフトウェアのインターフェイスに使用されるテキストが保存されており、いたずらなどの防止のために保護されています。
 すべてのウィキに対して翻訳を追加/変更する場合は、MediaWiki の地域化プロジェクト [//translatewiki.net/ translatewiki.net] を使用してください。',
-'editinginterface' => "'''è­¦å\91\8a:''' ã\82½ã\83\95ã\83\88ã\82¦ã\82§ã\82¢ã\81®ã\82¤ã\83³ã\82¿ã\83¼ã\83\95ã\82§ã\82¤ã\82¹ã\81«ä½¿ç\94¨ã\81\95ã\82\8cã\82\8bã\81®ã\83\86ã\82­ã\82¹ã\83\88ã\81®ã\83\9aã\83¼ã\82¸ã\82\92ç·¨é\9b\86ã\81\97ã\81¦ã\81\84ã\81¾ã\81\99ã\80\82
+'editinginterface' => "'''警告:''' ソフトウェアのインターフェイスに使用されるテキストのページを編集しています。
 このページを変更すると、このウィキの他の利用者のユーザーインターフェイスの外観に影響します。
 すべてのウィキに対して翻訳を追加/変更する場合は、MediaWiki の地域化プロジェクト [//translatewiki.net/wiki/Main_Page?setlang=ja translatewiki.net] を使用してください。",
 'sqlhidden' => '(SQL クエリ非表示)',
@@ -1117,10 +1117,10 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'editingold' => "'''警告:このページの古い版を編集しています。'''
 保存すると、この版以降に追加されていた変更がすべて失われます。",
 'yourdiff' => '差分',
-'copyrightwarning' => "{{SITENAME}}への投稿は、すべて$2(詳細は$1を参照)のもとで公開したと見なされることにご注意ください。
+'copyrightwarning' => "{{SITENAME}}への投稿は、すべて$2 (詳細は$1を参照) のもとで公開したと見なされることにご注意ください。
 あなたが投稿したものを、他人がよって遠慮なく編集し、それを自由に配布するのを望まない場合は、ここには投稿しないでください。<br />
 また、投稿するのは、あなたが書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください。
-'''著作権保護されている作品を、許諾なしに投稿しないでください'''",
+'''著作権保護されている作品を、許諾なしに投稿しないでください!'''",
 'copyrightwarning2' => "{{SITENAME}}へのすべての投稿は、他の利用者が編集、変更、除去する可能性があります。
 あなたの投稿を、他人が遠慮なく編集するのを望まない場合は、ここには投稿しないでください。<br />
 また、投稿するのは、あなたが書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は$1を参照)。
@@ -1170,6 +1170,15 @@ IP アドレスは複数の利用者で共有されている場合がありま
 'edit-already-exists' => '新しいページを作成できませんでした。
 そのページは既に存在しています。',
 'defaultmessagetext' => '既定のメッセージ文',
+'content-failed-to-parse' => '$2 の本文を$1モデルとして構文解析できませんでした。',
+'invalid-content-data' => '本文データが無効です',
+'content-not-allowed-here' => 'ページ [[$2]] では、「$1」コンテンツは許可されていません',
+
+# Content models
+'content-model-wikitext' => 'ウィキテキスト',
+'content-model-text' => 'プレーンテキスト',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''警告:'''このページでの高負荷なパーサー関数の呼び出し回数が多過ぎます。
@@ -1484,7 +1493,7 @@ $1",
 'prefs-watchlist-edits-max' => '最大数:1000',
 'prefs-watchlist-token' => 'ウォッチリストのトークン:',
 'prefs-misc' => 'その他',
-'prefs-resetpass' => 'ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\81®変更',
+'prefs-resetpass' => 'ã\83\91ã\82¹ã\83¯ã\83¼ã\83\89ã\82\92変更',
 'prefs-changeemail' => 'メールアドレスを変更',
 'prefs-setemail' => 'メールアドレスを設定',
 'prefs-email' => 'メールの設定',
@@ -1648,7 +1657,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'right-suppressredirect' => '転送ページを作成せずにページを移動',
 'right-upload' => 'ファイルをアップロード',
 'right-reupload' => '既存のファイルに上書き',
-'right-reupload-own' => '自分自身がアップロードした既存のファイルに上書き',
+'right-reupload-own' => '自身がアップロードした既存のファイルに上書き',
 'right-reupload-shared' => '共有メディアリポジトリ上のファイルにローカルで上書き',
 'right-upload_by_url' => 'URL からファイルをアップロード',
 'right-purge' => '確認なしでサイトのキャッシュを破棄',
@@ -1672,7 +1681,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'right-hideuser' => '利用者名をブロックして公開記録から隠す',
 'right-ipblock-exempt' => 'IPブロック、自動ブロック、広域ブロックを回避',
 'right-proxyunbannable' => 'プロキシの自動ブロックを回避',
-'right-unblockself' => '自分自身に対するブロックを解除',
+'right-unblockself' => '自身に対するブロックを解除',
 'right-protect' => '保護レベルを変更し、保護されたページを編集',
 'right-editprotected' => '保護ページ(カスケード保護を除く)を編集',
 'right-editinterface' => 'ユーザーインターフェイスを編集',
@@ -1685,7 +1694,7 @@ $1 {{PLURAL:$1|文字}}以下である必要があります。',
 'right-import' => '他のウィキからページを取り込み',
 'right-importupload' => 'ファイルアップロードでページを取り込み',
 'right-patrol' => '他人の編集を巡回済みにする',
-'right-autopatrol' => '自分の編集を自動的に巡回済みにする',
+'right-autopatrol' => '自身の編集を自動で巡回済みにする',
 'right-patrolmarks' => '最近の更新で巡回済み印を閲覧',
 'right-unwatchedpages' => 'ウォッチされていないページ一覧を閲覧',
 'right-mergehistory' => 'ページの履歴を統合',
@@ -2619,7 +2628,7 @@ $2による直前の版へ変更されました。',
 'restriction-level' => '制限レベル:',
 'minimum-size' => '最小サイズ',
 'maximum-size' => '最大サイズ:',
-'pagesize' => '(バイト)',
+'pagesize' => '(バイト)',
 
 # Restrictions (nouns)
 'restriction-edit' => '編集',
@@ -2663,8 +2672,8 @@ $2による直前の版へ変更されました。',
 'undeletedrevisions' => '{{PLURAL:$1|$1版}}を復元しました',
 'undeletedrevisions-files' => '{{PLURAL:$1|$1版}}と{{PLURAL:$2|$2ファイル}}を復元しました',
 'undeletedfiles' => '{{PLURAL:$1|$1ファイル}}を復元しました',
-'cannotundelete' => '復元に失敗しました
-他の誰かがこのページを既に復元した可能性があります。',
+'cannotundelete' => '復元に失敗しました:
+$1',
 'undeletedpage' => "'''$1を復元しました。'''
 
 最近の削除と復元の記録については[[Special:Log/delete|削除記録]]を参照してください。",
@@ -2973,6 +2982,7 @@ $1 のブロックの理由は「''$2''」です。",
 'immobile-target-namespace-iw' => 'ウィキ間リンクは、ページの移動先には指定できません。',
 'immobile-source-page' => 'このページは移動できません。',
 'immobile-target-page' => '移動先ページ名に移動させることができません。',
+'bad-target-model' => '指定した移動先では、異なるコンテンツ モデルを使用しています。$1から$2には変換できません。',
 'imagenocrossnamespace' => 'ファイルを、ファイル名前空間以外に移動させることはできません',
 'nonfile-cannot-move-to-file' => 'ファイルではないものを、ファイル名前空間に移動させることはできません',
 'imagetypemismatch' => '新しいファイルの拡張子がファイルのタイプと一致していません',
@@ -3698,7 +3708,7 @@ Variants for Chinese language
 'exif-flash-mode-1' => '強制発光モード',
 'exif-flash-mode-2' => '強制非発光モード',
 'exif-flash-mode-3' => '自動発光モード',
-'exif-flash-function-1' => 'ストロボ機能し',
+'exif-flash-function-1' => 'ストロボ機能し',
 'exif-flash-redeye-1' => '赤目軽減有り',
 
 'exif-focalplaneresolutionunit-2' => 'インチ',
index fcf0715..6ff692e 100644 (file)
@@ -957,6 +957,12 @@ $2
 ის უკვე არსებობს.',
 'defaultmessagetext' => 'შეტყობინების სტანდარტული ტექსტი',
 
+# Content models
+'content-model-wikitext' => 'ვიკიტექსტი',
+'content-model-text' => 'უბრალო ტექსტი',
+'content-model-javascript' => 'ჯავასკრიპტი',
+'content-model-css' => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'ყურადღება. მოცემული გვერდი შეიცავს ძალიან ბევრ მძიმე ფუნქციას.
 
@@ -2402,7 +2408,8 @@ $UNWATCHURL
 'undeletedrevisions' => '$1 ვერსია აღდგენილია',
 'undeletedrevisions-files' => '$1 ვერსია და $2 ფაილი აღდგენილია',
 'undeletedfiles' => '$1 ფაილი აღდგენილია',
-'cannotundelete' => 'წაშლის გაუქმება ვერ განხორციელდა; შესაძლოა თქვენამდე სხვამ უკვე გააუქმა წაშლა.',
+'cannotundelete' => 'წაშლის გაუქმება ვერ განხორციელდა: 
+$1',
 'undeletedpage' => "'''$1 აღდგენილია'''
 
 უკანასკნელი წაშლილთა და აღდგენის სია შეგიძლიათ ნახოთ [[Special:Log/delete|წაშლილთა სიაში]].",
@@ -2971,6 +2978,7 @@ $1',
 'pageinfo-magic-words' => 'ჯადოსნური {{PLURAL:$1|სიტყვა|სიტყვა}} ($1)',
 'pageinfo-hidden-categories' => 'დამალული {{PLURAL:$1|კატეგორია|კატეგორია}} ($1)',
 'pageinfo-templates' => 'ინტეგრირებულია {{PLURAL:$1|თარგი|თარგი}} ($1)',
+'pageinfo-toolboxlink' => 'გვერდის ინფორმაცია',
 
 # Skin names
 'skinname-standard' => 'კლასიკური',
index 155134d..beb551d 100644 (file)
@@ -388,7 +388,7 @@ Ilaq ad εeggenem yiwen [[Special:ListUsers/sysop|anedbal]] war ad ttum asefkem
 'fileappenderror' => 'Ulamek an seffes « $1 » ar « $2 ».',
 'filecopyerror' => 'Ur yezmir ara ad yexdem alsaru n ufaylu "$1" ar "$2".',
 'filerenameerror' => 'Ur yezmir ara ad ibeddel isem ufaylu "$1" ar "$2".',
-'filedeleteerror' => 'Ur yezmir ara ad yemḥu afaylu "$1".',
+'filedeleteerror' => 'Ulamek an mḥu afaylu "$1".',
 'directorycreateerror' => 'Ulamek an snulfu akaram « $1 ».',
 'filenotfound' => 'Ur yezmir ara ad yaf afaylu "$1".',
 'fileexistserror' => 'Ulamek an aru afaylu « $1 » : afaylu agi yesnulfad yakan.',
@@ -945,25 +945,37 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 
 # Suppression log
 'suppressionlog' => 'Aɣmis n isfaḍen',
+'suppressionlogtext' => 'Ddaw-agi, umuɣ n tukksiwin d ikyafen yellan ɣef ugbur yeffren i inedbalen.
+Ẓeṛ [[Special:BlockList|umuɣ ikyafen]] i umuɣ n tiririyin d ikyafen yellan d imahlanen.',
 
 # History merging
 'mergehistory' => 'Zdi amezruy n isebtar',
+'mergehistory-header' => 'Asebtar agi aken yeǧǧ ad tesduklem ileqman n umezruy n usebtar unṣib γer usebtar amaynut.
+Senked d akken tamhelt agi ad eǧǧ amezruy n usebtar ad ikemmel.',
 'mergehistory-box' => 'Zdi lqem n sin isebtar',
 'mergehistory-from' => 'Azar n usebter :',
 'mergehistory-into' => 'Aserken n usebter :',
 'mergehistory-list' => 'Amezruy n ibeddilen i nezmer an zdi',
+'mergehistory-merge' => 'Ileqman id iteddun n [[:$1]] zemren ad twasduklen d [[:$2]]. Seqdec tigejdit n tqeffalt ṛadyu iwakken ad tesdukleḍ ala ileqman yettwasnulfan seg tazwara armi d azmez yettwamlan. Ẓeṛ d akken aseqdec n iseγwan n tunigin ad iwennez tigejdit agi.',
 'mergehistory-go' => 'Ẓeṛ ibeddilen i nezmer an zdi',
 'mergehistory-submit' => 'Azday n ileqman',
 'mergehistory-empty' => 'Ulac lqem i nezmer an zdi.',
+'mergehistory-success' => '$3 {{PLURAL:$3|lqem|ileqman}} n [[:$1]] {{PLURAL:$3|yezdukel|zdukelen}} deg [[:$2]].',
+'mergehistory-fail' => 'Ulamek an zdukel imezruyen. Fru tikkelt nniḍen asebter d iɣewwaren is n uzmez.',
 'mergehistory-no-source' => 'Azar n usebter $1 ulac-it.',
 'mergehistory-no-destination' => 'Aserken n usebter $1 ulac-it',
 'mergehistory-invalid-source' => 'Azar n usebter ilaq ad i sɛu azwel i ɣbelen.',
 'mergehistory-invalid-destination' => 'Aserken n usebter ilaq ad i sɛu azwel i ɣbelen.',
+'mergehistory-autocomment' => '[[:$1]] yezdukel s [[:$2]]',
+'mergehistory-comment' => '[[:$1]] yezdukel s [[:$2]] : $3',
+'mergehistory-same-destination' => 'Asebter n azar d usebter n userken ur zemren ara ad illin d yiwen',
 'mergehistory-reason' => 'Ayɣer',
 
 # Merge log
 'mergelog' => 'Aɣmis n izdayen',
+'pagemerge-logentry' => '[[$1]] yezdukel s [[$2]] (lqem alama d $3)',
 'revertmerge' => 'Fru',
+'mergelogpagetext' => 'Attan tebdart n wesdukel umezruy usebtar deg win n usebtar nniḍen amaynut.',
 
 # Diffs
 'history-title' => 'Tiẓṛi tiss sint umezruy n "$1"',
@@ -972,8 +984,14 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'difference-multipage' => '(Tameẓla gar isebtar)',
 'lineno' => 'Ajerriḍ $1:',
 'compareselectedversions' => 'Ẓer imgerraden ger tisiwal i textareḍ',
+'showhideselectedversions' => 'Ssken/Ffer ileqman i xtiṛen',
 'editundo' => 'ssefsu',
 'diff-multi' => '({{PLURAL:$1|Yiwet tasiwelt tabusarit|$1 n tisiwal tibusarin}} af {{PLURAL:$2|amseqdac|$2 imseqdacen}} {{PLURAL:$1|ur ttumlal ara|ur ttumlalent ara}})',
+'diff-multi-manyusers' => '({{PLURAL:$1|Yiwen lqem agrawan|$1 ileqman igrawanen}} af {{PLURAL:$2|aseqdac|$2 iseqdacen}} {{PLURAL:$1|yeffer|ffren}})',
+'difference-missing-revision' => '{{PLURAL:$1|Yiwet tacaggart|$1 ticaggartin}} n tameẓla agi ($1) {{PLURAL:$2|ur tella ara (ulac)|ur llant ara (ulac)}}.
+
+Acku azday n tameẓla, ɣef wayen tsennedeḍ, d-aqbur. Asebter yemḥa.
+Tzemreḍ ad affeḍ tilɣa deg [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} uɣmis n isebtar yekksen].',
 
 # Search results
 'searchresults' => 'Igmad n unadi',
@@ -981,6 +999,7 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'searchresulttext' => 'Akken ad tessneḍ amek ara tnadiḍ deg {{SITENAME}}, ẓer [[{{MediaWiki:Helppage}}|{{int:help}}]].',
 'searchsubtitle' => "Tnudaḍ « '''[[:$1]]''' » ([[Special:Prefixindex/$1|akkw isebtar i zwiren s « $1 »]]{{int:pipe-separator}}[[Special:WhatLinksHere/$1|Akkw isebtar yesɛan azday ɣer « $1 »]])",
 'searchsubtitleinvalid' => "Tnadiḍ ɣef '''$1'''",
+'toomanymatches' => 'Teceggeɛeḍ amḍan ameqqṛan n igemmaḍ, ilaq ad ceggeɛeḍ tuttra nniḍen.',
 'titlematches' => 'Ayen yecban azwel n umegrad',
 'notitlematches' => 'Ulac ayen yecban azwel n umegrad',
 'textmatches' => 'Ayen yecban azwel n usebter',
@@ -996,7 +1015,7 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'searchmenu-new' => "'''Snulfud asebter « [[:$1|$1]] » deg wiki agi !'''",
 'searchhelp-url' => 'Help:Agbur',
 'searchmenu-prefix' => '[[Special:PrefixIndex/$1|Nadi isebtar i zwaren s adat agi]]',
-'searchprofile-articles' => 'Isebtaren n ugbur',
+'searchprofile-articles' => 'Isebtar n ugbur',
 'searchprofile-project' => 'Isebtaren n tallat dɣa n usenfa',
 'searchprofile-images' => 'Agetmedia',
 'searchprofile-everything' => 'Akk',
@@ -1008,6 +1027,7 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'searchprofile-advanced-tooltip' => 'Fren ideggen n isemawen i unadi',
 'search-result-size' => '$1 ({{PLURAL:$2|1 awal|$2 awalen}})',
 'search-result-category-size' => '$1 {{PLURAL:$1|amseqdac|imseqdacen}} $2 ({{PLURAL:$2|adu-taggayt|adu-tiggayin}}, $3 {{PLURAL:$3|afaylu|ifuyla}})',
+'search-result-score' => 'Taflest : $1%',
 'search-redirect' => '(asemmimeḍ $1)',
 'search-section' => '(tigezmi $1)',
 'search-suggest' => 'D awal $1 i tnadiḍ ?',
@@ -1028,7 +1048,7 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'powersearch' => 'Anadi amahlan',
 'powersearch-legend' => 'Anadi amahlan',
 'powersearch-ns' => 'Nadi deg tallunin n isemawen',
-'powersearch-redir' => 'Beqqeḍ alsinamuden',
+'powersearch-redir' => 'Beqqeḍ isemmimḍen',
 'powersearch-field' => 'Nadi',
 'powersearch-togglelabel' => 'Ɛellem :',
 'powersearch-toggleall' => 'Akkw',
@@ -1082,9 +1102,15 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'columns' => 'Tigejda:',
 'searchresultshead' => 'Anadi',
 'resultsperpage' => 'Geddac n tiririyin i mkul asebter:',
+'stub-threshold' => 'Talast timinegt i <a href="#" class="stub">izdayen ɣer ibegzan</a> (itamḍanen) :',
 'stub-threshold-disabled' => 'Yensa',
+'recentchangesdays' => 'Amḍan n ussan an beqqeḍ deg ibeddilen ineggura.',
 'recentchangesdays-max' => 'Afellay $1 {{PLURAL:$1|ass|ussan}}',
 'recentchangescount' => 'Amḍan n ibeddilen i ubeqqeḍ s lexṣas :',
+'prefs-help-recentchangescount' => 'Wagi yesɛa deg-es ibeddilen ineggura, isebtar n umezruy d iɣmisen.',
+'prefs-help-watchlist-token' => 'Ččuṛ taɣzut agi s azal lbaḍna dɣa asuddem RSS ad yetwarew i umuɣ inek/inem n uɛassi.
+Akkw amdan yesnen tiddest agi ad yezmer ad i ɣeṛ umuɣ inek/inem n uɛassi, ihi ilaq ad xtiṛeḍ azal yegdelen.
+Ha-t-an azal agacuran i tzemreḍ ad seqdeceḍ : $1',
 'savedprefs' => 'Isemyifiyen inek yettusmektan.',
 'timezonelegend' => 'Iẓḍi n ukud :',
 'localtime' => 'Asrag adigan :',
@@ -1112,18 +1138,29 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'prefs-custom-css' => 'CSS asagen',
 'prefs-custom-js' => 'JavaScript asagen',
 'prefs-common-css-js' => 'JavaScript  d CSS azduklan i akkw lebsa :',
+'prefs-reset-intro' => 'Tzemreḍ ad seqdeceḍ asebter agi iwakken ad erreḍ iɣewwaren inek/inem ar azalen n lexṣas n usmel.
+Wagi ur yezmer ara ad yetwekkes.',
+'prefs-emailconfirm-label' => 'Aragag n tirawt :',
+'prefs-textboxsize' => 'Tiddi n usfaylu n ubeddel',
 'youremail' => 'E-mail *:',
 'username' => 'Isem n wemseqdac:',
 'uid' => 'Amseqdac ID:',
+'prefs-memberingroups' => 'Aεeggal n {{PLURAL:$1|ugraw|igrawen}} :',
+'prefs-registration' => 'Azmez n tiggezt :',
 'yourrealname' => 'Isem n ṣṣeḥ *:',
 'yourlanguage' => 'Tutlayt:',
 'yourvariant' => 'Lqem nniḍen n tutlayt n ugbur :',
+'prefs-help-variant' => 'Lqem naɣ inun inek/inem iwakken an beqqeḍ agbur n wiki agi.',
 'yournick' => 'Azmul amaynut :',
+'prefs-help-signature' => 'Iwenniten ɣef isebtar n umeslay ilaq ad illin zmelen s « <nowiki>~~~~</nowiki> », sakin ad i sɛu aselkat ɣer azmul inek/inem dɣa azmez d usrag.',
 'badsig' => 'Azmul mačči d ṣaḥiḥ; Ssenqed tags n HTML.',
+'badsiglength' => 'Azmul inek/inem, teɣwzi-s tameqqṛant aṭas.
+Ur ilaq ara ad i sɛu ugar n $1 {{PLURAL:$1|asekkil|isekkilen}}.',
 'yourgender' => 'Tawsit :',
 'gender-unknown' => 'Ulac tumlin',
 'gender-male' => 'Amalay',
 'gender-female' => 'Untay',
+'prefs-help-gender' => 'Axetṛan : yetseqdec iwakken ad yefk tawsit i inzan n ugrudem. Talɣut agi at illi tazayert.',
 'email' => 'E-mail',
 'prefs-help-realname' => '* Isem n ṣṣeḥ (am tebɣiḍ): ma textareḍ a t-tefkeḍ, ad yettuseqdac iwakken ad snen medden anwa yura tikkin inek.',
 'prefs-help-email' => '* E-mail (am tebɣiḍ): Teǧǧi imseqdacen wiyaḍ a k-aznen email mebla ma ẓren tansa email inek.',
@@ -1144,6 +1181,10 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'prefs-displaywatchlist' => 'Tixtiṛiyin n ubeqqeḍ',
 'prefs-diffs' => 'Timeẓliwin',
 
+# User preference: e-mail validation using jQuery
+'email-address-validity-valid' => 'E-mail agi teɣbel',
+'email-address-validity-invalid' => 'Telaq tansa e-mail i ɣbelen !',
+
 # User rights
 'userrights' => 'Laɛej iserfan n wemseqdac',
 'userrights-lookup-user' => 'Laɛej iderman n yimseqdacen',
@@ -1153,7 +1194,16 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'userrights-editusergroup' => 'Beddel iderman n wemseqdac',
 'saveusergroups' => 'Smekti iderman n yimseqdacen',
 'userrights-groupsmember' => 'Amaslad deg:',
+'userrights-groupsmember-auto' => 'Aεeggal udrig n :',
+'userrights-groups-help' => 'Tzemreḍ ad beddeleḍ igrawen anda yella aseqdac agi :
+* Taxxamt i tekkin : aseqdac yella deg ugraw agi.
+* Taxxamt ur tekkin ara : aseqdac ur yella ara deg ugraw agi
+* Titrit (*) : ur tzemreḍ ara ad ekkeseḍ agraw agi sakin i tid ernuḍ, naɣ bis-bersa.',
 'userrights-reason' => 'Ayɣer',
+'userrights-no-interwiki' => 'Ur tesɛiḍ ara turagt iwakken ad beddeleḍ izerfan n iseqdacen ɣef wiki nniḍen.',
+'userrights-nodatabase' => 'Taffa n isefka « $1 » ulac itt naɣ mačči d tadigant.',
+'userrights-nologin' => 'Ilaq ad [[Special:UserLogin|qqeneḍ]] s yiwen umiḍan anedbal iwakken ad beddeleḍ izerfan n useqdac.',
+'userrights-notallowed' => 'Amiḍan inek/inem ur yesɛa ara turagt iwakken ad beddeleḍ izerfan n useqdac.',
 'userrights-changeable-col' => 'Igrawen i tzemreḍ ad beddeleḍ',
 'userrights-unchangeable-col' => 'Igrawen ur tzemreḍ ara ad beddeleḍ',
 
@@ -1192,9 +1242,43 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'right-move-subpages' => 'Beddel isem n isebtar d adu-isebtar nsen',
 'right-move-rootuserpages' => 'Beddel isem n usebtar amenzawi n useqdac',
 'right-movefile' => 'Beddel isem n ifuyla',
+'right-suppressredirect' => 'Ur snulfu ara asemmimeḍ seg azwel amezwaru s ubeddel n isem usebter',
 'right-upload' => 'Azen ifuyla',
 'right-reupload' => 'Sefxes afaylu yellan',
 'right-reupload-own' => 'Sefxes afaylu id n-azen.',
+'right-reupload-shared' => 'Ɛefes deg udigan afaylu yellan ɣef azadur azduklan',
+'right-upload_by_url' => 'Kter afaylu seg tansa URL',
+'right-purge' => 'Senger tazarkatut n isebtar war asuter n uragag',
+'right-autoconfirmed' => 'Beddel isebtar azinsegdelen',
+'right-nominornewtalk' => 'Ur ndeḥ ara tazmilt n inzan imaynuten ma neseqdac abeddel amectuḥ ɣef usebtar n umeslay n yiwen useqdac',
+'right-apihighlimits' => 'Seqdec tilisa tid ɛlayen deg tuttriwin API',
+'right-writeapi' => 'Seqdec API n ubeddel',
+'right-delete' => 'Mḥu isebtar',
+'right-bigdelete' => 'Mḥu isebtar yesɛan amezruy affuyan',
+'right-deletelogentry' => 'Ekkes ḍɣa erred yiwen asekcem n uɣmis',
+'right-deleterevision' => 'Ekkes dɣa erred yiwen lqem n usebter',
+'right-deletedhistory' => 'Ẓeṛ isekcam n imezruyen yekksen, maca war aḍris nsen',
+'right-deletedtext' => 'Ẓeṛ aḍris yemḥan d timeẓliwin gar ileqman yemḥan',
+'right-browsearchive' => 'Nadi ɣef isebtar yettumḥan',
+'right-undelete' => 'Erred asebter yemḥan',
+'right-suppressionlog' => 'Ẓeṛ iɣmisen usligen',
+'right-block' => 'Kyef deg tira iseqdacen nniḍen',
+'right-blockemail' => 'Sḍiqqef aceggaɛ n tira (e-mail) i yiwen useqdac',
+'right-hideuser' => 'Kyef aseqdac s tuffra n isem-is ar udem n uzayez',
+'right-protect' => 'Beddel aswir n umesten n isebtar dɣa beddel isebtar i gdelen',
+'right-editprotected' => 'Beddel isebtar i gdelen (war asegdel s uceṛcuṛ)',
+'right-editinterface' => 'Beddel agrudem n useqdac',
+'right-editusercssjs' => 'Beddel ifuyla CSS d JavaScript n iseqdacen nniḍen',
+'right-editusercss' => 'Beddel ifuyla CSS n iseqdacen nniḍen',
+'right-edituserjs' => 'Beddel ifuyla JavaScript n iseqdacen nniḍen',
+'right-import' => 'Kter ifuyla seg iWikiyen nniḍen',
+'right-importupload' => 'Azen isebtar seg ufaylu',
+'right-unwatchedpages' => 'Ẓeṛ umuɣ n isebtar ur sɛan ara iɛssasen',
+'right-mergehistory' => 'Sdukel amezruy n isebtar',
+'right-userrights' => 'Beddel akkw izerfan n yiwen aseqdac',
+'right-userrights-interwiki' => 'Beddel izerfan n iseqdacen yellan deg awiki nniḍen',
+'right-siteadmin' => 'Sekkweṛ naɣ kkes aseḍru i taffa n isefka',
+'right-sendemail' => 'Ceggaɛ tirawt i iseqdacen nniḍen',
 
 # User rights log
 'rightslog' => 'Aɣmis n yizerfan n wemseqdac',
@@ -1231,6 +1315,8 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'action-mergehistory' => 'Sdukel amezruy n usebtar agi',
 'action-userrights' => 'Ẓreg izerfan n imseqdacen yark',
 'action-userrights-interwiki' => 'Ẓreg izerfan n umseqdac deg wikis wiyaḍ',
+'action-siteadmin' => 'sekkweṛ naɣ kkes aseḍru i taffa n isefka',
+'action-sendemail' => 'Ceggaɛ tira',
 
 # Recent changes
 'nchanges' => '$1 {{PLURAL:$1|Abeddel|Ibeddlen}}',
@@ -1262,8 +1348,11 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'number_of_watching_users_pageview' => '[$1 {{PLURAL:$1|aɛessas|iɛessasen}}]',
 'rc_categories' => 'Ḥedded i taggayin (ferreq s "|")',
 'rc_categories_any' => 'Ulayɣer',
+'rc-change-size-new' => '$1 {{PLURAL:$1|atamḍan|itamḍanen}} sakin abeddel',
+'newsectionsummary' => '/* $1 */ tigezmi tamaynut',
 'rc-enhanced-expand' => 'Ẓeṛ tilɣa (yeḥwaǧ JavaScript)',
 'rc-enhanced-hide' => 'Ffer tilɣa',
+'rc-old-title' => 'yesnulfad s uzwel « $1 »',
 
 # Recent changes linked
 'recentchangeslinked' => 'Ibeddlen imaynuten n isebtar myezdin',
@@ -1279,9 +1368,11 @@ Ur tesɛiḍ ara izerfan n wadduf.',
 'upload' => 'Azen afaylu',
 'uploadbtn' => 'Azen afaylu',
 'reuploaddesc' => 'Semmewet dɣa uɣaled ar tiferkit n tuznin.',
+'upload-tryagain' => 'Ceggaɛ aglam n ufaylu ibeddelen',
 'uploadnologin' => 'Ur tekcimeḍ ara',
 'uploadnologintext' => 'Yessefk [[Special:UserLogin|ad tkecmeḍ]]
 iwakken ad tazneḍ afaylu.',
+'upload_directory_missing' => 'Akaram n taktert n ufaylu ($1) ulac-it dɣa ur d-yesnulfa ara sɣur aqeddac web.',
 'upload_directory_read_only' => 'Weserver/serveur Web ur yezmir ara ad yaru deg ($1).',
 'uploaderror' => 'Agul deg usekcam',
 'uploadtext' => "Sseqdec tiferkit agi iwakken ad ktereḍ ifuyla ɣef uqeddac.
@@ -1311,7 +1402,9 @@ Akken ad tessekcmeḍ afaylu deg usebter, seqdec azay am wagi
 'illegalfilename' => 'Isem n ufaylu "$1" yesɛa isekkilen ur tettalaseḍ ara a ten-tesseqdceḍ deg yizwal n isebtar. G leɛnayek beddel isem n ufaylu u azen-it tikkelt nniḍen.',
 'filename-toolong' => 'Isem ufaylu ilaq ad yesεu m-ay aṭas 240 iṭamḍanen (bytes).',
 'badfilename' => 'Isem ufaylu yettubeddel ar "$1".',
+'filetype-mime-mismatch' => 'Asiɣzef n ufaylu « .$1 » ur yesɛa ara tuqqna s tawsit MIME id n-ufa deg ufaylu ($2).',
 'filetype-badmime' => 'Ur tettalaseḍ ara ad tazneḍ ufayluwen n anaw n MIME "$1".',
+'filetype-bad-ie-mime' => 'Afaylu ur yezmer ara ad yetwekter acku yetwaf am « $1 » sɣur Internet Explorer. Tawsit agi d tazanbagt acku d tamihawt.',
 'filetype-missing' => 'Afaylu ur yesɛi ara taseggiwit (am ".jpg").',
 'empty-file' => 'Afaylu id cegɛeḍ d-ilem.',
 'file-too-large' => 'Afaylu id cegɛed d-ameqqṛan aṭas.',
@@ -1348,18 +1441,36 @@ Ma tebɣiḍ ad azeneḍ afaylu inek/inem, ilaq ad uɣaleḍ ar deffir dɣa ad a
 [[File:$1|thumb|center|$1]]',
 'file-exists-duplicate' => 'Afaylu agi d-asleg n {{PLURAL:$1|ufaylu agi|ifuyla agi}} :',
 'uploadwarning' => 'Aɣtal deg wazan n ufayluwen',
+'uploadwarning-text' => 'Beddel aglam n ufaylu dɣa ɛreḍ tikkelt nniḍen',
 'savefile' => 'Smekti afaylu',
 'uploadedimage' => '"[[$1]]" yettwazen',
+'overwroteimage' => 'yekter lqem amaynut n « [[$1]] »',
 'uploaddisabled' => 'Suref-aɣ, azen n ufayluwen yettwakkes',
+'copyuploaddisabled' => 'Taktert n ufaylu s URL yensan.',
+'uploadfromurl-queued' => 'Afaylu inek/inem yekcem deg udras n ugani.',
 'uploaddisabledtext' => 'Azen n ifuyla yettwakkes deg wiki agi.',
+'php-uploaddisabledtext' => 'Taktert n ifuyla tensa deg PHP. Selken taxtiṛit n tawila  file_uploads.',
 'uploadscripted' => 'Afaylu-yagi yesɛa angal n HTML/script i yexdem agula deg browser/explorateur.',
 'uploadvirus' => 'Afaylu-nni yesɛa anfafad asenselkim (virus)! Ẓer kter: $1',
+'uploadjava' => 'Wagi d afaylu ZIP yesɛan afaylu Java .class.
+Azdam n ifuyla Java ur yesɛa ara turagt, acku zemren ad zizdewen ikyafen n taɣellist.',
+'upload-source' => 'Afaylu aɣbalu',
 'sourcefilename' => 'Isem n ufaylu aɣbalu :',
 'sourceurl' => 'URL aγbalu',
 'destfilename' => 'Isem n ufaylu deg aserken',
+'upload-maxfilesize' => 'Tiddi tafellayt n ufaylu : $1',
+'upload-description' => 'Aglam n ufaylu',
+'upload-options' => 'Tixtiṛiyin n taktert ifuyla',
 'watchthisupload' => 'Ɛass asebter agi',
 'filewasdeleted' => 'Afaylu s yisem-agi yettwazen umbeɛd yettumḥa. Ssenqed $1 qbel ad tazniḍ tikelt nniḍen.',
 'upload-success-subj' => 'Azen yekfa',
+'upload-success-msg' => 'Taktert inek/inem seg [$2] yesmures. Af-it d-agi : [[:{{ns:file}}:$1]]',
+'upload-failure-subj' => 'Ugur n taktert',
+'upload-failure-msg' => 'Yella ugur s taktert inek/inem seg [$2] :
+
+$1',
+'upload-warning-subj' => 'Alɣu deg taktert',
+'upload-warning-msg' => 'Yella ugur s taktert seg [$2]. Tzemreḍ ad uɣaleḍ ar [[Special:Upload/stash/$1|tiferkit n taktert]] iwakken ad fruḍ ugur agi.',
 
 'upload-proto-error' => 'Agul deg protokol',
 'upload-proto-error-text' => 'Assekcam yenṭerr URL i yebdan s <code>http://</code> neɣ <code>ftp://</code>.',
@@ -1369,6 +1480,85 @@ Ma tebɣiḍ ad azeneḍ afaylu inek/inem, ilaq ad uɣaleḍ ar deffir dɣa ad a
 'upload-misc-error-text' => 'Anezri warisem yegweḍeḍ asmi yettwazen afaylu.
 Ilaq ad selkeneḍ ma URL nni teɣbel, dɣa ɛreḍ tikkelt nniḍen.
 Ma yella daɣen anezri, ilaq ad meslaye ḍ s  [[Special:ListUsers/sysop|unedbal]].',
+'upload-too-many-redirects' => 'URL agi yesɛa aṭas illusen n wesnili.',
+'upload-unknown-size' => 'Tiddi warisem',
+'upload-http-error' => 'Anezri HTTP : $1',
+'upload-copy-upload-invalid-domain' => 'Anɣel n izdamen ur yezmer ara seg taɣult agi.',
+
+# File backend
+'backend-fail-stream' => 'Ulamek an ɣeṛ afaylu $1.',
+'backend-fail-backup' => 'Ulamek an ḥrez afaylu $1.',
+'backend-fail-notexists' => 'Afaylu $1 ulac it.',
+'backend-fail-hashes' => 'Ulamek an sɛu idwayen n ufaylu i usnemhel.',
+'backend-fail-notsame' => 'Afaylu imeẓli yella yakan i $1.',
+'backend-fail-invalidpath' => '$1 mačči d abrid n uḥraz iɣbelen.',
+'backend-fail-delete' => 'Ulamek an mḥu afaylu "$1".',
+'backend-fail-alreadyexists' => 'Afaylu $1 yella yakan.',
+'backend-fail-store' => 'Ulamek an ḥrez afaylu $1 deg $2.',
+'backend-fail-copy' => 'Ulamek an nɣel afaylu $1 deg $2.',
+'backend-fail-move' => 'Ulamek an sekḥer afaylu $1 deg $2.',
+'backend-fail-opentemp' => 'Ulamek an ldi afaylu akudan.',
+'backend-fail-writetemp' => 'Ulamek an aru deg ufaylu akudan.',
+'backend-fail-closetemp' => 'Ulamek an mdel afaylu akudan.',
+'backend-fail-read' => 'Ulamek an ɣeṛ afaylu "$1".',
+'backend-fail-create' => 'Ulamek an aru afaylu "$1".',
+'backend-fail-maxsize' => 'Ulamek an aru afaylu "$1" acku yugar {{PLURAL:$2|yiwen atamḍan|$2 itamḍanen}}.',
+'backend-fail-readonly' => 'Tannalt n uḥraz "$1" yella deg taɣuri kan. Taɣzint id yefka : "$2"',
+'backend-fail-synced' => 'Afaylu "$1" yesɛa addad azanbag deg tannalin n uḥraz tigensanin',
+'backend-fail-connect' => 'Ulamek an qqen ar tannalt n uḥraz "$1".',
+'backend-fail-internal' => 'Yella anezri warisem deg tannalt n uraz "$1".',
+'backend-fail-contenttype' => 'Ulamek ad n efk tawsit n ugbur n ufaylu an ḥrez deg "$1".',
+'backend-fail-batchsize' => 'Tannalt n uḥraz yefkad akemmus n $1 {{PLURAL:$1|tamhelt|timehlin}} n ufaylu ; talast tella ar $2 {{PLURAL:$2|tamhelt|timehlin}}.',
+'backend-fail-usable' => 'Ulamek an ɣeṛ naɣ an aru afaylu « $1 » acku drus izerfan naɣ ikaramen xusen.',
+
+# File journal errors
+'filejournal-fail-dbconnect' => 'Ulamek an qqen ar taffa n isefka n uɣmis i ixf n uḥraz "$1".',
+'filejournal-fail-dbquery' => 'Ulamek an mucceḍ taffa n isefka n uɣmis i ixf n uḥraz "$1".',
+
+# Lock manager
+'lockmanager-notlocked' => 'Ulamek an kkes aseḍru « $1 » ; ur yesɛa ara asekkweṛ.',
+'lockmanager-fail-closelock' => 'Ulamek an mdel afaylu n uzekṛun i « $1 ».',
+'lockmanager-fail-deletelock' => 'Ulamek an mḥu afaylu n uzekṛun i « $1 ».',
+'lockmanager-fail-acquirelock' => 'Ulamek an krez azekṛun i « $1 ».',
+'lockmanager-fail-openlock' => 'Ulamek an ldi afaylu n uzekṛun i « $1 ».',
+'lockmanager-fail-releaselock' => 'Ulamek an bru azekṛun i « $1 ».',
+'lockmanager-fail-db-bucket' => 'Ulamek an siwel ddeqs taffa n isefka n usekkweṛ deg uqbuc $1.',
+'lockmanager-fail-db-release' => 'Ulamek an bru izekṛunen ɣef taffa n isefka $1.',
+'lockmanager-fail-svr-acquire' => 'Ulamek an krez izekṛunen ɣef uqeddac $1.',
+'lockmanager-fail-svr-release' => 'Ulamek an bru izekṛunen ɣef uqeddac $1.',
+
+# ZipDirectoryReader
+'zip-wrong-format' => 'Afaylu agi mačči d afaylu n weɣbaṛ ZIP.',
+
+# Special:UploadStash
+'uploadstash' => 'Tazarkatut n taktert',
+'uploadstash-clear' => 'Sfeḍ ifuyla deg tazarkatut',
+'uploadstash-nofiles' => 'Ur tesɛiḍ ara ifuyla deg tazarkatut n taktert',
+'uploadstash-errclear' => 'Asfeḍ n ifuyla yefkad taruẓi',
+'uploadstash-refresh' => 'Mucceḍ umuɣ n ifuyla',
+'invalid-chunk-offset' => 'Tiggit n iɣil ur teɣbel ara',
+
+# img_auth script messages
+'img-auth-accessdenied' => 'Addaf yugwi',
+'img-auth-notindir' => 'Abrid yesuteren mačči d akaram n taktert yellan deg tawila.',
+'img-auth-badtitle' => 'Ulamek an ssali azwel i ɣbelen seg « $1 ».',
+'img-auth-nologinnWL' => 'Ur teqqneḍ ara dɣa « $1 » ur yella ara deg umuɣ amellal.',
+'img-auth-nofile' => 'Afaylu « $1 » ulac it.',
+'img-auth-isdir' => 'Tɛerdeḍ ad ldiḍ akaram « $1 ».
+Tzemreḍ kan ad ldiḍ ifuyla.',
+'img-auth-streaming' => 'Taɣuri tamaɣlalt n « $1 ».',
+'img-auth-noread' => 'Aseqdac ur yesɛa ara azref deg taɣuri ɣef « $1 ».',
+'img-auth-bad-query-string' => 'URL tesɛa azrar n tuttra ur i ɣbelen ara.',
+
+# HTTP errors
+'http-invalid-url' => 'URL ur teɣbel ara : $1',
+'http-invalid-scheme' => 'URL s uzenziɣ « $1 » ur ɣbelen ara d-agi.',
+'http-request-error' => 'Anezri warisem deg uceggaɛ n tuttra.',
+'http-read-error' => 'Anezri n taɣuri HTTP.',
+'http-timed-out' => 'Tuttra HTTP teneffeṛ.',
+'http-curl-error' => 'Anezri deg tiririt n URL : $1',
+'http-host-unreachable' => 'Ulamek an siḍes URL',
+'http-bad-status' => 'Yella ugur deg tuttra HTTP : $1 $2',
 
 # Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
 'upload-curl-error6' => 'Ur yezmir ara ad yessglu URL',
@@ -1379,6 +1569,7 @@ Ma yella daɣen anezri, ilaq ad meslaye ḍ s  [[Special:ListUsers/sysop|unedbal
 'license' => 'Turagt',
 'license-header' => 'Turagt',
 'nolicense' => 'Ur textareḍ acemma',
+'license-nopreview' => '(Azarskan ur yestufa ara)',
 'upload_source_url' => ' (URL saḥiḥ)',
 'upload_source_file' => ' (afaylu deg uselkim inek)',
 
@@ -1386,31 +1577,85 @@ Ma yella daɣen anezri, ilaq ad meslaye ḍ s  [[Special:ListUsers/sysop|unedbal
 'listfiles_search_for' => 'Nadi ɣef yisem n tugna:',
 'imgfile' => 'afaylu',
 'listfiles' => 'Umuɣ n tugniwin',
+'listfiles_thumb' => 'Aqmamaḍ',
 'listfiles_date' => 'Azemz',
 'listfiles_name' => 'Isem',
 'listfiles_user' => 'Amseqdac',
 'listfiles_size' => 'Tiddi (bytes/octets)',
 'listfiles_description' => 'Aglam',
+'listfiles_count' => 'Ileqman',
 
 # File description page
 'file-anchor-link' => 'Afaylu',
 'filehist' => 'Amazray n tugna',
 'filehist-help' => 'Senned ɣef yiwen azmez d usrag iwakken ad ẓṛeḍ afaylu aken yella deg imir nni.',
+'filehist-deleteall' => 'ekkes akkw',
+'filehist-deleteone' => 'ekkes',
 'filehist-revert' => 'Uɣal ar tasiwelt ssabeq',
 'filehist-current' => 'Lux a',
 'filehist-datetime' => 'Azmez/Asrag',
-'filehist-thumb' => 'Tugna tamecṭuḥt',
+'filehist-thumb' => 'Aqmamaḍ',
 'filehist-thumbtext' => 'Tugna tamectuḥt i lqem n $1',
+'filehist-nothumb' => 'Ulac aqmamaḍ',
 'filehist-user' => 'Amseqdac',
 'filehist-dimensions' => 'Iseggiwen',
+'filehist-filesize' => 'Tiddi n ufaylu',
 'filehist-comment' => 'Awennit',
+'filehist-missing' => 'Afaylu ulac-it',
 'imagelinks' => 'Izdayen',
 'linkstoimage' => '{{PLURAL:$1|Asebter agi teseqdac|$1 isebtaren agi teseqdacen}} afaylu agi :',
+'linkstoimage-more' => 'Ugar n {{PLURAL:$1|yiwen asebter|$1 isebtar}} tseqdacen afaylu agi.
+Umuɣ agi yebeqqeḍ ala {{PLURAL:$1|asebter amezwaru|$1 isebtar imezwura}} i seqdacen afaylu agi.
+Yella [[Special:WhatLinksHere/$2|umuɣ ummid]].',
 'nolinkstoimage' => 'Ulaḥedd seg isebtar sɛan azday ar afaylu-agi.',
+'morelinkstoimage' => 'Ẓeṛ [[Special:WhatLinksHere/$1|izdayen nniḍen]] ɣer afaylu agi.',
+'linkstoimage-redirect' => '$1 (allus n wesnili n ufaylu) $2',
+'duplicatesoffile' => '{{PLURAL:$1|Afaylu agi d anɣel|Ifuyla agi d ineɣlan}} n ufaylu agi ([[Special:FileDuplicateSearch/$2|tilɣa timarnanin]]) :',
 'sharedupload' => 'Afaylu agi yettuseqdac seg : $1. Yezmer ad yettuseqdac deg isenfaṛen nniḍen',
+'sharedupload-desc-there' => 'Afaylu agi yussad seg : $1. Yezmer ad yetseqdac sɣur isenfaren nniḍen.
+Ẓeṛ [$2 asebter is n uglam] ma tebɣiḍ tilɣa nniḍen.',
 'sharedupload-desc-here' => 'Afaylu agi yusad seg : $1. Ahat yeseqdec deg isenfaṛen nniḍen.
 Aglam-is ɣef [$2 asebter n aglam] ye beqqeḍ ddaw-agi.',
+'sharedupload-desc-edit' => 'Afaylu agi yussad seg : $1. Yezmer ad yetseqdac sɣur isenfaren nniḍen.
+Ahat tebɣiḍ ad beddeleḍ aglam is ɣef [$2 asebter is n uglam].',
+'sharedupload-desc-create' => 'Afaylu agi yussad seg : $1. Yezmer ad yetseqdac sɣur isenfaren nniḍen.
+Ẓeṛ [$2 asebter is n uglam] ma tebɣiḍ tilɣa nniḍen.',
+'filepage-nofile' => 'Ulac afaylu s isem agi.',
+'filepage-nofile-link' => 'Ulac afaylu s isem agi, maca tzemreḍ ad [$1 ktereḍ yiwen].',
 'uploadnewversion-linktext' => 'tazneḍ tasiwelt tamaynut n ufaylu-yagi',
+'shared-repo-from' => 'seg : $1',
+'shared-repo' => 'azadur azduklan',
+'upload-disallowed-here' => 'Ur tzemreḍ ara ad semselsiḍ tugna agi.',
+
+# File reversion
+'filerevert' => 'Erred $1',
+'filerevert-legend' => 'Erred afaylu',
+'filerevert-intro' => "Ha-ta-n ad uɣaleḍ ar ufaylu  '''[[Media:$1|$1]]''' ar [$4 lqem n $2 af $3].",
+'filerevert-comment' => 'Taɣẓint :',
+'filerevert-defaultcomment' => 'Uɣaleḍ ar lqem n $1 af $2',
+'filerevert-submit' => 'Erred',
+'filerevert-success' => "'''[[Media:$1|$1]]''' yuɣaled ar  [$4 lqem n $2 af $3].",
+'filerevert-badversion' => 'Ulac, deg udigan, lqem aqbur n ufaylu yesɛan azmez agi.',
+
+# File deletion
+'filedelete' => 'Kkes $1',
+'filedelete-legend' => 'Kkes asebter',
+'filedelete-intro' => "Ha-ta-n ad ekkeseḍ '''[[Media:$1|$1]]'' akkw d umezruy is.",
+'filedelete-intro-old' => "Ha-ta-n ad mḥuḍ lqem n '''[[Media:$1|$1]]''' n [$4 $2 af $3].",
+'filedelete-comment' => 'Taɣẓint :',
+'filedelete-submit' => 'Ekkes',
+'filedelete-success' => "'''$1''' yetwekkes.",
+'filedelete-success-old' => "Lqem n '''[[Media:$1|$1]]''' n $2 af $3 yetwekkes.",
+'filedelete-nofile' => "'''$1''' ulac-it.",
+'filedelete-nofile-old' => "Ulac lqem i ɣbeṛen n '''$1''' s ayla agi.",
+'filedelete-otherreason' => 'Taɣẓint nniḍen / taɣzint tamarnant :',
+'filedelete-reason-otherlist' => 'Taɣẓint nniḍen',
+'filedelete-reason-dropdown' => '* Tiɣzinin tillusanin n tukksa n ifuyla
+** Akukel n uzref n umeskar
+** Afaylu yesɛan anɣel',
+'filedelete-edit-reasonlist' => 'Beddel tiɣẓinin n umḥu i-d-yettuɣalen',
+'filedelete-maintenance' => 'Tukksa d tiririt n ifuyla yensa (akudan) deg ugani n ibeddi.',
+'filedelete-maintenance-title' => 'Ulamek an kkes afaylu',
 
 # MIME search
 'mimesearch' => 'Anadi n MIME',
@@ -1439,7 +1684,18 @@ Ur tettuḍ ara ad selkeneḍ ma ur llan ara izdayen nniḍen ɣer tilɣatin uqb
 
 # Statistics
 'statistics' => 'Tisnaddanin',
+'statistics-header-pages' => 'Tisnaddanin n isebtar',
+'statistics-header-edits' => 'Tisnaddanin n ibeddilen',
+'statistics-header-views' => 'Tisnaddanin n iskanen',
 'statistics-header-users' => 'Tisnaddanin n wemseqdac',
+'statistics-header-hooks' => 'Tisnaddanin nniḍen',
+'statistics-articles' => 'Isebtar n ugbur',
+'statistics-pages' => 'Isebtar',
+'statistics-pages-desc' => 'Akkw isebtar n wiki agi, ula d isebtar n umeslay, etc...',
+'statistics-files' => 'Ifuyla yettwaznen',
+'statistics-edits' => 'Ibeddilen n isebtar seg aserkeb n {{SITENAME}}',
+'statistics-edits-average' => 'Amḍan allal n ibeddilen sɣur asebter',
+'statistics-views-total' => 'Iskanen',
 'statistics-mostpopular' => 'isebtar mmeẓren aṭṭas',
 
 'disambiguations' => 'Isebtar yesɛan izdayen ɣer isebtar n tiynisemt',
@@ -1452,7 +1708,7 @@ Asebter yella d asebter n tiynisemt lukan yetseqdac talɣa i qqenen ar [[MediaWi
 'doubleredirectstext' => 'Mkull ajerriḍ yesɛa azday ɣer asmimeḍ amezwaru akk d wis sin, ajerriḍ amezwaru n uḍris n usebter wis sin daɣen, iwumi yefkan asmimeḍ ṣaḥiḥ i yessefk ad sɛan isebtar azday ɣur-s.',
 
 'brokenredirects' => 'Isemmimḍen imerẓa',
-'brokenredirectstext' => 'Isemmimḍen-agi sɛan izdayen ar isebtar ulac-iten:',
+'brokenredirectstext' => 'Isemmimḍen-agi sɛan izdayen ar isebtar ulac-iten :',
 'brokenredirects-edit' => 'beddel',
 'brokenredirects-delete' => 'mḥu',
 
@@ -1461,6 +1717,8 @@ Asebter yella d asebter n tiynisemt lukan yetseqdac talɣa i qqenen ar [[MediaWi
 'withoutinterwiki-legend' => 'Adat',
 'withoutinterwiki-submit' => 'Ssken',
 
+'fewestrevisions' => 'Isebtar yesɛan cwiṭ ibeddilen',
+
 # Miscellaneous special pages
 'nbytes' => '$1 {{PLURAL:$1|byte/octet|bytes/octets}}',
 'ncategories' => '$1 {{PLURAL:$1|Taggayt|Taggayin}}',
@@ -1480,48 +1738,68 @@ Asebter yella d asebter n tiynisemt lukan yetseqdac talɣa i qqenen ar [[MediaWi
 'popularpages' => 'Isebtar iɣerfanen',
 'wantedcategories' => 'Taggayin mmebɣant',
 'wantedpages' => 'Isebtar mmebɣan',
+'wantedfiles' => 'Ifuyla yettwasutren s waṭas.',
+'wantedtemplates' => 'Talɣiwin yetsuteren',
 'mostlinked' => 'Isebtar myezdin aṭas',
 'mostlinkedcategories' => 'Taggayin myezdint aṭas',
+'mostlinkedtemplates' => 'Talɣiwin yetseqdacen aṭas.',
 'mostcategories' => 'Isebtar i yesɛan aṭṭas taggayin',
 'mostimages' => 'Ifuyla i seqdacen aṭas',
+'mostinterwikis' => 'Isebtar yesɛan aṭas interwikis',
 'mostrevisions' => 'Isebtar i yettubedlen aṭas',
 'prefixindex' => 'Akk isebtaren s yisekkilen imezwura',
+'prefixindex-namespace' => 'Akkw isebtar s adat (tallunt n isemawe $1)',
 'shortpages' => 'isebtar imecṭuḥen',
 'longpages' => 'Isebtar imeqqranen',
 'deadendpages' => 'isebtar mebla izdayen',
 'deadendpagestext' => 'Isebtar agi ur sɛan ara izdayen ɣer isebtar nniḍen n {{SITENAME}}.',
 'protectedpages' => 'isebtar yettwaḥerzen',
+'protectedpages-indef' => 'Imestenen imeɣlalen kan',
+'protectedpages-cascade' => 'Imestenen s uceṛcuṛ kan',
 'protectedpagestext' => 'isebtar-agi yettwaḥerzen seg ubeddel neɣ asemmimeḍ',
 'protectedpagesempty' => 'isebtar-agi ttwaḥerzen s imsektayen -agi.',
+'protectedtitles' => 'Izwal ugdilen',
+'protectedtitlestext' => 'Izwal agi ugdilen deg usnulfu nsen',
+'protectedtitlesempty' => 'Ulac azwel yesɛan asegdel s iɣewwaren agi.',
 'listusers' => 'Umuɣ n yimseqdacen',
+'listusers-editsonly' => 'Sekned kan iseqdacen yesɛan asekcem naɣ ugar',
+'listusers-creationsort' => 'Fren s azmez n usnulfu',
+'usereditcount' => '$1 {{PLURAL:$1|abeddel|ibeddilen}}',
 'usercreated' => '{{GENDER:$3|Yesnulfu-d}} ass n $1 ar $2',
 'newpages' => 'isebtar imaynuten',
 'newpages-username' => 'Isem n wemseqdac:',
 'ancientpages' => 'isebtar iqdimen',
 'move' => 'Smimeḍ',
 'movethispage' => 'Smimeḍ asebter-agi',
-'unusedimagestext' => 'Ssen belli ideggen n internet sɛan izdayen ɣer tugna-agi s URL n qbala, ɣas akken tugna-nni hatt da.',
+'unusedimagestext' => 'Ifuyla agi llan, maca ulac asebter anda llan.
+Ahat llan ismal nniḍen yesɛan azday ɣer afaylu, ihi yezmer ad yiqqim afaylu d agi dɣa ad yetseqdac deg ismal nni.',
 'unusedcategoriestext' => 'Taggayin-agi weǧden meɛna ulac isebtar neɣ taggayin i sseqdacen-iten.',
 'notargettitle' => 'Ulac nnican',
 'notargettext' => 'Ur textareḍ ara asebter d nnican neɣ asebter n wemseqdac d nnican.',
+'nopagetitle' => 'Ulac asebter asaḍas am wagi',
+'nopagetext' => 'Asebter asaḍas agi ulac-it.',
 'pager-newer-n' => '{{PLURAL:$1|amaynut|$1 imaynuten}}',
 'pager-older-n' => '{{PLURAL:$1|aqbur|$1 iqburen}}',
+'suppress' => 'Mdi',
+'querypage-disabled' => 'Asebter uslig agi yensa , taɣzint : timellal is.',
 
 # Book sources
 'booksources' => 'Iɣbula n yidlisen',
 'booksources-search-legend' => 'Nadi ɣef iɣbula n yidlisen',
 'booksources-go' => 'Ruḥ',
 'booksources-text' => 'Deg ukessar, yella wumuɣ n yizdayen iberraniyen izzenzen idlisen (imaynuten akk d weqdimen), yernu ahat sɛan kter talɣut ɣef idlisen i tettnadiḍ fell-asen:',
+'booksources-invalid-isbn' => 'ISBN agi ur yeɣbel ara ; selken ma ulac anezri deg-es.',
 
 # Special:Log
 'specialloguserlabel' => 'Ameskar :',
 'speciallogtitlelabel' => 'Asaḍas (azwel naɣ aseqdac) :',
 'log' => 'Aɣmis',
 'all-logs-page' => 'Akk iɣmisen izayezen',
-'alllogstext' => 'Ssken akk iɣmisen n {{SITENAME}}.
-Tzemreḍ ad textareḍ cwiṭ seg-sen ma tebɣiḍ.',
+'alllogstext' => 'Abeqqeḍ n akkw iɣmisen yestufan ɣef {{SITENAME}}.<br />
+Tzemreḍ ad sageneḍ abeqqeḍ s tixtiṛit n tawsit n uɣmis, isem n useqdac naɣ asebter nni.',
 'logempty' => 'Ur yufi ara deg uɣmis.',
 'log-title-wildcard' => 'Nadi ɣef izwal i yebdan s uḍris-agi',
+'showhideselectedlogentries' => 'Beqqeḍ/ffer isekcam n uɣmis agi',
 
 # Special:AllPages
 'allpages' => 'Akk isebtar',
@@ -1529,6 +1807,7 @@ Tzemreḍ ad textareḍ cwiṭ seg-sen ma tebɣiḍ.',
 'nextpage' => 'Asebter ameḍfir ($1)',
 'prevpage' => 'Asebter ssabeq ($1)',
 'allpagesfrom' => 'Ssken isebtar seg:',
+'allpagesto' => 'Beqqeḍ isebtar alama :',
 'allarticles' => 'Akk imagraden',
 'allinnamespace' => 'Akk isebtar ($1 isem n taɣult)',
 'allnotinnamespace' => 'Akk isebtar (mačči deg $1 isem n taɣult)',
@@ -1538,16 +1817,25 @@ Tzemreḍ ad textareḍ cwiṭ seg-sen ma tebɣiḍ.',
 'allpagesprefix' => 'Ssken isebtar s uzwir:',
 'allpagesbadtitle' => 'Azwel n usebter mačči ṣaḥiḥ neɣ yesɛa azwir inter-wiki. Waqila yesɛa isekkilen ur ttuseqdacen ara deg izwal.',
 'allpages-bad-ns' => '{{SITENAME}} ur yesɛi ara isem n taɣult "$1".',
+'allpages-hide-redirects' => 'Ffer isemmimḍen',
+
+# SpecialCachedPage
+'cachedspecial-refresh-now' => 'Ẓeṛ aneggaru.',
 
 # Special:Categories
 'categories' => 'Taggayin',
-'categoriespagetext' => 'Llant taggayin-agi deg wiki-yagi.
-[[Special:UnusedCategories|Unused categories]] are not shown here.
-Also see [[Special:WantedCategories|wanted categories]].',
+'categoriespagetext' => '{{PLURAL:$1|Taggayt agi teseqdec|Taggayin agi teseqdecet}} sɣur isebtar naɣ ifuyla.
+[[Special:UnusedCategories|Taggayin ur sɛan ara aqeddic]]
+Ẓeṛ daɣen [[Special:WantedCategories|taggayin yetwesuteren]].',
 'categoriesfrom' => 'Ssken taggayin seg :',
 'special-categories-sort-count' => 'Afran s amḍan n iferdisen',
 'special-categories-sort-abc' => 'Afran s ugemmay',
 
+# Special:DeletedContributions
+'deletedcontributions' => 'Isekcam yemḥan',
+'deletedcontributions-title' => 'Isekcam yemḥan',
+'sp-deletedcontributions-contribs' => 'Isekcam',
+
 # Special:LinkSearch
 'linksearch' => 'Anadi n izdayen yeffɣen',
 'linksearch-pat' => 'Anadi n tanfalit :',
@@ -1560,6 +1848,10 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'listusers-submit' => 'Ssken',
 'listusers-noresult' => 'Ur yufi ḥedd (amseqdac).',
 
+# Special:ActiveUsers
+'activeusers-from' => 'Ssken iseqdacen seg :',
+'activeusers-noresult' => 'Ur yufi aseqdac.',
+
 # Special:Log/newusers
 'newuserlogpage' => 'Aɣmis n isnulfan n  imiḍanen n imseqdacen',
 
@@ -1644,7 +1936,7 @@ Ma tebɣiḍ ad tekkseḍ asebter seg wumuɣ n uɛessi inek, wekki ɣef \"Fakk a
 'watchmethod-list' => 'yessenqed isebtar i ttɛassaɣ i ibeddlen imaynuten',
 'watchlistcontains' => 'Umuɣ n uɛessi inek ɣur-s $1 n {{PLURAL:$1|usebter|isebtar}}.',
 'iteminvalidname' => "Agnu akk d uferdis '$1', isem mačči ṣaḥiḥ...",
-'wlnote' => "Deg ukessar {{PLURAL:$1|yella yiwen ubeddel aneggaru|llan '''$1''' n yibeddlen ineggura}} deg {{PLURAL:$2|saɛa taneggarut|'''$2''' swayeɛ tineggura}}.",
+'wlnote' => "Ddaw agi  {{PLURAL:$1|yella abeddel aneggaru|llan '''$1''' ibeddilen ineggura}} n {{PLURAL:$2|usrag aneggaru|'''$2''' isragen ineggura}}, seg $3 af $4.",
 'wlshowlast' => 'Ssken $1 n swayeɛ $2 n wussan neɣ $3 ineggura',
 'watchlist-options' => 'Tifranin n umuɣ n uɛessi',
 
@@ -1698,6 +1990,8 @@ Tuɣalin d tadhelt :
 'excontentauthor' => "Ayen yella: '$1' ('[[Special:Contributions/$2|$2]]' kan i yekken deg-s)",
 'exbeforeblank' => "Ayen yella uqbal ma yettumḥa: '$1'",
 'exblank' => 'asebter yella d ilem',
+'delete-confirm' => 'Kkes "$1"',
+'delete-legend' => 'Ekkes',
 'historywarning' => 'Ɣur-wet : Asebter i ara temḥuḍ yesɛa amezruy s azal alemmas n $1 {{PLURAL:$1|lqem|ileqman}} :',
 'actioncomplete' => 'Axdam yekfa',
 'actionfailed' => 'Tigawt agi texser',
@@ -1708,9 +2002,14 @@ Tuɣalin d tadhelt :
 'deletionlog' => 'Aɣmis n umḥay',
 'reverted' => 'Asuɣal i tasiwel taqdimt',
 'deletecomment' => 'Ayɣer',
+'deleteotherreason' => 'Taɣẓint nniḍen / taɣzint tamarnant :',
+'deletereasonotherlist' => 'Taɣẓint nniḍen',
+'delete-edit-reasonlist' => 'Beddel tiɣẓinin n umḥu n usebter',
 
 # Rollback
+'rollback_short' => 'Semmet',
 'rollbacklink' => 'semmet',
+'rollbacklinkcount' => 'semmet $1 {{PLURAL:$1|abeddel|ibeddilen}}',
 'cantrollback' => 'Ur yezmir ara ad yessuɣal; yella yiwen kan amseqdac iwumi ibeddel/yexleq asebter-agi.',
 'editcomment' => "Agzul n ubeddel yella: \"''\$1''\".",
 'revertpage' => 'Yessuɣal ibeddlen n [[Special:Contributions/$2|$2]] ([[User talk:$2|Meslay]]); yettubeddel ɣer tasiwelt taneggarut n [[User:$1|$1]]',
@@ -1726,19 +2025,32 @@ G leɛnayek wekki ɣef taqeffalt "Back/Précédent" n browser/explorateur inek,
 'protect-title' => 'Ad yeḥrez "$1"',
 'prot_1movedto2' => '[[$1]] yettusmimeḍ ar [[$2]]',
 'protect-legend' => 'Sentem tiḥḥerzi',
+'protectcomment' => 'Taɣẓint :',
 'protect-default' => '(ameslugen)',
 'protect-level-sysop' => 'Inedbalen kan',
 'protect-summary-cascade' => 'acercur',
 'protect-expiring' => 'yemmut deg $1 (UTC)',
+'protect-otherreason' => 'Taɣẓint nniḍen / taɣzint tamarnant :',
+'protect-otherreason-op' => 'Taɣẓint nniḍen',
+'protect-edit-reasonlist' => 'Beddel tiɣẓinin n usegdel',
+'protect-expiry-options' => '1 asrag:1 hour,1 ass:1 day,1 imalas:1 week,2 imalasen:2 weeks,1 aggur:1 month,3 agguren:3 months,6 agguren:6 months,1 assegwas:1 year,adfi:infinite',
 'restriction-type' => 'Turagt',
 'minimum-size' => 'Tiddi minimum',
 
 # Restrictions (nouns)
 'restriction-edit' => 'Beddel',
 'restriction-move' => 'Smimeḍ',
+'restriction-create' => 'Snulfu',
+
+# Restriction levels
+'restriction-level-autoconfirmed' => 'adu-asegdel',
 
 # Undelete
+'undelete' => 'Ẓer isebtar yettumḥan',
+'undeletepage' => 'Ẓeṛ dɣa erred isebtar yetwekkesen',
+'undeletepagetitle' => "'''Umuɣ agi yesɛa ileqman yetwekkesen n [[:$1|$1]]'''.",
 'viewdeletedpage' => 'Ẓer isebtar yettumḥan',
+'undelete-fieldset-title' => 'Erred ileqman',
 'undeletelink' => 'ẓeṛ/uɣaled',
 'undeleteviewlink' => 'ẓeṛ',
 'undeletecomment' => 'Taɣẓint :',
@@ -1799,15 +2111,43 @@ G leɛnayek wekki ɣef taqeffalt "Back/Précédent" n browser/explorateur inek,
 'ipadressorusername' => 'Tansa IP neɣ isem n wemseqdac',
 'ipbreason' => 'Ayɣer',
 'ipbsubmit' => 'Ɛekkel amseqdac-agi',
-'ipboptions' => '2 isragen:2 hours,1 ass:1 day,3 ussan:3 days,1 imalas:1 week,2  imulas:2 weeks,1 aggur:1 month,3 igguren:3 months,6 igguren:6 months,1 aseggwas:1 year,afdi:infinite',
+'ipboptions' => '2 isragen:2 hours,1 ass:1 day,3 ussan:3 days,1 imalas:1 week,2  imalasen:2 weeks,1 aggur:1 month,3 agguren:3 months,6 agguren:6 months,1 aseggwas:1 year,afdi:infinite',
 'ipbotheroption' => 'nniḍen',
 'badipaddress' => 'Tansa IP mačči d ṣaḥiḥ',
+'ipusubmit' => 'Ekkes akyaf agi',
+'unblocked' => 'Yetwekkes akyaf n [[User:$1|$1]]',
+'unblocked-range' => 'Yetwekkes akyaf n $1',
+'unblocked-id' => 'Akyaf $1 yetwekkes',
+'blocklist' => 'Iseqdacen id yetkyefen',
 'ipblocklist' => 'imseqdacen isewḥelen',
+'ipblocklist-legend' => 'Nadi aseqdac id yetkyefen',
+'blocklist-userblocks' => 'Ffer ikyafen n imiḍanen',
+'blocklist-tempblocks' => 'Ffer ikyafen ikudanen',
+'blocklist-addressblocks' => 'Ffer ikyafen n tansa IP tisuftin',
+'blocklist-rangeblocks' => 'Ffer iḥedran n azrag',
+'blocklist-timestamp' => 'Azmez d usrag',
+'blocklist-target' => 'Asaḍas',
+'blocklist-expiry' => 'Azmez n tasewti',
+'blocklist-by' => 'Anedbal i sexdemen akyaf',
+'blocklist-params' => 'Iɣewwaren n ukyaf',
+'blocklist-reason' => 'Taɣẓint',
 'ipblocklist-submit' => 'Nadi',
+'ipblocklist-localblock' => 'Akyaf adigan',
+'ipblocklist-otherblocks' => '{{PLURAL:$1|Akyaf nniḍen|Ikyafen nniḍen}}',
+'infiniteblock' => 'ameɣlal',
+'expiringblock' => 'tasewti ass n $1 af $2',
+'anononlyblock' => 'iseqdacen ur sɛan ara amiḍan kan',
+'noautoblockblock' => 'akyaf awurman yensa',
+'createaccountblock' => 'asnulfu n umiḍan yekyef',
+'emailblock' => 'e-mail yekyef',
+'blocklist-nousertalk' => 'ur yezmer ara ad yebeddel asebter-is n umeslay',
+'ipblocklist-empty' => 'Umuɣ n tansiwin IP i kyefen d-ilem.',
+'ipblocklist-no-results' => 'Tansa IP naɣ aseqdac i sutereḍ ur yekyef ara.',
 'blocklink' => 'ɛekkel',
 'unblocklink' => 'ekkes asewḥel',
 'change-blocklink' => 'beddel asewḥel',
 'contribslink' => 'tikkin',
+'emaillink' => 'Ceggaɛ e-mail',
 'blocklogpage' => 'Aɣmis n isewḥelen',
 'blocklogentry' => 'yesewḥel [[$1]] ; alama : $2 $3',
 'block-log-flags-anononly' => 'Imseqdacen udrigen kan',
@@ -1823,14 +2163,12 @@ Ur tezmireḍ ara ad snulfuḍ amiḍan.',
 
 # Move page
 'move-page-legend' => 'Smimeḍ asebter',
-'movepagetext' => "Mi tedsseqdceḍ talɣa deg ukessar ad ibddel isem n usebter, yesmimeḍ akk umezruy-is ɣer isem amaynut.
-Azwel aqdim ad yuɣal azady n wesmimeḍ ɣer azwel amaynut.
-Izdayen ɣer azwel aqdim ur ttubeddlen ara;
-ssenqd-iten u ssenqed izdayen n snat d tlata tikkwal.
-D kečč i yessefk a ten-yessenqed.
-
-Meɛna, ma yella amagrad deg azwel amaynut neɣ azday n wamsmimeḍ mebla amezruy, asebter-inek '''ur''' yettusmimeḍ '''ara'''.
-Yernu, tzemreḍ ad tesmimeḍ asebter ɣer isem-is aqdim ma tɣelṭeḍ.",
+'movepagetext' => "Seqdec tiferkit ddaw agi iwakken ad beddeleḍ isem n usebter, s usiweḍ n akkw amezruy is ɣer isem amaynut. Azwel aqbur ad yuɣal d asebter n usemmime ɣer azwel amaynut. Tzemreḍ ad mucceḍeḍ s uwurman isemmimen amiran i sweṛen ɣer azwel amezwaru. Ma ur tebɣiḍ ara at sexdemeḍ wagi, ilaq ad selkeneḍ akkw [[Special:DoubleRedirects|Asemmimeḍ yeḍran snat tikwal]] naɣ [[Special:BrokenRedirects|asmmimeḍ yerẓan]]. Ilaq ad sɛuḍ talkint belli izdayen tsweṛen ɣer aserken is.
+
+Abeddel n isem ur yezmer ara ad yilli ma yella yakan asebter s isem agi, ḥaca ma ulac amezruy deg-es.
+
+'''Ɣur-wet !'''
+Wagi yezmer ad yexdem abeddel ameqqṛan i asebter s aṭas timerziwin ; ilaq ad fehmeḍ uqbel ad beddeleḍ asebter.",
 'movepagetalktext' => "Asebter \"Amyannan\" yettusmimeḍ ula d netta '''ma ulac:'''
 *Yella asebter \"Amyannan\" deg isem amaynut, neɣ
 *Trecmeḍ tankult deg ukessar.
@@ -2047,11 +2385,21 @@ Lukan a t-tesseqdceḍ yezmer ad yexsser aselkim inek/inem.",
 # Special:NewFiles
 'newimages' => 'Umuɣ n ifayluwen imaynuten',
 'imagelisttext' => "Deg ukessar yella wumuɣ n '''$1''' {{PLURAL:$1|ufaylu|yifayluwen}} $2.",
+'newimages-legend' => 'Tastayt',
+'newimages-label' => 'Isem n ufaylu (naɣ aḥric ines) :',
+'showhidebots' => '($1 iṛubuten)',
 'noimages' => 'Tugna ulac-itt.',
 'ilsubmit' => 'Nadi',
 'bydate' => 's uzemz',
 'sp-newimages-showfrom' => 'Beqqeḍ ifuyla imaynuten seg $1 ar $2',
 
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'seconds' => '{{PLURAL:$1|$1 tasint|$1 tasinin}}',
+'minutes' => '{{PLURAL:$1|$1 tamrect|$1 timercin}}',
+'hours' => '{{PLURAL:$1|$1 asrag|$1 isragen}}',
+'days' => '{{PLURAL:$1|$1 ass|$1 ussan}}',
+'ago' => '$1 aya',
+
 # Bad image list
 'bad_image_list' => 'Amasal d-wagi :
 
@@ -2061,6 +2409,8 @@ Izdayen nniḍen ɣef yiwen ajerriḍ llan d tisuraf, am isebtar ɣef anta tugna
 # Metadata
 'metadata' => 'Adferisefka',
 'metadata-help' => 'Afaylu agi, yesɛa tilɣa tisutay, ahat d-tamsaknewt id ernan tilɣa agi. Ma afaylu yebeddel seg addad-is amezwaru, ahat kra n tilɣa ur zemrent ara ad illint d-timekdant s-ufaylu amiran.',
+'metadata-expand' => 'Beqqeḍ tilɣa tummidin',
+'metadata-collapse' => 'Ffer tilɣa tummidin',
 'metadata-fields' => 'Urtan n adferisefka n tugniwin yellan deg umuɣ n izen agi, ad seddun deg usebter n aglam n tugna mi ṭabla n adferisefka at illi tesemẓi. Urtan nniḍen ad illin ffren m-ulac.
 * make
 * model
@@ -2078,6 +2428,68 @@ Izdayen nniḍen ɣef yiwen ajerriḍ llan d tisuraf, am isebtar ɣef anta tugna
 
 # EXIF tags
 'exif-imagewidth' => 'Tehri',
+'exif-imagelength' => 'Taɣwzi',
+'exif-bitspersample' => 'Ibitten s isger',
+'exif-compression' => 'Tawsit n asekkusem',
+'exif-photometricinterpretation' => 'Talɣa n uferdis n tugna',
+'exif-orientation' => 'Taɣda',
+'exif-samplesperpixel' => 'Tisegranin s uferdis n tugna',
+'exif-planarconfiguration' => 'Aheggi n isefka',
+'exif-ycbcrsubsampling' => 'Atug n adu-isefka n ulemmec n Y ar C',
+'exif-ycbcrpositioning' => 'Aselfu n Y d C',
+'exif-xresolution' => 'Tabadut taglawit',
+'exif-yresolution' => 'Tabadut taratakt',
+'exif-stripoffsets' => 'Asun n isefka n tugna',
+'exif-rowsperstrip' => 'Amḍan n ijerriden s tasfift',
+'exif-stripbytecounts' => 'Tiddi n itamḍanen s tasfift',
+'exif-jpeginterchangeformat' => 'Ideg n SOI JPEG',
+'exif-jpeginterchangeformatlength' => 'Tiddi s itamḍanen n isefka JPEG',
+'exif-whitepoint' => 'Tiniskit n uqqa amellal',
+'exif-primarychromaticities' => 'Tiniskit n tizwaranin',
+'exif-referenceblackwhite' => 'Azalen n tamselɣut aberkan d umellal',
+'exif-datetime' => 'Azmez n ubeddel',
+'exif-imagedescription' => 'Aglam n tugna',
+'exif-make' => 'Amakras n taweṣṣaft',
+'exif-model' => 'Talɣa n taweṣṣaft',
+'exif-software' => 'Aseɣẓan yetseqdecen',
+'exif-artist' => 'Ameskar',
+'exif-copyright' => 'Amli n uzref n umeskar',
+'exif-exifversion' => 'Lqem EXIF',
+'exif-flashpixversion' => 'Lqem FlashPix',
+'exif-colorspace' => 'Tallunt n tiniskit',
+'exif-componentsconfiguration' => 'Anamek n yal isger',
+'exif-compressedbitsperpixel' => 'Askar n usekkusem n tugna',
+'exif-pixelydimension' => 'Tehri n tugna',
+'exif-pixelxdimension' => 'Taɣwzi n tugna',
+'exif-usercomment' => 'Iwenniten n useqdac',
+'exif-relatedsoundfile' => 'Afaylu n eslu yeqqnen',
+'exif-datetimeoriginal' => 'Azmez n tuddma tamezwarut',
+'exif-datetimedigitized' => 'Azmez n usemḍen',
+'exif-subsectime' => 'Azmez n ubeddel',
+'exif-subsectimeoriginal' => 'Azmez n tuddma tamezwarut',
+'exif-subsectimedigitized' => 'Azmez n usemḍen',
+'exif-exposuretime' => 'Akud n timzikent',
+'exif-exposuretime-format' => '$1 tas ($2 tas)',
+'exif-fnumber' => 'Alday',
+'exif-exposureprogram' => 'Ahil n timzikent',
+'exif-aperturevalue' => 'Alday n APEX',
+'exif-exposurebiasvalue' => 'Aseɣti n timzikent',
+'exif-maxaperturevalue' => 'Alday afellay',
+'exif-subjectdistance' => 'Ameccaq n usentel',
+'exif-meteringmode' => 'Askar n usket',
+'exif-lightsource' => 'Aɣbalu n tafat',
+'exif-flash' => 'Lebṛaq',
+'exif-focallength' => 'Taɣwzi n usaḍas',
+'exif-subjectarea' => 'Asun n usentel',
+'exif-flashenergy' => 'Tanezmart n lebṛaq',
+'exif-focalplanexresolution' => 'Tabadut taglawit n uɣawas asaḍas',
+'exif-focalplaneyresolution' => 'Tabadut taratakt n uɣawas asaḍas',
+'exif-focalplaneresolutionunit' => 'Aferdis n tabadut n uɣawas asaḍas',
+'exif-subjectlocation' => 'Asideg n usentel',
+'exif-exposureindex' => 'Amatar n timzikent',
+'exif-sensingmethod' => 'Tawsit n umaṭṭaf',
+'exif-filesource' => 'Aɣbal n ufaylu',
+'exif-scenetype' => 'Tawsit n usayes',
 'exif-worldregiondest' => 'Timnaḍin n umaḍal yebeqqeḍen',
 'exif-countrydest' => 'Timura yebeqqeḍen',
 'exif-countrycodedest' => 'Tangalt n tamurt yebeqqeḍen',
@@ -2105,8 +2517,125 @@ Izdayen nniḍen ɣef yiwen ajerriḍ llan d tisuraf, am isebtar ɣef anta tugna
 'exif-originaltransmissionref' => 'Tangalt n usideg n tuzzna tamezwarut',
 'exif-identifier' => 'Asulay',
 
+'exif-copyrighted-true' => 'Ddaw azref n umeskar',
+'exif-copyrighted-false' => 'Taɣuly tazayezt',
+
+'exif-unknowndate' => 'Azmez warisem',
+
+'exif-orientation-1' => 'Amagnu',
+'exif-orientation-2' => 'Tetti s udem aglawan',
+'exif-orientation-3' => 'Tezzi s 180°',
+'exif-orientation-4' => 'Tetti s udem aratak',
+'exif-orientation-5' => 'Tezzi s 90° deg unamek imitti n usrag dɣa tetti s udem aratak',
+'exif-orientation-6' => 'Tezzi s 90° deg unamek imitti n usrag',
+'exif-orientation-7' => 'Tezzi s 90° deg unamek n usrag dɣa tetti s udem aratak',
+'exif-orientation-8' => 'Tezzi s 90° deg unamek n usrag',
+
+'exif-planarconfiguration-1' => 'Isefka iqriben',
+'exif-planarconfiguration-2' => 'Isefka ibrarazen',
+
+'exif-colorspace-65535' => 'Ur yezize ara',
+
+'exif-componentsconfiguration-0' => 'Ulac it',
+
+'exif-exposureprogram-0' => 'Ur yersen ara',
+'exif-exposureprogram-1' => 'Awfus',
+'exif-exposureprogram-2' => 'Ahil alugan',
+'exif-exposureprogram-3' => 'Tazwart i ulday',
+'exif-exposureprogram-4' => 'Tazwart i uqfel',
+'exif-exposureprogram-5' => 'Ahil n usnulfu (azullen i tadrut n urti)',
+'exif-exposureprogram-6' => 'Ahil n tigawt (azullen i urured n yqfel)',
+'exif-exposureprogram-7' => 'Askar tafrist (i tugniwin s tama dɣa s ugilal iluɣen)',
+'exif-exposureprogram-8' => 'Askar agama (i tugniwin n igmaten i llulcen)',
+
+'exif-subjectdistance-value' => '$1 lmitra',
+
+'exif-meteringmode-0' => 'Warisem',
+'exif-meteringmode-1' => 'Alemmas',
+'exif-meteringmode-2' => 'Allal amnekna deg agwans',
+'exif-meteringmode-3' => 'Asfaw',
+'exif-meteringmode-4' => 'Aget-asfaw',
+'exif-meteringmode-5' => 'Talɣa',
+'exif-meteringmode-6' => 'Aḥric',
 'exif-meteringmode-255' => 'Nniḍen',
 
+'exif-lightsource-0' => 'Warisem',
+'exif-lightsource-1' => 'Tafukt n ass',
+'exif-lightsource-2' => 'Arafaw afliyuṛi',
+'exif-lightsource-3' => 'Tungsten (tafat tanesfawt)',
+'exif-lightsource-4' => 'Lebṛaq',
+'exif-lightsource-9' => 'Akud aceεlal',
+'exif-lightsource-10' => 'Akud isignew',
+'exif-lightsource-11' => 'Tili',
+'exif-lightsource-12' => 'Asfaw afliyuṛi  « tafukt n ass » (D 5700 – 7100 K)',
+'exif-lightsource-13' => 'Asfaw afliyuṛi amellal « ass » (N 4600 – 5400 K)',
+'exif-lightsource-14' => 'Asfaw afliyuṛi amellal « asemmaḍ » (W 3900 – 4500 K)',
+'exif-lightsource-15' => 'Asfaw afliyuṛi amellal (WW 3200 – 3700 K)',
+'exif-lightsource-17' => 'Tafat talugent A',
+'exif-lightsource-18' => 'Tafat talugent B',
+'exif-lightsource-19' => 'Tafat talugent C',
+'exif-lightsource-24' => 'Tungsten ISU n usakwen',
+'exif-lightsource-255' => 'Aɣbalu nniḍen n tafat',
+
+# Flash modes
+'exif-flash-fired-0' => 'Lebṛaq ur yendeḥ ara',
+'exif-flash-fired-1' => 'Lebṛaq yendeḥ',
+'exif-flash-mode-1' => 'Tafat n lebaq yuwren',
+'exif-flash-mode-2' => 'Tukksa n lebaq yuwren',
+'exif-flash-mode-3' => 'askar awurman',
+'exif-flash-function-1' => 'Ulac tasɣent n lebṛaq',
+'exif-flash-redeye-1' => 'Tasɣent mgel-allen izeggwaɣen',
+
+'exif-focalplaneresolutionunit-2' => 'Idebbuzen',
+
+'exif-sensingmethod-1' => 'Aranbadu',
+'exif-sensingmethod-2' => 'Amaṭṭaf n ini s yiwen aceṛṛun',
+'exif-sensingmethod-3' => 'Amaṭṭaf n ini s sin iceṛṛunen',
+'exif-sensingmethod-4' => 'Amaṭṭaf n ini s kṛaḍ iceṛṛunen',
+'exif-sensingmethod-5' => 'Amaṭṭaf n ini ulkim',
+'exif-sensingmethod-7' => 'Amaṭṭaf kṛaḍimzireg',
+'exif-sensingmethod-8' => 'Amaṭṭaf n ini imzireg ulkim',
+
+'exif-filesource-3' => 'Taweṣṣaft tumḍint',
+
+'exif-scenetype-1' => 'Tugna n tafarut tusridt',
+
+'exif-customrendered-0' => 'Akala alugen',
+'exif-customrendered-1' => 'Akala yesagen',
+
+'exif-exposuremode-0' => 'Awurman',
+'exif-exposuremode-1' => 'Awfus',
+'exif-exposuremode-2' => 'Tazercet tawurmant',
+
+'exif-whitebalance-0' => 'Awurman',
+'exif-whitebalance-1' => 'Awfus',
+
+'exif-scenecapturetype-0' => 'Alugen',
+'exif-scenecapturetype-1' => 'Agama',
+'exif-scenecapturetype-2' => 'Tafrist',
+'exif-scenecapturetype-3' => 'Asayes n iḍ',
+
+'exif-gaincontrol-0' => 'Ulac',
+'exif-gaincontrol-1' => 'Rrbeḥ ufrir s ubedlez',
+'exif-gaincontrol-2' => 'Rrbeḥ ufrir s aṭas',
+'exif-gaincontrol-3' => 'Rrbeḥ uzdir s ubedlez',
+'exif-gaincontrol-4' => 'Rrbeḥ uzdir s aṭas',
+
+'exif-contrast-0' => 'Amagnu',
+'exif-contrast-1' => 'Abadlaz',
+'exif-contrast-2' => 'Aẓayan',
+
+'exif-saturation-0' => 'Amagnu',
+'exif-saturation-1' => 'Abadlaz',
+'exif-saturation-2' => 'Tameqqṛant',
+
+'exif-sharpness-0' => 'Amagnu',
+'exif-sharpness-1' => 'Alegɣan',
+'exif-sharpness-2' => 'Aẓayan',
+
+'exif-subjectdistancerange-0' => 'Warisem',
+'exif-subjectdistancerange-1' => 'Amɣer',
+
 # Pseudotags used for GPSSpeedRef
 'exif-gpsspeed-k' => 'Kilometr deg ssaɛa',
 'exif-gpsspeed-m' => 'Miles deg usrag',
@@ -2117,8 +2646,11 @@ Izdayen nniḍen ɣef yiwen ajerriḍ llan d tisuraf, am isebtar ɣef anta tugna
 'exif-gpsdestdistance-m' => 'igimen',
 'exif-gpsdestdistance-n' => 'Miles iwlalen',
 
+'exif-gpsdop-excellent' => 'Yufrar ($1)',
 'exif-gpsdop-good' => 'Tamellayt ($1)',
 'exif-gpsdop-moderate' => 'Tallalt ($1)',
+'exif-gpsdop-fair' => 'Attwadag ($1)',
+'exif-gpsdop-poor' => 'Yecmet ($1)',
 
 'exif-objectcycle-a' => 'Tanzayt kan',
 'exif-objectcycle-p' => 'Tameddit kan',
@@ -2153,6 +2685,18 @@ Izdayen nniḍen ɣef yiwen ajerriḍ llan d tisuraf, am isebtar ɣef anta tugna
 'exif-iimcategory-hth' => 'Tadawsa',
 'exif-iimcategory-hum' => 'Aramsu alsi',
 'exif-iimcategory-lab' => 'Amahil',
+'exif-iimcategory-lif' => 'Askar n tudert dɣa n imezlan',
+'exif-iimcategory-pol' => 'Tasertit',
+'exif-iimcategory-rel' => 'Ddin d tifelsin',
+'exif-iimcategory-sci' => 'Tussna d tatiknulujit',
+'exif-iimcategory-soi' => 'Tuttriwin timettiyin',
+'exif-iimcategory-spo' => 'Addalen',
+'exif-iimcategory-war' => 'Ṭrad, taẓit d tasmessit',
+'exif-iimcategory-wea' => 'Tasnignewt',
+
+'exif-urgency-normal' => 'Alugen ($1)',
+'exif-urgency-low' => 'Anammum ($1)',
+'exif-urgency-high' => 'Afella ($1)',
 
 # External editor support
 'edit-externally' => 'Beddel afaylu-yagi s usnas aberrani.',
@@ -2162,6 +2706,7 @@ Izdayen nniḍen ɣef yiwen ajerriḍ llan d tisuraf, am isebtar ɣef anta tugna
 'watchlistall2' => 'akk',
 'namespacesall' => 'akk',
 'monthsall' => 'akk',
+'limitall' => 'Akkw',
 
 # E-mail address confirmation
 'confirmemail' => 'Sentem tansa n e-mail',
@@ -2287,7 +2832,7 @@ G leɛnaya-k sentem belli ṣaḥḥ tebɣiḍ ad tɛiwedeḍ axlaq n usebter-ag
 'duplicate-defaultsort' => 'Ɣur-wet : tasarut n ufran m-ulac « $2 » atsefεej tasarut n uqbel « $1 ».',
 
 # Special:Version
-'version' => 'Tasiwelt',
+'version' => 'Lqem',
 'version-specialpages' => 'isebtar usligen',
 
 # Special:SpecialPages
@@ -2306,6 +2851,13 @@ G leɛnaya-k sentem belli ṣaḥḥ tebɣiḍ ad tɛiwedeḍ axlaq n usebter-ag
 # Special:Tags
 'tag-filter' => 'Astay n [[Special:Tags|ticraḍ]] :',
 
+# Feedback
+'feedback-subject' => 'Asentel :',
+'feedback-message' => 'Izen :',
+'feedback-cancel' => 'Semmewet',
+'feedback-submit' => 'Ceggaɛ iwenniten',
+'feedback-adding' => 'Rnud iwenniten inek/inem ar usebter...',
+
 # Durations
 'duration-seconds' => '$1 {{PLURAL:$1|tasint|tisinin}}',
 'duration-minutes' => '$1 {{PLURAL:$1|tamrect|timercin}}',
index 33d7793..8c134a2 100644 (file)
@@ -1137,6 +1137,15 @@ IP 주소는 여러 사용자가 공유할 수 있습니다.
 'edit-already-exists' => '새 문서를 만들 수 없습니다.
 그 문서는 이미 존재합니다.',
 'defaultmessagetext' => '기본 메세지 내용',
+'content-failed-to-parse' => '$1 모델에 대한 $2 내용을 구문 분석하는 데 실패했습니다: $3',
+'invalid-content-data' => '잘못된 내용 데이터입니다',
+'content-not-allowed-here' => '"$1" 내용은 [[$2]] 문서예 허용하지 않습니다',
+
+# Content models
+'content-model-wikitext' => '위키텍스트',
+'content-model-text' => '일반 텍스트',
+'content-model-javascript' => '자바스크립트',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''경고:''' 이 문서는 너무 많은 파서 함수를 포함하고 있습니다.
@@ -2619,8 +2628,8 @@ $UNWATCHURL
 'undeletedrevisions' => '판 $1개를 복구했습니다',
 'undeletedrevisions-files' => '판 $1개와 파일 $2개를 복구했습니다.',
 'undeletedfiles' => '파일 $1개를 복구했습니다',
-'cannotundelete' => '복구에 실패했습니다.
-다른 사용자가 이미 복구했을 수도 있습니다.',
+'cannotundelete' => '복구하는 데 실패했습니다:
+$1',
 'undeletedpage' => "'''$1 문서를 복구했습니다.'''
 
 [[Special:Log/delete|삭제 기록]]에서 최근의 삭제와 복구 기록을 볼 수 있습니다.",
@@ -2637,7 +2646,7 @@ $UNWATCHURL
 이미 복구되었을 수 있습니다.',
 'undelete-error' => '문서 복구 중 오류',
 'undelete-error-short' => '파일 복구 오류: $1',
-'undelete-error-long' => '파일을 복구하는  오류가 발생했습니다:
+'undelete-error-long' => '파일을 복구하는 동안 오류가 발생했습니다:
 
 $1',
 'undelete-show-file-confirm' => '정말 "<nowiki>$1</nowiki>" 파일의 삭제된 $2 $3 버전을 보시겠습니까?',
@@ -2930,6 +2939,7 @@ $1 사용자가 차단된 이유는 다음과 같습니다: "$2"',
 'immobile-target-namespace-iw' => '인터위키 링크를 넘어 문서를 이동할 수 없습니다.',
 'immobile-source-page' => '이 문서는 이동할 수 없습니다.',
 'immobile-target-page' => '새 이름으로 옮길 수 없습니다.',
+'bad-target-model' => '원하는 대상은 다른 내용 모델을 사용합니다. $1에서 $2로 변환할 수 없습니다.',
 'imagenocrossnamespace' => '파일을 파일이 아닌 이름공간으로 옮길 수 없습니다.',
 'nonfile-cannot-move-to-file' => '파일이 아닌 문서를 파일 이름공간으로 옮길 수 없습니다.',
 'imagetypemismatch' => '새 파일의 확장자가 원래의 확장자와 일치하지 않습니다.',
index b22f804..a7db1eb 100644 (file)
@@ -939,6 +939,12 @@ Si gouf anscheinend geläscht.",
 'edit-already-exists' => 'Déi nei Säit konnt net ugeluecht ginn, well et se scho gëtt.',
 'defaultmessagetext' => 'Standardtext',
 
+# Content models
+'content-model-wikitext' => 'Wikitext',
+'content-model-text' => 'Kloertext',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Opgepasst:'' Dës Säit huet ze vill Ufroe vu komplexe Parserfunktiounen.
 
@@ -2360,7 +2366,8 @@ An esou Fäll däerf déi neiste Versioun net markéiert ginn oder déi neiste g
 'undeletedrevisions' => '$1 {{PLURAL:$1|Versioun gouf|$1 Versioune goufe}} restauréiert',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 Versioun|$1 Versiounen}} a(n) {{PLURAL:$2|1 Fichier|$2 Fichiere}} goufe restauréiert',
 'undeletedfiles' => '$1 {{PLURAL:$1|Fichier gouf|Fichiere goufe}} restauréiert',
-'cannotundelete' => "D'Restauratioun huet net fonktionéiert. Een anere Benotzer huet déi Säit warscheinlech scho virun iech restauréiert.",
+'cannotundelete' => "D'Restauratioun huet net fonctionnéiert:
+$1",
 'undeletedpage' => "'''$1''' gouf restauréiert.
 
 Am [[Special:Log/delete|Läsch-Logbuch]] fannt Dir déi geläscht a restauréiert Säiten.",
index 526f075..967f98d 100644 (file)
@@ -147,31 +147,34 @@ $messages = array(
 'tog-underline' => 'Сюлмафкснень алга китькстамс:',
 'tog-justify' => 'Тиемс сёрматфть фкакс ушедоматнень лопать кувалмова',
 'tog-hideminor' => 'Од полафтоматнень эса кяшемс ёмланя видептематне',
+'tog-hidepatrolled' => 'Кяшемс лувонь кирдихнень видептемаснон мекольце полафнематнень эса',
+'tog-newpageshidepatrolled' => 'Кяшемс лувонь кирдихнень эса видептьф лопат од лопань лувса',
 'tog-extendwatchlist' => 'Келептемс мельгеваномать сембе полафтоматнень няфтемга, аф аньцек мекольценнет',
-'tog-usenewrc' => 'Ð\9dолдак Ñ\82евÑ\81 Ñ\86ебÑ\8fÑ\80Ñ\8cгоÑ\84Ñ\82Ñ\84 Ð¾Ð´ Ð¸Ð»Ñ\8fкÑ\81Ñ\82опÑ\82омаÑ\82 (Ñ\8dÑ\80Ñ\8fви JavaScript)',
+'tog-usenewrc' => 'Ð\9fолгаÑ\8fÑ\84Ñ\82омÑ\81 Ð¸Ð»Ñ\8fкÑ\81Ñ\82опÑ\82омаÑ\82ненÑ\8c Ð»Ð¾Ð¿Ð°Ð½Ñ\8c ÐºÐ¾Ñ\80Ñ\8fÑ\81 Ð¼ÐµÐºÐ¾Ð»Ñ\8cÑ\86е Ð¿Ð¾Ð»Ð°Ñ\84немаÑ\82ненÑ\8c Ñ\8dÑ\81а Ð´Ð¸ Ð¼ÐµÐ»Ñ\8cгеваномаÑ\81а (веÑ\88и JavaScript)',
 'tog-numberheadings' => 'Сёрмадома коняксс лувомтяшксне эслек путовихть',
 'tog-showtoolbar' => 'Кядьёнкс седяфксть няфтемс сёрмадомбачк (JavaScript)',
 'tog-editondblclick' => 'Кафксть люпштазь сувамс сёрматфть петнема (JavaScript)',
 'tog-editsection' => 'Няфтемс сюлмафксть [петемс] эрь пяльксонди',
 'tog-editsectiononrightclick' => 'Петнемс пялькстне: люпштамс сёрмадомбяльксть лемонц лангс видешире пуняса (JavaScript)',
 'tog-showtoc' => 'Няфтемс сёрматфть потмакс (лопатнень, конатнень эса 3 сёрмадома конякста лама)',
-'tog-rememberpassword' => 'Ð\92анÑ\84Ñ\82омÑ\81 Ð¼Ð¾Ð½Ñ\8c Ñ\81Ñ\83вама Ð»ÐµÐ¼Ð¾Ð·Ðµ Ñ\82Ñ\8f Ñ\81одама Ð¼Ð°Ñ\88инаÑ\81а (for a maximum of $1 {{PLURAL:$1|day|days}})',
-'tog-watchcreations' => 'СÑ\83ваÑ\84Ñ\82омÑ\81 Ð¼Ð¾Ð½Ñ\8c Ñ\82еÑ\84Ñ\82Ñ\8c Ð»Ð¾Ð¿Ð°Ñ\82не Ð¼Ð¾Ð½Ñ\8c мельгеваномазон',
-'tog-watchdefault' => 'СÑ\83ваÑ\84Ñ\82омÑ\81 Ð¼Ð¾Ð½Ñ\8c Ð¿ÐµÑ\82нема Ð»Ð¾Ð¿Ð°Ð½Ðµ Ð¼Ð¾Ð½Ñ\8c мельгеваномазон',
-'tog-watchmoves' => 'Ð\9bопаÑ\82ненÑ\8c Ñ\88аÑ\88Ñ\84Ñ\82омÑ\81Ñ\82а Ñ\81Ñ\83ваÑ\84Ñ\82омÑ\81 Ñ\81инÑ\8c Ð¼Ð¾Ð½Ñ\8c мельгеваномазон',
-'tog-watchdeletion' => 'Ð\9bопаÑ\82ненÑ\8c Ð½Ð°Ñ\80дамÑ\81Ñ\82а Ñ\81Ñ\83ваÑ\84Ñ\82омÑ\81 Ñ\81инÑ\8c Ð¼Ð¾Ð½Ñ\8c мельгеваномазон',
+'tog-rememberpassword' => 'Ð\92анÑ\84Ñ\82омÑ\81 Ð¼Ð¾Ð½Ñ\8c Ñ\81Ñ\83вама Ð»ÐµÐ¼Ð¾Ð·Ðµ Ñ\82Ñ\8f Ñ\81одаммаÑ\88инаÑ\81а (Ñ\81Ñ\8fда ÐºÑ\83ваÑ\82Ñ\8c $1 {{PLURAL:$1|Ñ\88и|Ñ\88иÑ\82}})',
+'tog-watchcreations' => 'СÑ\83ваÑ\84Ñ\82омÑ\81 Ð»Ð¾Ð¿Ð°Ñ\82ненÑ\8c, ÐºÐ¾Ð½Ð°Ñ\82ненÑ\8c Ñ\82иине Ð´Ð¸ Ñ\84айлаÑ\82, ÐºÐ¾Ð½Ð°Ñ\82ненÑ\8c Ñ\82онгине мельгеваномазон',
+'tog-watchdefault' => 'СÑ\83ваÑ\84Ñ\82омÑ\81 Ð»Ð¾Ð¿Ð°Ñ\82ненÑ\8c Ð´Ð¸ Ñ\84айлаÑ\82ненÑ\8c, ÐºÐ¾Ð½Ð°Ñ\82ненÑ\8c Ð¿ÐµÑ\82неÑ\81айне мельгеваномазон',
+'tog-watchmoves' => 'СÑ\83ваÑ\84Ñ\82омÑ\81 Ð»Ð¾Ð¿Ð°Ñ\82ненÑ\8c Ð´Ð¸ Ñ\84айлаÑ\82ненÑ\8c, ÐºÐ¾Ð½Ð°Ñ\82ненÑ\8c Ñ\88аÑ\88Ñ\84Ñ\82Ñ\8bне мельгеваномазон',
+'tog-watchdeletion' => 'СÑ\83ваÑ\84Ñ\82омÑ\81 Ð»Ð¾Ð¿Ð°Ñ\82ненÑ\8c Ð´Ð¸ Ñ\84айлаÑ\82ненÑ\8c, ÐºÐ¾Ð½Ð°Ñ\82ненÑ\8c Ð½Ð°Ñ\80дÑ\8bне мельгеваномазон',
 'tog-minordefault' => 'Тяшксемс сембе петема анцяйнятне мъзярс илякс изь мярьгов',
 'tog-previewontop' => 'Няфтемс сёрматфть васень няфтемать петемань седяфксть инголе',
 'tog-previewonfirst' => 'Васень няфтема васенце петнемада меле',
-'tog-nocache' => 'Ð\90Ñ\84 Ð¼Ñ\8fÑ\80Ñ\8cгома Ð»Ð¾Ð¿Ð°Ñ\82ненÑ\8c Ñ\8dÑ\81лек Ð²Ð°Ð½Ñ\84неви Ñ\84айлÑ\81нон Ñ\82иемÑ\81',
-'tog-enotifwatchlistpages' => 'Кучемс электрононь сёрма монь ванома лопать илякстоптомада меле',
+'tog-nocache' => 'Ð\9aаÑ\80дамÑ\81 Ð¸Ð½Ñ\82еÑ\80неÑ\82Ñ\81 Ð²Ñ\8fÑ\82иенди Ñ\8dÑ\81лек Ð²Ð°Ð½Ñ\84неви Ñ\84айлÑ\85ненÑ\8c Ñ\82иема',
+'tog-enotifwatchlistpages' => 'Кучт тейне е-сёрма мзярда монь мельгеваномаста лопат илякстоптовихть',
 'tog-enotifusertalkpages' => 'Кучемс электрононь сёрма монь тиить корхтама лопанц илякстоптомада меле',
-'tog-enotifminoredits' => 'Кучемс электрононь сёрма нъльне петема анцяйняда меле',
+'tog-enotifminoredits' => 'Кучт тейне е-сёрма нъльне мъзярда лопат эди файлхт аф ламне видептевихть',
 'tog-enotifrevealaddr' => 'Штафтомс монь электрононь адресозе пачфтема сёрмаса',
 'tog-shownumberswatching' => 'Няфтемс мъзяра сувсида конат арафтозь лопать эсь мельгеваномазост',
+'tog-oldsig' => 'Афкуксонь кядьтяшкс',
 'tog-fancysig' => 'Кядьтяшкст улихть викитекстокс (эслек тиеви сюлмафксфтома)',
-'tog-externaleditor' => 'Нолдамс тевс ушеширень петнить мъзярс илякс изь мярьгов (аньцек тевонь содайхненди, сяс мес эрявихть башка кядьёнкст-арафнемат содама машинаса)',
-'tog-externaldiff' => 'Нолдамс тевс ушеширень програм верзиень ваксс путоманкса мъзярс илякс изь мярьгов (аньцек тевонь содайхненди, сяс мес эрявихть башка кядьёнкст-арафнемат содама машинаса)',
+'tog-externaleditor' => 'Нолдамс тевс ушеширень петнить мъзярс илякс изь мярьгов (аньцек тевонь содайхненди, сяс мес эрявихть башка кядьёнкст-арафнемат содама машинаса [//www.mediawiki.org/wiki/Manual:External_editors сяда тов.])',
+'tog-externaldiff' => 'Нолдамс тевс ушеширень програм верзиень ваксс путоманкса мъзярс илякс изь мярьгов (аньцек тевонь содайхненди, сяс мес эрявихть башка кядьёнкст-арафнемат содама машинаса[//www.mediawiki.org/wiki/Manual:External_editors сяда тов.])',
 'tog-showjumplinks' => 'Мярьгомс "юпадемс" сатовома сюлмафкстненди',
 'tog-uselivepreview' => 'Максомс эряй васень няфтемась (JavaScript) (Варжамань)',
 'tog-forceeditsummary' => 'Няфтемс мондине мезе сёрмадомс шава петнема вальмас сувамста',
@@ -180,6 +183,7 @@ $messages = array(
 'tog-watchlisthideminor' => 'Кяшемс петнема анцяйнятне ванома лопаста',
 'tog-watchlisthideliu' => 'Кяшемс сёрматфтф тиихнень петнемаснон мельгеваномаса',
 'tog-watchlisthideanons' => 'Кяшемс лемфтома тиихнень петнемаснон мельгеваномаса',
+'tog-watchlisthidepatrolled' => 'Кяшемс лувонь кирдихнень видептемаснон мельгеваномаса',
 'tog-ccmeonemails' => 'Кучт тейне копия электрононь сермане конатнень кучсайне иля тиихненди.',
 'tog-diffonly' => 'Тят няфте лопань потмоц кафта верзиятнень ваксс путомать ала',
 'tog-showhiddencats' => 'Няфтемс кяшф категориет',
@@ -189,6 +193,13 @@ $messages = array(
 'underline-never' => 'Мъзярдонга',
 'underline-default' => 'Интернет полатксть кадомс апак полафтт',
 
+# Font style option in Special:Preferences
+'editfont-style' => 'Полафтомс тя паксянь сёрмадома стиленц',
+'editfont-default' => 'Интернетс вятись апак полафтт',
+'editfont-monospace' => 'Фкя келеса сёрмадома',
+'editfont-sansserif' => 'Сёрмадома Sans-serif',
+'editfont-serif' => 'Serif сёрмадома',
+
 # Dates
 'sunday' => 'Таргоши (Недляши)',
 'monday' => 'Одговши (Панедельник)',
@@ -256,7 +267,9 @@ $messages = array(
 'category-file-count' => '{{PLURAL:$2|Тя категориеса аньцек фкя файл.|Вага {{PLURAL:$1|файл|$1 файлхт}} тя категориеса $2-нь эста.}}',
 'category-file-count-limited' => 'Вага {{PLURAL:$1|файл|$1 файлхт}} тя категориеса.',
 'listingcontinuesabbrev' => 'полатксоц',
+'index-category' => 'Индексыяф лопат',
 'noindex-category' => '↓Индексфтома лопатне',
+'broken-file-category' => 'Лопат колаф сюлмафкснень мархта',
 
 'about' => 'Колганза',
 'article' => 'Сёрматфть потмонц лопац',
@@ -281,11 +294,13 @@ $messages = array(
 'faqpage' => 'Project:Сидеста Кеподеви Кизефксне',
 
 # Vector skin
+'vector-action-addsection' => 'Поладомс мезень колга корхтамс',
 'vector-action-delete' => 'Нардамс',
 'vector-action-move' => 'Шашфтомс',
 'vector-action-protect' => 'Араламс',
 'vector-action-undelete' => 'Мърдафтомс',
-'vector-action-unprotect' => 'Аралама лоткамс',
+'vector-action-unprotect' => 'Араламать полафтомс',
+'vector-simplesearch-preference' => 'Нодамс тевс тёждялгтотф кядьёнксонь седяфксть (аньцек векторонь лангакс)',
 'vector-view-create' => 'Тиемс',
 'vector-view-edit' => 'Петнемс',
 'vector-view-history' => 'История няфтемс',
@@ -309,6 +324,7 @@ $messages = array(
 'printableversion' => 'Лихтеви верзие',
 'permalink' => 'Ялань сюлмафкс',
 'print' => 'Нолдамс',
+'view' => 'Ваномс',
 'edit' => 'Петнеме',
 'create' => 'Тиемс',
 'editthispage' => 'Петнемс тя лопать',
@@ -316,11 +332,12 @@ $messages = array(
 'delete' => 'Нардамс',
 'deletethispage' => 'Нардамс тя лопать',
 'undelete_short' => 'Мърдафтомс {{PLURAL:$1|петнема|$1 петнемат}}',
+'viewdeleted_short' => 'Ваномс {{PLURAL:$1|фкя нардаф видептема|$1 нардаф видептемат}}',
 'protect' => 'Араламс',
 'protect_change' => 'полафтомс прянь араламать',
 'protectthispage' => 'Араламс тя лопать',
-'unprotect' => 'Ð\92алÑ\85Ñ\82омÑ\81 Ð°Ñ\80аламаÑ\82Ñ\8c',
-'unprotectthispage' => 'Ð\92алÑ\85Ñ\82омÑ\81 Ñ\82Ñ\8f Ð»Ð¾Ð¿Ð°Ñ\82Ñ\8c Ð°Ñ\80аламац',
+'unprotect' => 'Ð\90Ñ\80аламаÑ\82Ñ\8c Ð¿Ð¾Ð»Ð°Ñ\84Ñ\82омÑ\81',
+'unprotectthispage' => 'Ð\9fолаÑ\84Ñ\82омÑ\81 Ñ\82Ñ\8f Ð»Ð¾Ð¿Ð°Ñ\82Ñ\8c Ð°Ñ\80аламанц',
 'newpage' => 'Од лопа',
 'talkpage' => 'Корхтамс тя лопать колга',
 'talkpagelinktext' => 'Корхтама',
@@ -348,6 +365,13 @@ $messages = array(
 'jumpto' => 'Юпадемс тязк:',
 'jumptonavigation' => 'навигацие',
 'jumptosearch' => 'вешендема',
+'view-pool-error' => 'Ужяль, тя пингть серверхнень вийсна аф сатовихть.
+Вельф лама тиихть тяряфнихть ваномс тя лопать.
+Эняльттяма учт аф ламос тя лопанди одукс сама инголе.
+$1',
+'pool-timeout' => 'Пигонь кирдемась учи пякстаманц',
+'pool-queuefull' => 'Тяряфнемада вельф лама',
+'pool-errorunknown' => 'Аф содаф эльбятькс',
 
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
 'aboutsite' => '{{SITENAME}} колга',
@@ -381,6 +405,10 @@ $messages = array(
 'youhavenewmessages' => 'Тонь ули $1 ($2).',
 'newmessageslink' => 'Од сёрмат',
 'newmessagesdifflink' => 'мекольце полафтома',
+'youhavenewmessagesfromusers' => 'Тонь $1 {{PLURAL:$3|тага фкя тиить эзда|$3 тиихнень эзда}} ($2).',
+'youhavenewmessagesmanyusers' => 'Тонь $1 лама тиихнень эзда ($2).',
+'newmessageslinkplural' => '{{PLURAL:$1|од сёрма|од сёрмат}}',
+'newmessagesdifflinkplural' => 'мекольце {{PLURAL:$1|полафнема|полафнемат}}',
 'youhavenewmessagesmulti' => 'Тонь улихть од сёрмат $1-са',
 'editsection' => 'петнемс',
 'editold' => 'петнемс',
@@ -391,6 +419,8 @@ $messages = array(
 'toc' => 'Лопань потмоц',
 'showtoc' => 'няфтемс',
 'hidetoc' => 'кяшемс',
+'collapsible-collapse' => 'Ёмлалгофтомс',
+'collapsible-expand' => 'Келептемс',
 'thisisdeleted' => 'Ваномс эли мърдафтомс $1?',
 'viewdeleted' => 'Ваномс $1?',
 'restorelink' => '{{PLURAL:$1|нардаф петнема|$1 нардаф петнемат}}',
@@ -402,6 +432,8 @@ $messages = array(
 'page-rss-feed' => '"$1" RSS линия',
 'page-atom-feed' => '"$1" Atom линия',
 'red-link-title' => '$1 (стама лопась аш)',
+'sort-descending' => 'Арафтомс алу',
+'sort-ascending' => 'Арафтомс вяри',
 
 # Short words for each namespace, by default used in the namespace tab in monobook
 'nstab-main' => 'Лопа',
@@ -428,12 +460,12 @@ $messages = array(
 # General errors
 'error' => 'Эльбятькс',
 'databaseerror' => 'Датабаза эльбятькс',
-'dberrortext' => 'Ð\94аÑ\82абазанÑ\8c Ð²ÐµÑ\88ендембаÑ\87к Ð»Ð¸Ñ\81Ñ\81Ñ\8c Ñ\81инÑ\82акÑ\81 эльбятькс.
-ТÑ\8f, Ñ\83лема, Ð¿Ñ\80огÑ\80амонÑ\8c Ñ\8dлÑ\8cбÑ\8fÑ\82Ñ\8cкÑ\81.
-Мекольце датабазонь вешендема ульсь:
-<blockquote><tt>$1</tt></blockquote>
-функциеста "<tt>$2</tt>".
\94аÑ\82абазаÑ\81Ñ\8c Ð¼Ñ\8aÑ\80даÑ\84Ñ\82озе Ñ\8dлÑ\8cбÑ\8fÑ\82Ñ\8cкÑ\81Ñ\82Ñ\8c "<tt>$3: $4</tt>".',
+'dberrortext' => 'СодамоÑ\88инÑ\8c Ð¿Ð°Ñ\80ганÑ\8c Ð²ÐµÑ\88ендембаÑ\87к Ð»Ð¸Ñ\81Ñ\81Ñ\8c Ñ\81инÑ\82акÑ\81онÑ\8c эльбятькс.
+ТÑ\8f, Ñ\83лема, Ð¿Ñ\80огÑ\80амгÑ\8fÑ\80Ñ\8cкÑ\81онÑ\8c Ñ\81и.
+Мекольце содамошинь паргань вешема:
+<blockquote><code>$1</code></blockquote>
+функциеста "<code>$2</code>".
¡Ð¾Ð´Ð°Ð¼Ð¾Ñ\88инÑ\8c Ð¿Ð°Ñ\80гаÑ\81Ñ\8c Ð¿Ð°Ñ\87Ñ\84Ñ\82еÑ\81Ñ\8c Ñ\8dлÑ\8cбÑ\8fÑ\82Ñ\8cкÑ\81 "<samp>$3: $4</samp>".',
 'dberrortextcl' => 'Датабазонь вешендембачк лиссь синтакс эльбятькс.
 Мекольце датабазонь вешендема ульсь:
 "$1"
@@ -445,7 +477,7 @@ $messages = array(
 'readonlytext' => 'Датабазась тяни пякстаф од сёрмадоматненди эли полафнематненди, шятьта нежедематненди, меле сон мърдай эрьшинь покаманцты.
 
 Оцюнясь кона сонь пякстазе арьсезе сонь шарьхкотьфтемац: $1',
-'missing-article' => 'Ð\94аÑ\82абазаÑ\81а Ð°Ñ\84 Ð¼Ñ\83ви Ñ\82екÑ\81Ñ\82 конань эряви мумс, сонь лемоц "$1" $2.
+'missing-article' => 'СодамоÑ\88инÑ\8c Ð¿Ð°Ñ\80гÑ\81а Ð°Ñ\84 Ð¼Ñ\83ви Ñ\82екÑ\81Ñ\82Ñ\81Ñ\8c конань эряви мумс, сонь лемоц "$1" $2.
 
 Тя сидеста лиси мъзярда молят сирелготф верзиева эли историянь сюлмафксова, кона вяти нардаф лопас.
 
@@ -456,6 +488,8 @@ $messages = array(
 'readonly_lag' => 'Датабазась эслек пякстась мъзярс кядяла датабаза серверхт сотни прясерверть мархта',
 'internalerror' => 'Потмонь эльбятькс',
 'internalerror_info' => 'Потмонь эльбятькс: $1',
+'fileappenderrorread' => '"$1" файлась аф лувови поладома пингста.',
+'fileappenderror' => '"$1" файлась изь поладов "$2" файлти.',
 'filecopyerror' => 'Аш кода копиямс файл "$1" файл "$2"с.',
 'filerenameerror' => 'Аш кода "$1" файлти максомс од лем "$2".',
 'filedeleteerror' => 'Файл "$1" аф нардави.',
@@ -467,28 +501,43 @@ $messages = array(
 'badarticleerror' => 'Тя лопаса тя аф тиеви.',
 'cannotdelete' => 'Лопась эли кочкаф "$1" файлсь аф нардави.
 Сонь, улема, кинге нардазе ни.',
+'cannotdelete-title' => '"$1" лопась аф нардави',
+'delete-hook-aborted' => 'Туворкс програм петнемать лоткафтозе.
+Пачфтемат тянь коряс аш.',
 'badtitle' => 'Аф кондясти лем',
 'badtitletext' => 'Вешф лопань лемоц аф тяфтама эли шава, шятьта кялень-ётка эли викинь-ётка лемсна аф лац сюлмафт. Сонь эса, улема ащи фкя эли сяда лама башка тяштькстт конат коняксонди аф кондястихть.',
-'perfcached' => 'Вешф програмонь информациесь сёрматфоль эслек ванфневи файлхнень эса ди, улема, сирелгодсь. A maximum of {{PLURAL:$1|one result is|$1 results are}} available in the cache.',
-'perfcachedts' => 'Тя програмонь информациесь сёрматфоль эслек ванфневи файлхнень эса ди мекольцеда одонзаф $1. A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.',
+'perfcached' => 'Вешф програмонь информациесь сёрматфоль эслек ванфневи файлхнень эса ди, улема, сирелгодсь. Сяда {{PLURAL:$1|фкя муфкс|$1 муфкст}} эслек ванфневи файлань кярьксса.',
+'perfcachedts' => 'Тя програмонь информациесь сёрматфоль эслек ванфневи файлхнень эса ди мекольцеда одонзаф $1. Сяда {{PLURAL:$4|фкя муфкс|$4 муфкст}} эслек ванфневи файлонь кярьксса.',
 'querypage-no-updates' => 'Тя лопать одонзапне тяни аф тиевихть. Информациесь тяса тяни аф одонзави.',
 'wrong_wfQuery_params' => 'Аф кондясти параметратне функцияса wfQuery()<br />
 Функцие: $1<br />
 Вешфкс: $2',
 'viewsource' => 'Ваномс лисьмоть',
+'viewsource-title' => 'Ванк $1 лисьмаста',
 'actionthrottled' => 'Куроксшись кирьфтаф',
 'actionthrottledtext' => 'Лудна мархта тюрема туфталонкса тя тевть ламоксть тиемась нюрьхконя ётка пингста кардаф. Эняльттяма мърдамс тя тевти мъзярошка минутода меле.',
 'protectedpagetext' => 'Тя лопас сувама пякстаф лопань петнема кардамать сюнеда.',
 'viewsourcetext' => 'Тейть ули кода ваномс эди копиямс тя лопать лисьмоц:',
-'protectedinterface' => 'Тя лопаса ащи лопать ванфонц програмонь текстоц, сон пякстаф кальдяв тевда араламать сюнеда.',
-'editinginterface' => "'''Инголе кардама:''' Тон петнесак лопать конань эса ащи лопать ванфонц програмонь текстоц. Петнематне полафтсазь сонь ванфоц кода сон няеви иля тиихненди. Ётафтома тиеманкса эняльттяма ваномс [//translatewiki.net/wiki/Main_Page?setlang=mdf translatewiki.net] МедиаВикить локализациеть проектть.",
+'viewyourtext' => "Тондейть ули кода тя лопань '''петнематнень''' ваномс ди тиемс копиянснон:",
+'protectedinterface' => 'Тя лопать эса интерфейс текстсь тя викить програмгярксти, сон аралаф кальдяв тиемада.
+Вики ётафтоматнень поладоманди полафнемандивок сувак [//translatewiki.net/ translatewiki.net], MediaWiki локализациень проектти.',
+'editinginterface' => "'''Инголи кардама:''' Тон петнесак лопать конань эса ащи интерфейс текст програмкярьксонди. Петнематне полафтсазь сонь ванфоц, кода сон няеви иля тиихненди. Вики ётафтоматнень поладоманди, полафтомандивок сувак [//translatewiki.net/ translatewiki.net] MediaWiki локализациень проектти.",
 'sqlhidden' => '(SQL вешфкс кяшф)',
 'cascadeprotected' => 'Тя лопать аралазь петнемада сяс мес сон сувафни {{PLURAL:$1|сай лопас, кона путфоль|сай лопас, конат путфольхть}} каскад араламас:
 $2',
 'namespaceprotected' => "Тондейть аф мярьгови петнемс лопатне '''$1''' лепнень мархта.",
+'customcssprotected' => 'Тейть аф мярьгови петнемс CSS лопать, сяс мес потмосонза иля тиить латцеманза.',
+'customjsprotected' => 'Тейть аф мярьгови петнемс JavaScript лопать, сяс мес потмосонза иля тиить латцеманза.',
 'ns-specialprotected' => '{{ns:special}} лепнень мархта лопатне аф петневихть.',
 'titleprotected' => "[[User:$1|$1]] кардазь тя лемсь мархта лопа тиемать.
 Туфталсь ''$2''.",
+'filereadonlyerror' => '"$1" файлась аф полафтови сяс мес "$2" файлонь пърдафкссь аньцек морафтови форматса.
+
+Админць конась сёлгозе кадсь пачфтема: "$3".',
+'invalidtitle-knownnamespace' => 'Аф кондясти лем "$2" лемботмоса ди "$3" текстть эса',
+'invalidtitle-unknownnamespace' => 'Аф кондясти лем $1 лемботмоса ди "$2" текстть эса',
+'exception-nologin' => 'Апак сувак',
+'exception-nologin-text' => 'Тя лопать эли тиемать сатоманди васенда эряви сувамс викис.',
 
 # Virus scanner
 'virus-badscanner' => "Аф кондясти конфигурациесь: аф содаф вирусонь вешендема програмсь: ''$1''",
@@ -507,12 +556,15 @@ $2',
 'yourpassword' => 'Сувама валце:',
 'yourpasswordagain' => 'Сёрматк сувама валце омбоцекс:',
 'remembermypassword' => 'Ванфтомс монь сувама лемозе тя содам машинаса (максимум $1 {{PLURAL:$1|шис|шис}})',
+'securelogin-stick-https' => 'Кадовомс сотфокс HTTPS вельде сувамада меле',
 'yourdomainname' => 'Тонь доменце:',
+'password-change-forbidden' => 'Сувама валхне тя викить эса аф полафтовихть',
 'externaldberror' => 'Лиссь эльбятькс ушеширень датабазонь вельде кемокстакшнембачк эли тондейть аф мярьгови полафнемс тонь ушеширень сёрматфтомацень.',
 'login' => 'Сувама',
 'nav-login-createaccount' => 'Сувама / сёрматфтома',
 'loginprompt' => 'Тондейть эряви нолдамс тевс cookies {{SITENAME}}с суваманди.',
 'userlogin' => 'Сувама / сёрматфтома',
+'userloginnocreate' => 'Сувамс',
 'logout' => 'Лисема',
 'userlogout' => 'Лисема',
 'notloggedin' => 'Апак сувак',
@@ -521,12 +573,18 @@ $2',
 'createaccount' => 'Тиемс од сёрматфтомась',
 'gotaccount' => "Сёрматфтыть ни? '''$1'''.",
 'gotaccountlink' => 'Сувамс',
+'userlogin-resetlink' => 'Сувама эрявикснень юкстайть?',
 'createaccountmail' => 'электрононь сёрма вельде',
+'createaccountreason' => 'Туфтал:',
 'badretype' => 'Сувама валхне тон путыть аф фкат.',
-'userexists' => 'Тя лемсь кой-кие сявозь ни. Эняльттяма, арьсек иля лемсь.',
+'userexists' => 'Тя лемть сявозь ни. 
+Эняльттяма, арьсек эстейть иля.',
 'loginerror' => 'Сувама эльбятькс',
+'createaccounterror' => 'Сёрматфтомась аф тиеви: $1',
 'nocookiesnew' => 'Тиить сёрматфтомаце анок, аньцек тон изеть сува. {{SITENAME}}-са тиихнень содафтоманкса функцие cookies эряви. Тяни тонь содама машинаса функцие cookies кардаф. Эняльттяма нолдамс тевс cookies, меле сувак од эсь тиить лемцень эди сувама валцень мархта.',
 'nocookieslogin' => '{{SITENAME}} лопаса тиихнень содафтоманкса функцие cookies эряви. Тяни тонь содама машинаса функцие cookies кардаф. Эняльттяма нолдамс тевс cookies, меле сувак тага весть.',
+'nocookiesfornew' => 'Тиить сёрматфтомась апак тик сяс мес лисьмонц аф кемокстави.
+Варжак cookies нолдафт эли аф, одонзафтк лопать ди тяряфтт одукс.',
 'noname' => 'Тон изеть пута кемокстаф тиить лемоц.',
 'loginsuccesstitle' => 'Сувамась ётась лац',
 'loginsuccess' => "'''Тон сувать {{SITENAME}}-с кода \"\$1\".'''",
@@ -535,9 +593,12 @@ $2',
 Илякс тондейть эряви [[Special:UserLogin/signup|сёрматфтомс одукс]].',
 'nosuchusershort' => 'Тиись "$1" лемса аш. Ванк, улема, тон сёрмадыть лемть аф лац.',
 'nouserspecified' => 'Тиить лемсь эряви.',
+'login-userblocked' => 'Тиись перяф. Сувама кардаф.',
 'wrongpassword' => 'Сувама валсь сёрматф аф лац. Варжак тага весть.',
 'wrongpasswordempty' => 'Сувама валсь кадовсь апак сёрматк. Сёрматк одукс.',
 'passwordtooshort' => 'Тонь сувама валценди эряви улемс аф {{PLURAL:$1|1 тяшкста|$1 тяшкста}} кържа',
+'password-name-match' => 'Сувама лемце ди сувама сувама валце улемат аф фкат.',
+'password-login-forbidden' => 'Тя сувама лемсь эди сувама валсь кардафт.',
 'mailmypassword' => 'Кучт од сувама вал',
 'passwordremindertitle' => 'Од ёткопингонь сувама валсь {{SITENAME}}с суваманди',
 'passwordremindertext' => 'Кивок (улема, тон IP адресста $1) вешсь од сувама валсь {{SITENAME}} ($4)с суваманди.
@@ -545,6 +606,7 @@ $2',
 
 Улендяряй киге иля кучсь тя вешфксть эли тон мяляфтсак тонь сувама валцень эди тонь тяни аш мяльце сонь полафтома, тят тие мезеге тя пачфтемась самда меле ди киртть тонь ингольдень сувама валцень.',
 'noemail' => '"$1" тиить электрононь адресоц аш.',
+'noemailcreate' => 'Эряви тяштемс афкукс е-парга',
 'passwordsent' => 'Од сувама валсь кучфоль "$1" тиить электрононь адресонцты.
 Сувак сонь кундамда меле.',
 'blocked-mailpassword' => 'Петнемат тиемась тонь IP адрестот кардаф. Сувама валть кемокстама функциес кундама аф мярьгови кальдяв тиемада аралама туфталонкса.',
@@ -560,15 +622,24 @@ $2',
 'noemailprefs' => 'Мъзярс тон ашеть пута тонь электрононь адресце Викить сёрматнень коряс програмсь кодамога сёрмат аф кучсыне.',
 'emailconfirmlink' => 'Кемокстак тонь электрононь адресце',
 'invalidemailaddress' => 'Электрононь адресть аф пьрьняндави сяс сонь аф кондясти электрононь адресоц. Путт кондясти электрононь адресонц эли катк тя паксянять шавакс.',
+'cannotchangeemail' => 'Сёрматфтомать е-паргоц аф полафтови тя викить эса',
+'emaildisabled' => 'Тя лопанди аш кода кучемс е-сёрмат.',
 'accountcreated' => 'Сёрматфтомась тиф',
 'accountcreatedtext' => '$1 тиить сёрматфтомась тиф.',
 'createaccount-title' => 'Сёрматфнемась {{SITENAME}}-с',
 'createaccount-text' => 'Кати-кие тизе сёрматфтомась $2 {{SITENAME}} ($4)-са. "$2" -ть сувама валсь "$3". Тондейть эряви сувамс тозк эди арафтомс од сувама валть.
 
 Улендяряль тя сёрматфтомась эльбятьксокс мезеге тят тие.',
+'usernamehasherror' => 'Тиить лемозонза тяфтама тяшкст аф мярьговихть',
 'login-throttled' => 'Тон улхкомба вельф ламос тяряфнеть сувамс тя сувама валть вельде.
 Эняльттяма, учт аф ламос тага весть тяряфтома инголе.',
+'login-abort-generic' => 'Сувамацень апак тиевсь лац - Валхтф',
 'loginlanguagelabel' => 'Кяль: $1',
+'suspicious-userlogout' => 'Вешфксце лисемс кардафоль сяс мес няеви тянь кучезь колаф интернетс вятиень эли ётка ёкамань сервер вельде.',
+
+# E-mail sending
+'php-mail-error-unknown' => 'Аф содаф эльбятькс PHP сёрмавятемань функциеса.',
+'user-mail-no-addy' => 'Тяряфтыхть кучемс е-сёрма е-паргафтома',
 
 # Change password dialog
 'resetpass' => 'Полафтомс сувама валцень',
@@ -582,10 +653,23 @@ $2',
 'resetpass_forbidden' => 'Сувама валхнень полафтомс аш кода',
 'resetpass-no-info' => 'Тондейть эряви сёрматфтомс тя лопас видеста суваманди.',
 'resetpass-submit-loggedin' => 'Полафтомс сувама валцень',
+'resetpass-submit-cancel' => 'Валхтомс',
 'resetpass-wrong-oldpass' => 'Аф виде ёткопингонь эли тяниень сувама валсь.
 Улема тон полафтыть сувама валце ни эли кучеть вешфкс од ёткопингонь сувама вал кундаманкса.',
 'resetpass-temp-password' => 'Пингонь сувама валсь:',
 
+# Special:PasswordReset
+'passwordreset' => 'Полафтомс сувама валцень',
+'passwordreset-text' => 'Эряви пяшкодемс тя формать е-сёрма сёрматфтомацень колга сявоманди.',
+'passwordreset-legend' => 'Полафтомс сувама валцень',
+'passwordreset-disabled' => 'Сувама валсь аф полафтови тя викить эса.',
+'passwordreset-pretext' => '{{PLURAL:$1||Тяштьк содама пялькснень эзда фкя алу}}',
+'passwordreset-username' => 'Тиить лемоц',
+'passwordreset-domain' => 'Домен:',
+'passwordreset-capture' => 'Ваномс мекольце е-сёрма?',
+'passwordreset-capture-help' => 'Путондярят тяшкс тя паксять эса е-сёрма (пингонь сувама вал мархта) кармай няфтевома кодак кучф тиенди.',
+'passwordreset-emailtitle' => 'Серматфтомать колга {{SITENAME}}са',
+
 # Edit page toolbar
 'bold_sample' => 'Эчке сёрмадома',
 'bold_tip' => 'Эчке сёрмадома',
@@ -675,6 +759,9 @@ $2',
 Тондейть ули кода [[Special:Search/{{PAGENAME}}|вешендемс тя лопать коняксонц]] иля лопава,
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} вешендемс малады лувомава],
 эли [{{fullurl:{{FULLPAGENAME}}|action=edit}} петнемс тя лопать]</span>.',
+'noarticletext-nopermission' => 'Тяни аш текст тя лопаса.
+Тондейть ули кода [[Special:Search/{{PAGENAME}}|вешендемс тя лопать коняксонц]] иля лопава,
+<span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} вешендемс малады лувомава]</span>, аньцек тонь аш мярьговомаце тя лопать ушедомс.',
 'userpage-userdoesnotexist' => 'Сёрматфтомась «<nowiki>$1</nowiki>» лемса аш. Арьсек лацкаста, афкукс тонь улендяряй мяльце тиемс эли полафтомс тя лопать.',
 'clearyourcache' => "'''Шарфтк мяльце:''' Ванфтомада меле од полафнематнень ваноманкса тондейть эряви нардамс эслек ванфневи файлхнень тонь интернет полатксонь вальмастонза. '''Mozilla / Firefox / Safari:''' ''Shift'' кирдезь, люпштак ''Reload'', эли люпштак ''Ctrl-Shift-F5'' эли ''Ctrl-R'' (''Command-Shift-R'' Mac машинаса); '''Konqueror: '''люпштак ''Reload'' эли люпштак ''F5;'' '''Opera:''' програмса тондейть эрявксты нардамс сембе эслек ванфневи файлхт  ''Tools→Preferences'' вельде; '' '''Internet Explorer:''' ''Ctrl'' кирдезь люпштакшнек ''Refresh'' эли люпштак ''Ctrl-F5.''",
 'usercssyoucanpreview' => "'''Мялень максома:''' Ванфтомада инголе нолдак тевс 'Васень няфтема' пунять тонь од CSS эли JS файлть варжаманкса.",
@@ -684,7 +771,7 @@ $2',
 'userinvalidcssjstitle' => "'''Инголе мярьгома:''' Аш тема файл \"\$1\" мазопнеманкса. Киртть мяльсот .css эди .js лопас путови аньцек ёмла тяшкса коняксне, кепотьксонди {{ns:user}}:Foo/лем.css афи {{ns:user}}:Foo/Лем.css.",
 'updated' => '(Одонзаф)',
 'note' => "'''Шарфтк мяльце:'''",
-'previewnote' => "'''ТÑ\8f Ð°Ð½Ñ\8cÑ\86ек Ð²Ð°Ñ\81енÑ\8c Ð½Ñ\8fÑ\84Ñ\82емаÑ\81Ñ\8c; Ð¿Ð¾Ð»Ð°Ñ\84немаÑ\82не Ð½Ð¸Ð½Ð³Ðµ Ð¸Ñ\81Ñ\82Ñ\8c Ð²Ð°Ð½Ñ\84Ñ\82ов!'''",
+'previewnote' => "'''Ð\9aиÑ\80Ñ\82Ñ\82Ñ\8c Ð¼Ñ\8fлÑ\8cÑ\81оÑ\82, Ñ\82Ñ\8f Ð°Ð½Ñ\8cÑ\86ек Ð²Ð°Ñ\81енÑ\8c Ð½Ñ\8fÑ\84Ñ\82емаÑ\81Ñ\8c.''' Ð¢Ð¾Ð½Ñ\8c Ð¿Ð¾Ð»Ð°Ñ\84Ñ\82омаÑ\82не Ð½Ð¸Ð½Ð³Ðµ Ð¸Ñ\81Ñ\82Ñ\8c Ð²Ð°Ð½Ñ\84Ñ\82ов!",
 'previewconflict' => 'Текстсь тя васень няфтемаса няфтеви вярдень петнема паксяса стамкс кодамкс сон няеволь ванфтомада меле.',
 'session_fail_preview' => "'''Аш кода тонь петнемаце сувафтомс мекольце информациень юмафтомать сюнеда.
 Тик одукс.
@@ -756,6 +843,7 @@ $2',
 'edit-no-change' => 'Тонь петнемацень тевс изь нолда, сяс мес тон текстть ашеть полафта.',
 'edit-already-exists' => 'Аш кода од лопа ушедомс.
 Тя лопась ульсь ни.',
+'content-failed-to-parse' => 'Аш кода $2 сёрматфть нолдамс тевс $1 моделень коряс: $3',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Инголе кардама: Тя лопаса пяк лама питни синтаксонь анализаторхнень тяшкста.
@@ -801,6 +889,7 @@ $3 макссь туфталсь - ''$2''",
 Шарьхкотьфтема: (тян.) = тяниень верзиеда явомась,
 (сяд.) = сядынгольдень верзияда явомась, Ё = ёмла петнема.',
 'history-fieldset-title' => 'Вешентть история',
+'history-show-deleted' => 'Аньцек нардаф',
 'histfirst' => 'Кунардонь',
 'histlast' => 'Мекольце',
 'historysize' => '({{PLURAL:$1|1 байт|$1 байтт}})',
@@ -847,6 +936,8 @@ $3 макссь туфталсь - ''$2''",
 'revdelete-success' => "'''Верзиеть няевоманц одонзафозь лац.'''",
 'logdelete-success' => "'''Сёрматфть няевомац арафтовсь лац.'''",
 'revdel-restore' => 'Полафтомс няевомац',
+'revdel-restore-deleted' => 'нардаф верзиет',
+'revdel-restore-visible' => 'няеви верзиет',
 'pagehist' => 'Лопать историяц',
 'deletedhist' => 'Нардаф историяц',
 'revdelete-edit-reasonlist' => 'Петнемс нардамань туфталхне',
@@ -888,12 +979,12 @@ $3 макссь туфталсь - ''$2''",
 'mergelogpagetext' => 'Ванк ала сяда мекольдень лопатнень фкя фкянь мархта шоворемаснон историясна.',
 
 # Diffs
-'history-title' => '"$1"-нь верзиетнень историясна',
+'history-title' => '"$1"нь полафнематнень историясна',
 'difference-multipage' => 'Явомась лопаланготнень ёткова',
 'lineno' => 'Кикссь $1:',
 'compareselectedversions' => 'Путомс кочкаф верзиетнень ваксс',
 'editundo' => 'валхтомс',
-'diff-multi' => '({{PLURAL:$1|$1-нь ётконь верзиец изь няфтев|$1-нь ётконь верзиенза исть няфтев}}.)',
+'diff-multi' => '({{PLURAL:$1|ёткопингонь верзие, конась|$1 ёткопингонь верзиет, конатне}} {{PLURAL:$2|тии тизе|$2 тиихть тизь}} апак няфтек)',
 
 # Search results
 'searchresults' => 'Мезе мувсь',
@@ -908,6 +999,9 @@ $3 макссь туфталсь - ''$2''",
 'notextmatches' => 'Лопаса сёрматфсь изь мув',
 'prevn' => 'сядынголень {{PLURAL:$1|$1}}',
 'nextn' => 'сай {{PLURAL:$1|$1}}',
+'prevn-title' => 'Сядынгольдень $1 {{PLURAL:$1|сафкс|сафкст}}',
+'nextn-title' => 'Сядомелень $1 {{PLURAL:$1|сафкс|сафкст}}',
+'shown-title' => 'Няфтемс лопасонза $1 {{PLURAL:$1|сафкс|сафкст}}',
 'viewprevnext' => 'Ваномс ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-legend' => 'Вешендема арафнематне',
 'searchmenu-exists' => "'''Тя Викиса ули лопась \"[[:\$1]]\" лем мархта'''",
@@ -925,6 +1019,7 @@ $3 макссь туфталсь - ''$2''",
 'searchprofile-everything-tooltip' => 'Вешендемс сембе лопаса (корхнема лопат сявомок)',
 'searchprofile-advanced-tooltip' => 'Вешендемс кърдань лемботмова',
 'search-result-size' => '$1 ({{PLURAL:$2|1 вал|$2 валхт}})',
+'search-result-category-size' => '{{PLURAL:$1|1 якай|$1 якайхть}} ({{PLURAL:$2|1 субкатегорие|$2 субкатегориет}}, {{PLURAL:$3|1 файла|$3 файлат}})',
 'search-result-score' => 'Малавиксши: $1%',
 'search-redirect' => '(шашфтт $1с)',
 'search-section' => '(пялькс $1)',
@@ -938,6 +1033,7 @@ $3 макссь туфталсь - ''$2''",
 'searchall' => 'сембе',
 'showingresults' => "Ала няфтеви {{PLURAL:$1|мувсь '''1'''|мувсть '''$1'''}} '''$2'''-ста ушедомс.",
 'showingresultsnum' => "Ала няфтеви {{PLURAL:$3|мувсь '''1'''|мувсть '''$3'''}} '''$2'''-ста ушедомс.",
+'showingresultsheader' => "{{PLURAL:$5|'''$1''' сафкс '''$3'''-ста|'''$1 - $2''' сафкст '''$3'''-ста}} '''$4'''нди",
 'nonefound' => "'''Шарфтк мяльце''': Аньцек мъзярошка лемботмат вешендевихть инголе апак полафтт. Тяряфтт вешендема валда инголе путомс ''all:'' сембе потмонь вешендеманди (корхнема лопат ди шаблотт сявомок, ди с. т) эли кундак эрявикс лемботмос кода валынгольксс.",
 'search-nonefound' => 'Аш вешфксонди малады муфкст.',
 'powersearch' => 'Сядонга вешендемс',
@@ -1030,6 +1126,7 @@ $3 макссь туфталсь - ''$2''",
 'email' => 'Электрононь адресце',
 'prefs-help-realname' => 'Афкуксонь лемце путомась аф лувови эрявикс. Афкуксонь лемцень тязк путомада меле тонь лемце кармай эвондама лопаса тонь петнемацень ала.',
 'prefs-help-email' => 'Электрононь адресце тяса аф лувови эрявикс, интай юкстандярят сувама валце адресце путомась лезды сонь полафтоманди.',
+'prefs-help-email-others' => 'Тондейть ули кода путомс корхнема лопазот е-паргцень, конань вельде иля ломатне сёрмадовихть тейть. Е-паргце аф кармай няеви мзярда иля тиихне тяшнелихть тейть.',
 'prefs-help-email-required' => 'Эряви электрононь адресце.',
 
 # User rights
@@ -1180,6 +1277,10 @@ $3 макссь туфталсь - ''$2''",
 'recentchanges-legend' => 'Мекольце полафнематнень арафнемасна',
 'recentchanges-summary' => 'Ваномс сяда мекольце Викиса полафнематнень мельге тя лопаса.',
 'recentchanges-feed-description' => 'Ваномс сяда мекольце Викиса полафнематнень мельге тя шудемаса.',
+'recentchanges-label-newpage' => 'Тя видептемась од лопа тись',
+'recentchanges-label-minor' => 'Тя ёмланя видептема',
+'recentchanges-label-bot' => 'Тя видептемась тизе кона-бди робот програм',
+'recentchanges-label-unpatrolled' => 'Тя видептемась ашесь пова патруль ала ни',
 'rcnote' => "Ала {{PLURAL:$1|мекольце '''1''' полафнема|мекольце '''$1''' полафнемат}} '''$2''' ётай  {{PLURAL:$2|шис|шис}}, $5, $4ста.",
 'rcnotefrom' => "Ала няфтезь полафнематне '''$2'''-ста ('''$1'''-с).",
 'rclistfrom' => 'Няфтемс од полафнематне $1-ста ушедомс',
@@ -1344,7 +1445,7 @@ $3 макссь туфталсь - ''$2''",
 'filehist-dimensions' => 'Кувалма',
 'filehist-filesize' => 'Файлонь кувалмоц',
 'filehist-comment' => 'Мяльполаткс',
-'imagelinks' => 'Файл сюлмафкст',
+'imagelinks' => 'Файлань тевс нолнема',
 'linkstoimage' => 'Сай {{PLURAL:$1|лопась сюлмаф|$1 лопатне сюлмафт}} вага тя файлть мархта:',
 'linkstoimage-more' => '$1-да лама {{PLURAL:$1|лопа сюлмаф|лопат сюлмафт}} тя файлть мархта.
 Тя лувомаса няфневихть {{PLURAL:$1|васенце лопань сюлмафксоц|васенце $1 лопань сюлмафкссна}} аньцек тя файлть мархта.
@@ -1353,6 +1454,8 @@ $3 макссь туфталсь - ''$2''",
 'morelinkstoimage' => 'Ванк [[Special:WhatLinksHere/$1|сяда лама сюлмафкст]] тя файлонди.',
 'duplicatesoffile' => 'Сай {{PLURAL:$1|файлсь ащи кафонзафксокс|$1 файлхне ащихть кафонзафксокс}} тя файлонди ([[Special:FileDuplicateSearch/$2|сяда лама информацие]]):',
 'sharedupload' => 'Тя файлсь $1ста ди сонь ули кода сувафтомс иля проектс.',
+'sharedupload-desc-here' => 'Тя файлась $1ста ди сонь ули кода сувафтомс иля проектс.
+Колганза тяштьф [$2 файлать азондома лопазонза] конась няфтеви ала.',
 'uploadnewversion-linktext' => 'Тонгодемс тя файлонь од верзиенц',
 
 # File reversion
@@ -1493,6 +1596,7 @@ $3 макссь туфталсь - ''$2''",
 'listusers' => 'Тиихне',
 'listusers-editsonly' => 'Няфтемс аньцек петнематнень мархта тиихнень',
 'usereditcount' => '$1 {{PLURAL:$1|петнема|петнемат}}',
+'usercreated' => '{{GENDER:$3|Шкаф}} $1 шиста $2 пингста',
 'newpages' => 'Од лопат',
 'newpages-username' => 'Тиить лемоц:',
 'ancientpages' => 'Сембода сире лопат',
@@ -1617,6 +1721,7 @@ $3 макссь туфталсь - ''$2''",
 # Watchlist
 'watchlist' => 'Монь мельгеваномазе',
 'mywatchlist' => 'Монь мельгеваномазе',
+'watchlistfor2' => '$1 $2-нди',
 'nowatchlist' => 'Мезеге аш тонь мельгеваномасот.',
 'watchlistanontext' => '$1 тонь ванома мельгеваномаста лопат ваноманкса эли петнеманкса.',
 'watchnologin' => 'Апак сувак',
@@ -1698,6 +1803,7 @@ $UNWATCHURL
 'confirmdeletetext' => 'Тон сърхкать нардамс лопать сембе сонь историянц мархта.
 Эняльттяма, кемокстак тон афкукс ёрат тянь тиемс, эди тон шарьхкодьсак мезе лиси тяда меле, ди тон сембе тянь тисак [[{{MediaWiki:Policy-url}}|политик]] коряс.',
 'actioncomplete' => 'Тевонь тиемась анок',
+'actionfailed' => 'Тиемась изь лисе',
 'deletedtext' => 'Лопась "$1" нардафоль. Ванк $2 мекольце нардаматнень няфтеманкса.',
 'dellogpage' => 'Нардамань лувома',
 'dellogpagetext' => 'Ватт сяда мекольце нардаматнень лувомась ала.',
@@ -1810,6 +1916,7 @@ $UNWATCHURL
 'undelete-nodiff' => 'Сядынгольдень верзиет исть мув.',
 'undeletebtn' => 'Мърдафтомс',
 'undeletelink' => 'ваномс/мърдафтомс',
+'undeleteviewlink' => 'ваномс',
 'undeletereset' => 'Валхтомс',
 'undeleteinvert' => 'Валхтомс кочкама',
 'undeletecomment' => 'Мяльполаткс:',
@@ -1856,10 +1963,13 @@ $1',
 'sp-contributions-newbies-title' => 'Тиить путксонза од сёрматфтоматненди',
 'sp-contributions-blocklog' => 'Сёлгомань лувомась',
 'sp-contributions-deleted' => 'нардаф тиинь путксонза',
+'sp-contributions-uploads' => 'Тонгодемат',
+'sp-contributions-logs' => 'Сувама лувомат',
 'sp-contributions-talk' => 'корхтама',
 'sp-contributions-userrights' => 'тиинь видекснень вятема',
 'sp-contributions-search' => 'Вешендемс путкст',
 'sp-contributions-username' => 'IP адрес эли тиить лемоц:',
+'sp-contributions-toponly' => 'Няфтемс аньцек мекольце верзиетнень ёткса видептематне',
 'sp-contributions-submit' => 'Вешендема',
 
 # What links here
@@ -2087,6 +2197,8 @@ $1',
 'allmessagestext' => 'Тя MediaWiki-са васьфневи системонь пачфтематнень лувомась.
 Эняльттяма, сувак [//www.mediawiki.org/wiki/Localisation MediaWiki Локализациес] ди [//translatewiki.net translatewiki.net-с] кда тонь мяльце тиемс эсь путксце марстонь MediaWiki локализациес.',
 'allmessagesnotsupportedDB' => "Тя лопас аш кода кунцемс сяс мес '''\$wgUseDatabaseMessages'''лоткафоль.",
+'allmessages-language' => 'Кяль:',
+'allmessages-filter-submit' => 'Ётамс',
 
 # Thumbnails
 'thumbnail-more' => 'Оцюлгофтомс',
@@ -2094,8 +2206,11 @@ $1',
 'thumbnail_error' => 'Миниатюр тиема эльбятькс: $1',
 'djvu_page_error' => 'DjVu лопась аф сатови',
 'djvu_no_xml' => 'Аш кода латцемс XML DjVu файлти',
+'thumbnail-temp-create' => 'Пингонь миниатюрац аф тиеви',
+'thumbnail-dest-create' => 'Миниатюрась аф ванфтови коза эряви',
 'thumbnail_invalid_params' => 'Аф кондясти миниатюронь арафнеманза',
 'thumbnail_dest_directory' => 'Аш кода ушедомс од вастонь директориесь',
+'thumbnail_image-type' => 'Тя няйфкс форматсь аф нежедеви',
 
 # Special:Import
 'import' => 'Таргамс лопат',
@@ -2105,14 +2220,17 @@ $1',
 Сембе ётковикинь таргама тефне тяшневихть [[Special:Log/import|таргамань лувомас]].',
 'import-interwiki-source' => 'Вики лисьма/лопа:',
 'import-interwiki-history' => 'Копияфтомс тя лопать сембе историянь верзиенза',
+'import-interwiki-templates' => 'Сувафтомс сембе шаблотт',
 'import-interwiki-submit' => 'Таргамс',
 'import-interwiki-namespace' => 'Пачфтема лемботма:',
+'import-interwiki-rootpage' => 'Ёнонь юрлопась (кочкамать коряс):',
 'import-upload-filename' => 'Файллем:',
 'import-comment' => 'Мяльполаткс:',
-'importtext' => 'Эняльттяма таргак файлть Вики лисьмостонза [[Special:Export|вима лезкссь]] тевс нолдазь, ванфтт тянь тонь содама машинаса ди тонк тязк.',
+'importtext' => 'Эняльттяма таргак файлать Вики лисьмостонза [[Special:Export|вима лезкссь]]. Ванфтк содама машиназот ди тонк тяза.',
 'importstart' => 'Лопатне тарксевихть...',
 'import-revision-count' => '$1 {{PLURAL:$1|илякстоптома|илякстоптомат}}',
 'importnopages' => 'Ашет лопат таргаманди.',
+'imported-log-entries' => 'Таргак $1 {{PLURAL:$1|лувонь тяштема|лувонь тяштемат}}.',
 'importfailed' => 'Таргамась колавсь: <nowiki>$1</nowiki>',
 'importunknownsource' => 'Аф содаф таргама лисьмоть сортоц',
 'importcantopen' => 'Аш кода панжемс таргама файлть',
@@ -2132,6 +2250,12 @@ $1',
 'import-upload' => 'Тонгомс XML информациесь',
 'import-token-mismatch' => 'Сессиянь нформациесь юмась. Тяряфтт тага весть.',
 'import-invalid-interwiki' => 'Аш кода таргамс кочкаф Викить.',
+'import-error-edit' => '"$1" лопась апак тонк сяс мес тейть аф мярьгови петеманза.',
+'import-error-create' => '"$1" лопась апак тонк сяс мес тейть аф мярьгови тиеманза.',
+'import-error-interwiki' => '"$1" лопась апак тонк сяс мес лемоц ванфтфоль ушеширень сюлмаманди (interwiki).',
+'import-error-special' => '"$1" лопась апак тонк сяс мес сон башка лемботмоса, конаса лопат кардафт.',
+'import-error-invalid' => '"$1" лопась апак тонк сяс мес лемоц аф кондясти.',
+'import-options-wrong' => 'Аф виде {{PLURAL:$2|кочкама|кочкамат}}: <nowiki>$1</nowiki>',
 
 # Import log
 'importlogpage' => 'Таргамань лувома',
@@ -2205,6 +2329,7 @@ $1',
 'tooltip-rollback' => '"Потафтфкс" мърдафтсыне петнематне мекольце тиинь путксонц лопазонза фкя люпштамас.',
 'tooltip-undo' => '"Каряньфтема" мърдафтсыне тя петнемать эди панжесы петнема форм васень няфтемаса.
 Лезни поладомс туфталхт лихтемать эс.',
+'tooltip-summary' => 'Тяштьк нюрьхкяняста сувафтфть колга',
 
 # Metadata
 'notacceptable' => 'Вики серверонди аш кода максомс информациесь стама форматса конань эса тонь клиентти ули кода сонь морафтомс.',
@@ -2765,6 +2890,9 @@ $5
 
 #Путт сембе васу валзюлмафксонь пакшензон тя луфть (строкать) вельфке. Катт тя луфть (строкать) стамкс кодамкс сон ульсь</pre>',
 
+# Special:Tags
+'tag-filter' => '[[Special:Tags|Tag]] педямась:',
+
 # New logging system
 'revdelete-restricted' => 'нолдаф тевс кардафксне системонь вятиксненди',
 'revdelete-unrestricted' => 'системонь вятиксненди кардафксне валхтфт',
index ec6defb..288f118 100644 (file)
@@ -601,6 +601,7 @@ $2',
 'ns-specialprotected' => "Tsy afaka ovaina ny pejy anatin'ny toeran'anarana « {{ns:special}} » .",
 'titleprotected' => "Voaaron'i [[User:$1|$1]] ity lohateny ity mba tsy hamorona pejy mitondra ity anarana ity.
 Ny antony napetraka dia : « ''$2'' ».",
+'invalidtitle-knownnamespace' => 'Lohateny tsy miady amin\'ny fepetra miaraka amin\'ny anaram-balam-pejy "$2" ary soratra "$3"',
 'exception-nologin' => 'Tsy tafiditra',
 
 # Virus scanner
@@ -697,6 +698,7 @@ mba hanaporofoana fa anao io kaonty io.",
 'invalidemailaddress' => 'Tsy mety io imailaka nalefanao io satria tsy manaraka ny firafitra tokony ho izy.
 Azafady manomeza adiresy voasoratra tsara na avelao ho banga io toerana io.',
 'cannotchangeemail' => "Tsy afaka ovaina eto amin'ity wiki ity ny adiresy imailaky ny kaonty.",
+'emaildisabled' => 'Tsy afaka mandefa imailaka ity tranonkala ity.',
 'accountcreated' => 'Kaonty voaforona',
 'accountcreatedtext' => "Voasokatra ilay kaonty hoan'i $1.",
 'createaccount-title' => "Fanokafana kaonty ho an'ny/i {{SITENAME}}",
@@ -862,7 +864,7 @@ Azonao atao ny [[Special:Search/{{PAGENAME}}||Tadiavo ny momba ny {{PAGENAME}}]]
 * '''[{{SERVER}}{{localurl:{{NAMESPACE}}:{{PAGENAME}}|action=edit}} Na forony eto ny lahatsoratra momba ny {{PAGENAME}}]'''.",
 'noarticletext-nopermission' => "Mbola tsy misy lahatsoratra ao amin'io pejy io.
 
-Azonao atao ny [[Special:Search/{{PAGENAME}}|Mikaroka momba ny lohatenin'io pejy io]] ao amin'ny pejy hafa, mitady <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} anatin'ny laogy mikasika azy]</span>",
+Azonao atao ny [[Special:Search/{{PAGENAME}}|mikaroka ity lohateny ity]] eny amin'ny pejy hafa na <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} mitady ao amin'ny laogy misy fifandraisana]</span>, fa tsy azonao atao ny mamorona ity pejy ity.",
 'userpage-userdoesnotexist' => 'Mbola tsy nisoratra anarana ato i « <nowiki>$1</nowiki> ». Marino raha tena hamorona ity pejy ity ianao.',
 'userpage-userdoesnotexist-view' => 'Tsy nisoratra anarana ato i « $1 ».',
 'blocked-notice-logextract' => "Ankehitriny ity mpikambana ity dia voasakana.
@@ -966,6 +968,7 @@ Mety voafafa angamba izy.',
 'edit-already-exists' => 'Tsy afaka amboarina ilay pejy vaovao.
 Efa misy izy.',
 'defaultmessagetext' => 'Hafatra raha tsy misy',
+'invalid-content-data' => "Data anaty votoatiny tsy miady amin'ny fepetra",
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Tandremo : Betsaka loatra ny fanantsoana ny tao parser.
@@ -1693,10 +1696,12 @@ Raha mbola misy foana ilay  olana, manorata any amin'ny [[Special:ListUsers/syso
 'upload-too-many-redirects' => "Be loatra ny fihodinan'ny URL.",
 'upload-unknown-size' => 'tsy fantatra ny habe',
 'upload-http-error' => 'Nisy tsy fetezana HTTP nitranga : $1',
+'upload-copy-upload-invalid-domain' => "Tsy misy eto amin'ity dômenina ity ny tahaky ny upload.",
 
 # File backend
 'backend-fail-stream' => 'Tsy afaka mamaky ilay rakitra $1.',
 'backend-fail-backup' => 'Tsy afaka mitahiry ilay rakitra $1.',
+'backend-fail-notexists' => 'Tsy misy ilay rakitra $1.',
 'backend-fail-hashes' => "Tsy azo ilay hash an-drakitra ho an'ny fampitahana.",
 'backend-fail-notsame' => "Efa misy rakitra samihafa ho an'i $1",
 'backend-fail-invalidpath' => '$1 dia lalam-pitahirizana tsy azo raisina.',
@@ -1957,6 +1962,7 @@ Aza manadino manamarina raha tsy misy rohy makany amin'ny endrika hafa alohan'ny
 'mostlinkedtemplates' => "Misy firohizana betsaka amin'ny endrika",
 'mostcategories' => 'Lahatsoratra misy sokajy betsaka indrindra',
 'mostimages' => "Misy firohizana betsaka amin'ny sary",
+'mostinterwikis' => 'Pejy be interwiki indrindra',
 'mostrevisions' => 'Lahatsoratra niova im-betsaka indrindra',
 'prefixindex' => "Pejy manomboka amin'ny...",
 'prefixindex-namespace' => 'Ny pejy rehetra mitondra ny tovona (anaran-tsehatra $1)',
@@ -2010,6 +2016,7 @@ wiki ity aza izy.</p>",
 Azonao ferana ny fahitana ny tao amin'ny fisafidianana karazana laogy iray, anaram-pikambana iray na pejy iray (samihafa ny sorabaventy sy soramadinika).",
 'logempty' => 'Tsy nahitana.',
 'log-title-wildcard' => "Hitady amin'ny lohateny manomboka amin'io soratra io",
+'showhideselectedlogentries' => 'Haneho/Hanafina ny iditry ny laogy nofidiana',
 
 # Special:AllPages
 'allpages' => 'Pejy rehetra',
@@ -2027,6 +2034,10 @@ Azonao ferana ny fahitana ny tao amin'ny fisafidianana karazana laogy iray, anar
 'allpagesprefix' => "Asehoy ny pejy miantomboka amin'ny:",
 'allpagesbadtitle' => 'Tsy mety ny anaram-pejy : misy tovona iraisam-piteny na interwiki natokana, na misy soratra iray na maro tsy azo ampiasaina anaty anaram-pejy.',
 'allpages-bad-ns' => '{{SITENAME}} dia tsy manana anaran-tsehatra mitondra anarana « $1 ».',
+'allpages-hide-redirects' => 'Haneho ny fihodinana',
+
+# SpecialCachedPage
+'cachedspecial-refresh-now' => 'Hijery ny farany indrindra',
 
 # Special:Categories
 'categories' => 'Sokajy',
@@ -2089,6 +2100,7 @@ Protokoly zaka <code>$1</code> aza ampiana ao amin'ny karokao izy ireo.",
 'mailnologin' => 'Tsy misy adiresy handefasana ny tenimiafina',
 'mailnologintext' => "Mila [[Special:UserLogin|miditra]] ianao sady manana imailaka mandeha sy voamarina ao amin'ny [[Special:Preferences|mombamomba anao]] vao afaka mandefa imailaka amin'ny mpikambana hafa.",
 'emailuser' => 'Andefaso imailaka io mpikambana io',
+'emailuser-title-notarget' => "Handefa imailaka an'ilay mpikambana",
 'emailpage' => 'Andefaso imailaka io mpikambana io',
 'emailpagetext' => "Raha nametraka adiresy tena miasa tao amin'ny [[Special:Preferences|mombamomba azy io mpikambana io]],
 dia ahafahana mandefa hafatra tokana ho any aminy ity fisy eto ambany ity.
index 0324a11..c531689 100644 (file)
@@ -1142,6 +1142,15 @@ $2
 'edit-already-exists' => 'Не може да се создаде нова страница.
 Истата веќе постои.',
 'defaultmessagetext' => 'Текст на пораката по основно',
+'content-failed-to-parse' => 'Не успеав да ја предадам содржината од типот $2 за моделот $1: $3',
+'invalid-content-data' => 'Неважечки податоци од содржината',
+'content-not-allowed-here' => 'Содржините од моделот „$1“ не се допуштени на страницата [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'викитекст',
+'content-model-text' => 'прост текст',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Предупредување: Оваа страница користи премногу повикувања на parser функции.
@@ -2617,7 +2626,8 @@ $UNWATCHURL
 'undeletedrevisions' => '{{PLURAL:$1|1 измена е обновена|$1 измени се обновени}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 измена|$1 измени}} и {{PLURAL:$2|1 податотека|$2 податотеки}} се вратени',
 'undeletedfiles' => '{{PLURAL:$1|1 податотека е вратена|$1 податотеки се вратени}}',
-'cannotundelete' => 'Враќањето не успеа. Можеби некој друг веќе ја вратил страницата.',
+'cannotundelete' => 'Враќањето не успеа:
+$1',
 'undeletedpage' => "'''$1 беше обновена'''
 
 Погледнете го [[Special:Log/delete|дневникот на бришења]] за попис на претходни бришења и обновувања.",
@@ -2926,6 +2936,7 @@ $1',
 'immobile-target-namespace-iw' => 'Меѓувики-врска не може да се користи за преименување на страници.',
 'immobile-source-page' => 'Оваа страница не може да се преместува.',
 'immobile-target-page' => 'Не може да се премести под бараниот наслов.',
+'bad-target-model' => 'Саканата одредница користи друг содржински модел. Не можам да претворам од $1 во $2.',
 'imagenocrossnamespace' => 'Не може да се премести податотека во неподатотечен именски простор',
 'nonfile-cannot-move-to-file' => 'Не можам да преместам неподатотека во податотечен именски простор',
 'imagetypemismatch' => 'Новата наставка на податотеката не соодветствува на нејзиниот тип',
index 0266cbc..097e531 100644 (file)
@@ -1076,6 +1076,15 @@ $1 ആണ് ഈ തടയൽ നടത്തിയത്. ''$2'' എന്ന
 'edit-already-exists' => 'പുതിയ താൾ സൃഷ്ടിക്കാൻ കഴിഞ്ഞില്ല.
 താൾ ഇപ്പോൾ തന്നെ നിലവിലുണ്ട്.',
 'defaultmessagetext' => 'സ്വതേയുള്ള സന്ദേശ എഴുത്ത്',
+'content-failed-to-parse' => '$2 ഉള്ളടക്കം $1 മാതൃകയിൽ പാഴ്സ് ചെയ്യൽ പരാജയപ്പെട്ടു: $3',
+'invalid-content-data' => 'അസാധുവായ ഉള്ളടക്ക ഡേറ്റ',
+'content-not-allowed-here' => '"$1" ഉള്ളടക്കം [[$2]] താളിൽ അനുവദിക്കുന്നില്ല',
+
+# Content models
+'content-model-wikitext' => 'വിക്കിഎഴുത്ത്',
+'content-model-text' => 'ശുദ്ധ എഴുത്ത്',
+'content-model-javascript' => 'ജാവാസ്ക്രിപ്റ്റ്',
+'content-model-css' => 'സി.എസ്.എസ്.',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''മുന്നറിയിപ്പ്:''' ഈ താളിൽ വളരെക്കൂടുതൽ പാഴ്സർ ഫങ്ഷനുകൾ വിളിച്ചിരിക്കുന്നു.
@@ -2515,7 +2524,8 @@ $UNWATCHURL
 'undeletedrevisions' => '{{PLURAL:$1|ഒരു പതിപ്പ്|$1 പതിപ്പുകൾ}} പുനഃസ്ഥാപിച്ചിരിക്കുന്നു',
 'undeletedrevisions-files' => '{{PLURAL:$1|ഒരു പതിപ്പും|$1 പതിപ്പുകളും}} {{PLURAL:$2|ഒരു പ്രമാണവും|$2 പ്രമാണങ്ങളും}} പുനഃസ്ഥാപിച്ചിരിക്കുന്നു',
 'undeletedfiles' => '{{PLURAL:$1|ഒരു പ്രമാണം|$1 പ്രമാണങ്ങൾ}} പുനഃസ്ഥാപിച്ചു',
-'cannotundelete' => 'മായ്ക്കൽ തിരസ്ക്കരിക്കാനുള്ള ശ്രമം പരാജയപ്പെട്ടു. മറ്റാരെങ്കിലും ഇതിനു മുൻപ് മായ്ക്കൽ തിരസ്ക്കരിച്ചിരിക്കാം.',
+'cannotundelete' => 'മായ്ക്കൽ തിരസ്കരണം പരാജയപ്പെട്ടു:
+$1',
 'undeletedpage' => "'''$1 പുനഃസ്ഥാപിച്ചിരിക്കുന്നു'''
 
 പുതിയതായി നടന്ന ഒഴിവാക്കലുകളുടേയും പുനഃസ്ഥാപനങ്ങളുടേയും വിവരങ്ങൾ കാണാൻ [[Special:Log/delete|മായ്ക്കൽ ലോഗ്]] കാണുക.",
@@ -2821,6 +2831,7 @@ $1',
 'immobile-target-namespace-iw' => 'അന്തർവിക്കി കണ്ണി താൾ മാറ്റാനുള്ള സാധുവായ ലക്ഷ്യമല്ല.',
 'immobile-source-page' => 'ഈ താൾ മാറ്റാൻ സാദ്ധ്യമല്ല',
 'immobile-target-page' => 'ലക്ഷ്യമാക്കിയ തലക്കെട്ടിലേക്ക് മാറ്റാൻ സാധിക്കില്ല.',
+'bad-target-model' => 'ആഗ്രഹിക്കുന്ന ലക്ഷ്യം മറ്റൊരു ഉള്ളടക്ക മാതൃകയാണ് ഉപയോഗിക്കുന്നത്. $1 എന്നതിനെ $2 ആക്കി മാറ്റാൻ കഴിയില്ല.',
 'imagenocrossnamespace' => 'പ്രമാണം അതിനായി അല്ലാത്ത നാമമേഖലയിലേയ്ക്ക് മാറ്റാൻ കഴിയില്ല',
 'nonfile-cannot-move-to-file' => 'പ്രമാണമല്ലാത്തവ പ്രമാണം നാമമേഖലയിലേയ്ക്ക് മാറ്റാൻ കഴിയില്ല.',
 'imagetypemismatch' => 'പുതിയ പ്രമാണത്തിന്റെ എക്സ്റ്റെൻഷൻ അതിന്റെ തരവുമായി ഒത്തുപോകുന്നില്ല.',
index f1bed2f..d41d9ea 100644 (file)
@@ -953,6 +953,15 @@ Log penghapusan bagi laman ini dilampirkan di bawah untuk rujukan.',
 'edit-no-change' => 'Suntingan anda diabaikan kerana tiada perubahan dibuat pada teks tersebut.',
 'edit-already-exists' => 'Tidak dapat mencipta laman baru kerana ia telah wujud.',
 'defaultmessagetext' => 'Teks mesej asal',
+'content-failed-to-parse' => 'Kandungan $2 tidak dapat dihuraikan untuk model $1: $3',
+'invalid-content-data' => 'Data kandungan tidak sah',
+'content-not-allowed-here' => 'Kandungan "$1" tidak dibenarkan di halaman [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikiteks',
+'content-model-text' => 'teks biasa',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Amaran: Laman ini mengandungi terlalu banyak panggilan fungsi penghurai yang intensif.
@@ -2408,7 +2417,7 @@ atau semakan tersebut telah dipulihkan atau dibuang daripada arkib.',
 'undeletedrevisions' => '$1 semakan dipulihkan',
 'undeletedrevisions-files' => '$1 semakan dan $2 fail dipulihkan',
 'undeletedfiles' => '$1 fail dipulihkan',
-'cannotundelete' => 'Penyahhapusan gagal; mungkin orang lain telah pun mengnyahhapuskannya.',
+'cannotundelete' => 'Penyahhapusan gagal: $1',
 'undeletedpage' => "'''$1 telah dipulihkan'''
 
 Sila rujuk [[Special:Log/delete|log penghapusan]] untuk rekod penghapusan terkini.",
@@ -2712,6 +2721,7 @@ Laman destinasi "[[:$1]]" telah pun wujud. Adakah anda mahu menghapuskannya supa
 'immobile-target-namespace-iw' => 'Pautan interwiki tidak boleh dijadikan sasaran untuk pemindahan laman.',
 'immobile-source-page' => 'Anda tidak boleh memindahkan laman ini.',
 'immobile-target-page' => 'Anda tidak boleh memindahkan laman ke tajuk itu.',
+'bad-target-model' => 'Destinasi yang dikehendaki menggunakan model kandungan yang berlainan. $1 tidak dapat ditukar kepada $2.',
 'imagenocrossnamespace' => 'Anda tidak boleh memindahkan fail ke ruang nama bukan fail',
 'nonfile-cannot-move-to-file' => 'Laman bukan fail tidak boleh dipindahkan ke ruang nama fail',
 'imagetypemismatch' => 'Sambungan baru fail tersebut tidak sepadan dengan jenisnya',
index 7ed7c6f..ebf9541 100644 (file)
@@ -1088,6 +1088,15 @@ Slette- og flytteloggen vises nedenfor.',
 'edit-no-change' => 'Redigeringen din ble ignorert fordi det ikke var noen endringer.',
 'edit-already-exists' => 'Kunne ikke opprette ny side fordi den finnes fra før.',
 'defaultmessagetext' => 'Standard meldingstekst',
+'content-failed-to-parse' => 'Klarte ikke å tolke innholdet $2 for innholdsmodellen $1: $3',
+'invalid-content-data' => 'Ugyldig innhold',
+'content-not-allowed-here' => 'Innholdsmodellen «$1» er ikke tillatt på siden [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'WikiTekst',
+'content-model-text' => 'Ren tekst',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Advarsel: Denne siden inneholder for mange prosesskrevende parserfunksjoner.
@@ -2527,7 +2536,8 @@ Dersom en ny side ved samme navn har blitt oprettet etter slettingen, vil de gje
 'undeletedrevisions' => '{{PLURAL:$1|Én revisjon|$1 revisjoner}} gjenopprettet',
 'undeletedrevisions-files' => '{{PLURAL:$1|Én revisjon|$1 revisjoner}} og {{PLURAL:$2|én fil|$2 filer}} gjenopprettet',
 'undeletedfiles' => '{{PLURAL:$1|Én fil|$1 filer}} gjenopprettet',
-'cannotundelete' => 'Kunne ikke gjenopprette siden (den kan være gjenopprettet av noen andre).',
+'cannotundelete' => 'Gjennoppretting feilet:
+$1',
 'undeletedpage' => "'''$1 ble gjenopprettet'''
 
 Sjekk [[Special:Log/delete|slettingsloggen]] for en liste over nylige slettinger og gjenopprettelser.",
@@ -2828,6 +2838,7 @@ Målsiden «[[:$1]]» finnes allerede. Vil du slette den så denne siden kan fly
 'immobile-target-namespace-iw' => 'Du kan ikke flytte en side til et navn som er en interwikilenke.',
 'immobile-source-page' => 'Denne siden kan ikke flyttes.',
 'immobile-target-page' => 'Kan ikke flytte til det navnet.',
+'bad-target-model' => 'Det ønskede målet bruker en annen innholdsmodell. Kan ikke konvertere fra $1 til $2.',
 'imagenocrossnamespace' => 'Kan ikke flytte filer til andre navnerom enn filnavnerommet',
 'nonfile-cannot-move-to-file' => 'Kan ikke flytte ikke-filer til filnavnerom',
 'imagetypemismatch' => 'Den nye filendelsen tilsvarer ikke filtypen',
index 40952c6..bc68ac8 100644 (file)
@@ -42,6 +42,7 @@
  * @author Trijnstel
  * @author Troefkaart
  * @author Tvdm
+ * @author Wiki13
  * @author לערי ריינהארט
  */
 
@@ -1154,6 +1155,12 @@ Deze lijkt verwijderd te zijn.',
 Deze bestaat al.',
 'defaultmessagetext' => 'Standaardinhoud',
 
+# Content models
+'content-model-wikitext' => 'wikitekst',
+'content-model-text' => 'platte tekst',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Waarschuwing:''' deze pagina gebruikt te veel kostbare parserfuncties.
 
@@ -2641,8 +2648,8 @@ Mogelijk hebt u een verkeerde verwijzing of is de versie hersteld of verwijderd
 'undeletedrevisions' => '$1 {{PLURAL:$1|versie|versies}} teruggeplaatst',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 versie|$1 versies}} en {{PLURAL:$2|1 bestand|$2 bestanden}} teruggeplaatst',
 'undeletedfiles' => '{{PLURAL:$1|1 bestand|$1 bestanden}} teruggeplaatst',
-'cannotundelete' => 'Het terugplaatsen is mislukt.
-Misschien heeft een andere gebruiker de pagina al teruggeplaatst.',
+'cannotundelete' => 'Het terugplaatsen is mislukt:
+$1',
 'undeletedpage' => "'''$1 is teruggeplaatst'''
 
 In het [[Special:Log/delete|verwijderingslogboek]] staan recente verwijderingen en herstelhandelingen.",
index 9768664..47ceef3 100644 (file)
@@ -18,6 +18,7 @@
  * @author Guttorm Flatabø
  * @author H92
  * @author Harald Khan
+ * @author Jeblad
  * @author Jon Harald Søby
  * @author Jorunn
  * @author Kaganer
@@ -1024,7 +1025,7 @@ Det siste loggelementet er oppgjeve under som referanse:",
 Det siste loggelementet er oppgjeve under som referanse:",
 'templatesused' => '{{PLURAL:$1|Mal|Malar}} som er brukte på denne sida:',
 'templatesusedpreview' => '{{PLURAL:$1|Mal som er brukt|Malar som er brukte}} i førehandsvisinga:',
-'templatesusedsection' => '{{PLURAL:$1|Mal|Malar}} som er brukte i denne bolken:',
+'templatesusedsection' => '{{PLURAL:$1|Mal som er brukt|Malar som er brukte}} i denne bolken:',
 'template-protected' => '(verna)',
 'template-semiprotected' => '(delvis verna)',
 'hiddencategories' => 'Denne sida er med i {{PLURAL:$1|éin gøymd kategori|$1 gøymde kategoriar}}:',
@@ -1042,7 +1043,7 @@ Du kan gå attende og endre ei eksisterande side, [[Special:UserLogin|logge inn
 
 Du bør tenkje over om det er høveleg å halde fram med å endre denne sida.
 Sletteloggen for sida finn du her:",
-'moveddeleted-notice' => 'Denne sida er vorten sletta. Sletteloggen og flytteloggen er vist nedanfor for referanse.',
+'moveddeleted-notice' => 'Sida er vorten sletta. Sletteloggen og flytteloggen er viste nedanfor for referanse.',
 'log-fulllog' => 'Sjå full loggføring',
 'edit-hook-aborted' => 'Endring avbroten av ein funksjon, utan forklaring.',
 'edit-gone-missing' => 'Kunne ikkje oppdatere sida.
@@ -1051,6 +1052,15 @@ Det ser ut til at ho er sletta.',
 'edit-no-change' => 'Redigeringa di vart ignorert fordi det ikkje vart gjort endringar i teksten.',
 'edit-already-exists' => 'Kunne ikkje opprette ny side fordi ho alt eksisterer.',
 'defaultmessagetext' => 'Standard meldingstekst',
+'content-failed-to-parse' => 'Klarte ikkje å tolke innhaldet «$2» for innhaldsmodellen «$1»: $3',
+'invalid-content-data' => 'Ugyldig innhald',
+'content-not-allowed-here' => 'Innhaldsmodellen «$1» er ikkje tillaten på sida [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'WikiTekst',
+'content-model-text' => 'Rein tekst',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Åtvaring: Denne sida inneheld for mange prosesskrevande parserfunksjonar.
@@ -1679,7 +1689,7 @@ For å bruke ei fil på ei side, bruk ei lenkje på eit liknande format:
 'filestatus' => 'Opphavsrettsstatus:',
 'filesource' => 'Kjelde:',
 'uploadedfiles' => 'Filer som er opplasta',
-'ignorewarning' => 'Oversjå åtvaringa og lagre fila',
+'ignorewarning' => 'Sjå bort frå åtvaringa og lagre fila likevel',
 'ignorewarnings' => 'Oversjå åtvaringar',
 'minlength1' => 'Filnamn må ha minst eitt teikn.',
 'illegalfilename' => 'Filnamnet «$1» inneheld teikn som ikkje er tillatne i sidetitlar. Skift namn på fila og prøv på nytt.',
@@ -2084,7 +2094,7 @@ Merk at andre internettsider kan ha direkte lenkjer til filer, og difor kan file
 'log' => 'Loggar',
 'all-logs-page' => 'Alle offentlege loggar',
 'alllogstext' => 'Kombinert vising av alle loggane på {{SITENAME}}. Du kan avgrense resultatet ved å velje loggtype, brukarnamn eller den sida som er påverka (hugs å skilje mellom store og små bokstavar)',
-'logempty' => 'Ingen treff i loggane.',
+'logempty' => 'Ingen element i loggen passar.',
 'log-title-wildcard' => 'Søk i titlar som byrjar med denne teksten',
 'showhideselectedlogentries' => 'Vis/gøym valde loggoppføringar',
 
@@ -2231,21 +2241,22 @@ Om du seinare vil fjerne sida frå overvakingslista, klikk på «Fjern overvakin
 'watchnochange' => 'Ingen av sidene i overvakingslista er endra i den valde perioden.',
 'watchlist-details' => '{{PLURAL:$1|Éi side|$1 sider}} er overvaka, utanom diskusjonssider.',
 'wlheader-enotif' => '* Funksjonen for endringsmeldingar per e-post er på.',
-'wlheader-showupdated' => "* Sider som har blitt endra sidan du sist såg på dei er '''utheva'''",
+'wlheader-showupdated' => "* Sider som har vorte endra sidan du sist såg på dei er '''utheva'''",
 'watchmethod-recent' => 'sjekkar siste endringar for dei overvaka sidene',
 'watchmethod-list' => 'sjekkar om dei overvaka sidene har blitt endra i det siste',
 'watchlistcontains' => 'Overvakingslista di inneheld {{PLURAL:$1|éi side|$1 sider}}.',
 'iteminvalidname' => 'Problem med «$1», ugyldig namn...',
 'wlnote' => "Nedanfor er {{PLURAL:$1|den siste endringa|dei siste '''$1''' endringane}} {{PLURAL:$2|den siste timen|dei siste '''$2''' timane}}, for $3, kl. $4.",
-'wlshowlast' => 'Vis siste $1 timar $2 dagar $3',
+'wlshowlast' => 'Vis siste $1 timane $2 dagane $3',
 'watchlist-options' => 'Alternativ for overvakingslista',
 
 # Displayed when you click the "watch" button and it is in the process of watching
 'watching' => 'Overvakar...',
 'unwatching' => 'Fjernar frå overvakinglista...',
+'watcherrortext' => 'Det oppstod ein feil under endringa av overvakingsinnstillingane dine for «$1».',
 
 'enotif_mailer' => '{{SITENAME}}-endringsmeldingssendar',
-'enotif_reset' => 'Merk alle sider som vitja',
+'enotif_reset' => 'Merk alle sidene som vitja',
 'enotif_newpagetext' => 'Dette er ei ny side.',
 'enotif_impersonal_salutation' => '{{SITENAME}}-brukar',
 'changed' => 'endra',
@@ -2325,7 +2336,7 @@ Den siste endringa vart gjord av [[User:$3|$3]] ([[User talk:$3|brukardiskusjon]
 'editcomment' => "Samandraget for endringa var: «''$1''».",
 'revertpage' => 'Attenderulla endring gjord av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusjon]]) til siste versjonen av [[User:$1|$1]]',
 'revertpage-nouser' => 'Tilbakestilte endringar av (brukarnamn fjerna) til den siste versjonen av [[User:$1|$1]]',
-'rollback-success' => 'Rulla attende endringane av $1, tilbake til siste versjon av $2.',
+'rollback-success' => 'Rulla attende endringane av $1, attende til siste versjonen av $2.',
 
 # Edit tokens
 'sessionfailure-title' => 'Feil med omgangen.',
@@ -2343,6 +2354,7 @@ Sjå [[Special:ProtectedPages|lista over verna sider]] for lista over vern som n
 'protect-title-notallowed' => 'Sjå vernenivået til «$1»',
 'prot_1movedto2' => '«[[$1]]» flytt til «[[$2]]»',
 'protect-badnamespace-title' => 'Namnerommet kan ikkje vernast',
+'protect-badnamespace-text' => 'Sider i dette namnerommet kan ikkje vernast.',
 'protect-legend' => 'Stadfest vern',
 'protectcomment' => 'Grunngjeving:',
 'protectexpiry' => 'Endar:',
@@ -2782,6 +2794,7 @@ Vitja [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] og [//trans
 'import-interwiki-templates' => 'Inkluder alle malar',
 'import-interwiki-submit' => 'Importer',
 'import-interwiki-namespace' => 'Målnamnerom:',
+'import-interwiki-rootpage' => 'Målrotside (valfri):',
 'import-upload-filename' => 'Filnamn:',
 'import-comment' => 'Kommentar:',
 'importtext' => 'Lagre fila frå kjeldewikien med [[Special:Export|eksporteringsverktøyet]] på din eigen datamaskin, og last henne så opp her.',
@@ -2813,6 +2826,9 @@ Vitja [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] og [//trans
 'import-error-interwiki' => 'Sida «$1» vart ikkje importert sidan namnet hennar er reservert for ekstern lenking (interwiki).',
 'import-error-special' => 'Sida «$1» vart ikkje importert sidan ho høyrer til eit spesialnamnerom som ikkje tillèt sider.',
 'import-error-invalid' => 'Sida «$1» vart ikkje importert sidan namnet er ugildt.',
+'import-options-wrong' => '{{PLURAL:$2|Galt val|Gale val}}: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'Den oppgjevne rotsida er ein ugild tittel',
+'import-rootpage-nosubpage' => 'Namnerommet «$1» til rotsida tillèt ikkje undersider.',
 
 # Import log
 'importlogpage' => 'Importeringslogg',
@@ -2965,6 +2981,7 @@ Vitja [//www.mediawiki.org/wiki/Localisation MediaWiki Localisation] og [//trans
 'pageinfo-watchers' => 'Tal på overvakarar av sida',
 'pageinfo-redirects-name' => 'Omdirigeringar til sida',
 'pageinfo-subpages-name' => 'Undersider av sida',
+'pageinfo-subpages-value' => '$1 ({{PLURAL:$2|éi omdirigering|$2 omdirigeringar}}; {{PLURAL:$3|éi ikkje-omdirigering|$3 ikkje-omdirigeringar}})',
 'pageinfo-firstuser' => 'Sideopprettar',
 'pageinfo-firsttime' => 'Dato for opprettinga av sida',
 'pageinfo-lastuser' => 'Siste forfattaren',
@@ -3028,6 +3045,7 @@ $1',
 'file-info-size-pages' => '$1 × $2 pikslar, filstorleik: $3, MIME-type: $4, {{PLURAL:$5|éi side|$5 sider}}',
 'file-nohires' => 'Høgare oppløysing er ikkje tilgjengeleg.',
 'svg-long-desc' => 'SVG-fil, standardoppløysing: $1 × $2 pikslar, filstorleik: $3',
+'svg-long-desc-animated' => 'Animert SVG-fil, standardoppløysing $1 × $2 pikslar, filstorleik: $3',
 'show-big-image' => 'Full oppløysing',
 'show-big-image-preview' => 'Storleik på førehandsvising: $1.',
 'show-big-image-other' => '{{PLURAL:$2|Anna oppløysing|Andre oppløysingar}}: $1.',
@@ -3037,6 +3055,8 @@ $1',
 'file-info-png-looped' => '↓oppatteke',
 'file-info-png-repeat' => 'spela av {{PLURAL:$1|éin gong|$1 gonger}}',
 'file-info-png-frames' => '$1 {{PLURAL:$1|bilete|bilete}}',
+'file-no-thumb-animation' => "'''Merk: Grunna tekniske avgrensingar vil ikkje miniatyrbilete av fila verta animerte.'''",
+'file-no-thumb-animation-gif' => "'''Merk: Grunna tekniska avgrensingar vil ikkje miniatyrbilete av høgoppløyselege GIF-bilete som dette verta animerte.'''",
 
 # Special:NewFiles
 'newimages' => 'Filgalleri',
@@ -3225,6 +3245,8 @@ Andre er gøymde som standard.
 'exif-languagecode' => 'Språk',
 'exif-iimversion' => 'IIM-versjon',
 'exif-iimcategory' => 'Kategori',
+'exif-datetimeexpires' => 'Skal ikkje nyttast etter',
+'exif-datetimereleased' => 'Frigjeve',
 'exif-lens' => 'Objektiv',
 'exif-cameraownername' => 'Eigar av kameraet',
 'exif-label' => 'Merkelapp',
@@ -3406,6 +3428,7 @@ Andre er gøymde som standard.
 'exif-gpsdop-excellent' => 'Utmerkt ($1)',
 'exif-gpsdop-good' => 'God ($1)',
 'exif-gpsdop-moderate' => 'Moderat ($1)',
+'exif-gpsdop-fair' => 'Medels ($1)',
 'exif-gpsdop-poor' => 'Dårleg ($1)',
 
 'exif-objectcycle-a' => 'Berre morgon',
index 7969b80..edc5210 100644 (file)
@@ -60,9 +60,9 @@ $messages = array(
 'tog-previewontop' => 'Bontšha Ponopele pele ga lepokisi la diphetogo',
 'tog-previewonfirst' => 'Bontšha Ponopeleka phetogo ya pele',
 'tog-nocache' => "Thibela go tsenya matlakala go segakolodi (''cache'')",
-'tog-enotifwatchlistpages' => 'Nromele molaetša ge letlaka leo ke le tlhapetšego le eba le diphetogo',
+'tog-enotifwatchlistpages' => 'Nthomele molaetša ge letlaka leo ke le tlhapetšego le eba le diphetogo',
 'tog-enotifusertalkpages' => 'Nromele molaetša ge letlakala la Dipoledišano laka le fetoga',
-'tog-enotifminoredits' => 'Nromele email ge goba le diphetogo tše nnyenyane go matlakala',
+'tog-enotifminoredits' => 'Ethomele e-mail ge goba le diphetogo tše nnyenyane go matlakala',
 'tog-enotifrevealaddr' => 'Bonagatša email atrese go temošo tša poso',
 'tog-shownumberswatching' => 'Laetša palo bašomiši bao ba tlhapetšego',
 'tog-fancysig' => 'Tsaeno ya gose fihliwe',
@@ -195,8 +195,8 @@ $messages = array(
 'protect' => 'Lota',
 'protect_change' => 'Fetola go lotega',
 'protectthispage' => 'Lota letlakala le',
-'unprotect' => 'Tloša go lota',
-'unprotectthispage' => 'Tloša go lota letlakaleng',
+'unprotect' => 'Fetola go lota',
+'unprotectthispage' => 'Fetola go lota letlakaleng',
 'newpage' => 'Letlakala le lempsha',
 'talkpage' => 'Rêrišana ka letlakala le',
 'talkpagelinktext' => 'Bolela',
@@ -224,6 +224,7 @@ $messages = array(
 'jumpto' => 'Taboga go:',
 'jumptonavigation' => 'Tšweletšo',
 'jumptosearch' => 'fetleka',
+'pool-errorunknown' => 'Phošo yago setsebege',
 
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage) and the disambiguation template definition (see disambiguations).
 'aboutsite' => 'Mabapi le {{SITENAME}}',
@@ -256,6 +257,7 @@ $messages = array(
 'youhavenewmessages' => 'O na le $1 ($2).',
 'newmessageslink' => 'ya melaetša ye mefsa',
 'newmessagesdifflink' => 'phetogo ya mafelelo',
+'newmessagesdifflinkplural' => 'l{{PLURAL:$1|Phetogo tša|Diphetogo ya}}go feta',
 'youhavenewmessagesmulti' => 'O nale melaetša ye mefsa go $1',
 'editsection' => 'lokiša',
 'editold' => 'fetola',
@@ -454,7 +456,8 @@ oka [[Special:Search/{{PAGENAME}}|fetleka leina la letlakala]] matlakaleng a man
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} fetleka "logs"],
  goba [{{fullurl:{{FULLPAGENAME}}|action=edit}} wa fetola letlakala le]</span>.',
 'note' => "'''Ela hloko:'''",
-'previewnote' => "'''Ye ke Taetšo ya sebopego sa letlakala fela; diphetogo ga di ya bolokwa!'''",
+'previewnote' => "'''Elelwa gore ye ke taetšo ya sebopego sa letlakala fela.'''
+Diphetogo tša gago ga šetšo di bolokwa!",
 'editing' => 'O fetola $1',
 'editingsection' => 'Phetolo ya $1 (sekgoba)',
 'editingcomment' => 'O fetola $1 (sekgao se sempsha)',
@@ -541,7 +544,7 @@ fetola tshenolo',
 'revertmerge' => 'Tloša kopaganyo',
 
 # Diffs
-'history-title' => 'Histori ya diphetogo tša "$1"',
+'history-title' => 'Poeletšo ya diphetogo tša "$1"',
 'lineno' => 'Mothalo $1:',
 'compareselectedversions' => 'Bapetša diphapang tšeo di kgethilwego',
 'editundo' => 'dirolla',
@@ -832,10 +835,10 @@ Matlakala ago ba [[Special:Watchlist|lenanong la gago la matlakala ditlhapetšo]
 'booksources-go' => 'Sepela',
 
 # Special:Log
-'specialloguserlabel' => 'Mošomiši:',
-'speciallogtitlelabel' => 'Thaetlele:',
+'specialloguserlabel' => 'Modiri:',
+'speciallogtitlelabel' => 'Thaetlele (goba mošumiši):',
 'log' => "Di-''log''",
-'all-logs-page' => "Di-''log'' kamoka",
+'all-logs-page' => "Di-''log'' tša bohle ka moka",
 
 # Special:AllPages
 'allpages' => 'Matlakala ka moka',
@@ -856,7 +859,7 @@ Matlakala ago ba [[Special:Watchlist|lenanong la gago la matlakala ditlhapetšo]
 'deletedcontributions-title' => 'Diabe tša mošomiši tšeo di phumutšwego',
 
 # Special:LinkSearch
-'linksearch' => 'Dihlomaganyo tša ntle',
+'linksearch' => 'Fehleka dihlomaganyo tša ntle',
 'linksearch-ok' => 'Fetleka',
 'linksearch-line' => '$1 e kgokaganywa gotšwa $2',
 
@@ -873,9 +876,9 @@ Matlakala ago ba [[Special:Watchlist|lenanong la gago la matlakala ditlhapetšo]
 'emailuser' => 'Romela mošomiši yo molaetša',
 'emailpage' => 'Romela email go mošomiši',
 'noemailtitle' => 'Gago email atrese',
-'emailfrom' => 'Go tšwa go',
-'emailsubject' => 'Sebolelwa',
-'emailmessage' => 'Molaetša',
+'emailfrom' => 'Go tšwa go:',
+'emailsubject' => 'Sebolelwa:',
+'emailmessage' => 'Molaetša:',
 'emailsend' => 'Romela',
 'emailccme' => 'Nromela kopi ya melaetša.',
 'emailccsubject' => 'Kopi ya molaetša wa gago goya go $1: $2',
@@ -929,7 +932,7 @@ Lebelela $2 go hweetša sedi ka diphulo tša bjale.',
 
 # Rollback
 'rollbacklink' => 'bošetša morago',
-'editcomment' => "Ahlaahlo ya phetogo ke : \"''\$1''\".",
+'editcomment' => "Ahlaahlo ya phetogo e bile : \"''\$1''\".",
 
 # Protect
 'protectlogpage' => "''Log'' yago lota",
@@ -953,7 +956,7 @@ Seemo sa go lota ga letlakala '''$1''':",
 'protect-expiring' => 'fetatšatši ke $1 (UTC)',
 'protect-cascade' => 'Lota matlakala, akaretša le letlakala le (go lota ka kakaretšo)',
 'protect-cantedit' => 'Ga o kgone go fetola tekano ya bolotego letlakaleng le, ka ge o sena tumello yago bofetola.',
-'protect-expiry-options' => '2 diiri:2 hours,1 letšatši:1 day,3 matšatši:3 days,1 beke:1 week,2 dibeke:2 weeks,1 kgwedi:1 month,3 digkwedi:3 months,6 dikgwedi:6 months,1 ngwaga:1 year,ga efele:infinite',
+'protect-expiry-options' => 'iri:1 hour, letšatš1:1 day,beke:1 week,dibeke tše 2:2 weeks,kgwedi:1 month,dikgwedi tše 3:3 months,dikgwedi tše 6:6 months,ngwaga:1 year,gosefele (infinite):infinite',
 'restriction-type' => 'Tumello:',
 'restriction-level' => 'Seemo sago Lota:',
 
@@ -989,7 +992,7 @@ Seemo sa go lota ga letlakala '''$1''':",
 'sp-contributions-newbies' => 'Laetša diabe tša bašumiši ba bafsa fela',
 'sp-contributions-newbies-sub' => 'Tša tšhupaleloko tše mphsa',
 'sp-contributions-blocklog' => "''Log'' yago thiba",
-'sp-contributions-deleted' => 'Diabe tša mošomiši tšeo di phumutšwego',
+'sp-contributions-deleted' => 'diabe tša mošomiši tšeo di phumutšwego',
 'sp-contributions-uploads' => 'di-"upload"',
 'sp-contributions-logs' => "Di-''log''",
 'sp-contributions-talk' => 'Poledišano',
index b81f83a..bebf4fe 100644 (file)
@@ -299,7 +299,7 @@ $messages = array(
 'projectpage' => 'Проекты фарс фен',
 'imagepage' => 'Файлы фарс фен',
 'mediawikipage' => 'Фыстæджы фарс фен',
-'templatepage' => 'ШаблонÑ\8b Ñ\84аÑ\80Ñ\81 Ñ\84ен',
+'templatepage' => 'Ð¥Ñ\83Ñ\8bзæджÑ\8b Ñ\84аÑ\80Ñ\81 Ñ\84енÑ\8bн',
 'viewhelppage' => 'Æххуысы фарс фен',
 'categorypage' => 'Категорийы фарс фен',
 'viewtalkpage' => 'Тæрхон фен',
@@ -393,7 +393,7 @@ $1',
 'nstab-project' => 'Проекты тыххæй',
 'nstab-image' => 'Файл',
 'nstab-mediawiki' => 'Фыстæг',
-'nstab-template' => 'Шаблон',
+'nstab-template' => 'Ð¥Ñ\83Ñ\8bзæг',
 'nstab-help' => 'Æххуысы фарс',
 'nstab-category' => 'Категори',
 
@@ -770,7 +770,7 @@ $2
 'editconflict' => 'Ивыны конфликт: $1',
 'yourtext' => 'Дæ текст',
 'yourdiff' => 'Хицæндзинæдтæ',
-'templatesused' => 'Ð\90Ñ\86Ñ\8b Ñ\84аÑ\80Ñ\81Ñ\8b Ð¸Ñ\81 {{PLURAL:$1|Ñ\88аблон|Ñ\88аблоны}}:',
+'templatesused' => 'Ð\90Ñ\86Ñ\8b Ñ\84аÑ\80Ñ\81Ñ\8b Ð¸Ñ\81 {{PLURAL:$1|Ñ\85Ñ\83Ñ\8bзæг|Ñ\85Ñ\83Ñ\8bзæджы}}:',
 'template-protected' => '(æхгæд)',
 'template-semiprotected' => '(æрдæг-æхгæд)',
 'hiddencategories' => 'Ацы фарс у {{PLURAL:$1|1 æмбæхст категорийы|$1 æмбæхст категориты}} уæнг:',
@@ -786,12 +786,12 @@ $2
 'edit-already-exists' => 'Ног фарс скæнæн нæй. Ахæм фарс ис.',
 
 # Parser/template warnings
-'post-expand-template-inclusion-warning' => "'''СÑ\8bндæг: ''' Ð¨Ð°Ð±Ð»Ð¾Ð½ы бавæрд бæрц æгæр стыр у.
\9aæÑ\86Ñ\8bдæÑ\80 Ñ\88аблонтæ нæ бавæд уыдзысты.",
-'post-expand-template-inclusion-category' => 'ФæÑ\80Ñ\81Ñ\82æ, ÐºÃ¦Ð¼ Ñ\88аблоны бавæрд бæрц æгæр бирæ у',
-'post-expand-template-argument-warning' => "'''СÑ\8bндæг:''' Ð\90Ñ\86Ñ\8b Ñ\84аÑ\80Ñ\81Ñ\8b Ð¸Ñ\81 Ñ\83æддæÑ\80 Ð¸Ñ\83 Ñ\88аблоны аргумент, кæй райтынг у æгæр стыр.
+'post-expand-template-inclusion-warning' => "'''СÑ\8bндæг: ''' Ð¥Ñ\83Ñ\8bзæджы бавæрд бæрц æгæр стыр у.
\9aæÑ\86Ñ\8bдæÑ\80 Ñ\85Ñ\83Ñ\8bзæгтæ нæ бавæд уыдзысты.",
+'post-expand-template-inclusion-category' => 'ФæÑ\80Ñ\81Ñ\82æ, ÐºÃ¦Ð¼ Ñ\85Ñ\83Ñ\8bзæджы бавæрд бæрц æгæр бирæ у',
+'post-expand-template-argument-warning' => "'''СÑ\8bндæг:''' Ð\90Ñ\86Ñ\8b Ñ\84аÑ\80Ñ\81Ñ\8b Ð¸Ñ\81 Ñ\83æддæÑ\80 Ð¸Ñ\83 Ñ\85Ñ\83Ñ\8bзæджы аргумент, кæй райтынг у æгæр стыр.
 Уыцы аргументтæ уагъд æрцыдысты.",
-'post-expand-template-argument-category' => 'ФæÑ\80Ñ\81Ñ\82æ, ÐºÃ¦Ð´Ð¾Ð½Ñ\8b Ð¸Ñ\81 Ñ\88аблоны уагъд аргумент',
+'post-expand-template-argument-category' => 'ФæÑ\80Ñ\81Ñ\82æ, ÐºÃ¦Ð´Ð¾Ð½Ñ\8b Ð¸Ñ\81 Ñ\85Ñ\83Ñ\8bзæджы уагъд аргумент',
 
 # History pages
 'viewpagelogs' => 'Ацы фарсæн йæ логтæ равдисын',
@@ -1106,7 +1106,7 @@ $3',
 'download' => 'æрбавгæн',
 
 # Unused templates
-'unusedtemplates' => 'Ð\9fайда ÐºÃ¦Ð¼Ã¦Ð¹ Ð½Ã¦ Ñ\87Ñ\8bндæÑ\83Ñ\8b, Ð°Ñ\85æм Ñ\88аблонтæ',
+'unusedtemplates' => 'Ð\9fайда ÐºÃ¦Ð¼Ã¦Ð¹ Ð½Ã¦ Ñ\87Ñ\8bндæÑ\83Ñ\8b, Ð°Ñ\85æм Ñ\85Ñ\83Ñ\8bзæгтæ',
 
 # Random page
 'randompage' => 'Халæй ист фарс',
@@ -1134,7 +1134,7 @@ $3',
 'lonelypages' => 'Сидзæр фæрстæ',
 'uncategorizedpages' => 'Æнæкатегори фæрстæ',
 'uncategorizedimages' => 'Æнæкатегори файлтæ',
-'uncategorizedtemplates' => 'Ã\86нæкаÑ\82егоÑ\80и Ñ\88аблонтæ',
+'uncategorizedtemplates' => 'Ã\86нæкаÑ\82егоÑ\80и Ñ\85Ñ\83Ñ\8bзæгтæ',
 'popularpages' => 'Популярон фæрстæ',
 'wantedcategories' => 'Хъæугæ категоритæ',
 'wantedpages' => 'Хъæугæ фæрстæ',
@@ -1408,7 +1408,7 @@ $3',
 'tooltip-ca-nstab-special' => 'Ай сæрмагонд фарс у, дæ бон æй нæу ивын',
 'tooltip-ca-nstab-project' => 'Фенын проекты фарс',
 'tooltip-ca-nstab-image' => 'Нывы фарс',
-'tooltip-ca-nstab-template' => 'ФенÑ\8bн Ñ\88аблон',
+'tooltip-ca-nstab-template' => 'Ð¥Ñ\83Ñ\8bзæг Ñ\84енÑ\8bн',
 'tooltip-ca-nstab-category' => 'Категорийы фарс',
 'tooltip-minoredit' => 'Чысыл ивдæй йæ банысан кæнын',
 'tooltip-save' => 'Бавæр дæ ивдтытæ',
index c0f167d..6aad410 100644 (file)
@@ -28,15 +28,15 @@ $messages = array(
 'tog-editsectiononrightclick' => "Pérmet l'édichion del sekchion par un droé buke su ch'tite del sekchion (i feut JavaScript)",
 'tog-showtoc' => "Aficher l'tabe ed ches étnus (pou ches paches aveuc plu ed 3 intétes)",
 'tog-rememberpassword' => "Warder min lodjine su chl'ordinateu-lo (pour un maximum éd $1 {{PLURAL:$1|jour|jours}})",
-'tog-watchcreations' => "Ajouter chés paches qu'éj crée dseu em lisse",
-'tog-watchdefault' => "Ajouter chés paches qu'éj édite dseu em lisse.",
-'tog-watchmoves' => "Ajouter chés paches qu'éj déplache dseu m'lisse.",
-'tog-watchdeletion' => "Ajouter chés paches qu'éj déface dseur m'lisse.",
+'tog-watchcreations' => "Ajouter chés paches qu'éj crée et pi chés fichiés qu'éj téléquertche édseur em lisse à suire",
+'tog-watchdefault' => "Ajouter chés paches pi chés fichiés qu'éj cange édseur em lisse à suire.",
+'tog-watchmoves' => "Ajouter chés paches pi chés fichiés qu'éj déplache édseur m'lisse à suire.",
+'tog-watchdeletion' => "Ajouter chés paches pi chés fichiés qu'éj déface édseur m'lisse à suire.",
 'tog-previewontop' => "Aficher l'prévue édvint el bouéte édite",
 'tog-previewonfirst' => "Aficher l'prévue au preumié édite.",
-'tog-enotifwatchlistpages' => "Éspédier din m'boéte un imèle quante eune pache su m'lisse est candgée",
+'tog-enotifwatchlistpages' => "M'éspédier un imèle quante eune pache su m'lisse à suire est cangée",
 'tog-enotifusertalkpages' => 'Éspédier un imèle su em bouéte quante m\'pache "Dvise Uzeu" est candgée.',
-'tog-enotifminoredits' => 'Éspédier à mi étous un imèle pou ches tiots édites éd ches paches',
+'tog-enotifminoredits' => "M'éspédier étou un imèle pou chés tiots canjemints d'chés paches o d'chés fichiés",
 'tog-shownumberswatching' => "Aficher ch'nombe ed gins qu'ont vu.",
 'tog-watchlisthideown' => 'Muche mes édites dseur el lisse',
 'tog-watchlisthidebots' => 'Muche ches robots édites su el lisse',
@@ -152,7 +152,7 @@ $messages = array(
 'vector-action-protect' => 'Garantir',
 'vector-action-undelete' => "N'poin défacher",
 'vector-action-unprotect' => "Canger l'garantie",
-'vector-simplesearch-preference' => "Déhousser chés avanches d'ércherche améliorées (seulemint pour Vector)",
+'vector-simplesearch-preference' => "Actionner l'barette pour chés traches simpes (seulemint pour l'habillure Vector)",
 'vector-view-create' => 'Créer',
 'vector-view-edit' => 'Éditer',
 'vector-view-history' => "Vir l'histoère",
@@ -410,10 +410,15 @@ Os prométtez auchi éq vos avez écrit ch'teske vous-méme, ou éq vos l’avez
 'hiddencategories' => '{{PLURAL:$1|Catégorie muchée|Catégories muchées}} pou chol pache:',
 'permissionserrorstext-withaction' => "Vos n’avez poin l'pérmichon éd $2, pou {{PLURAL:$1|ch'motif suivant|chés motifs suivants}}:",
 
+# Parser/template warnings
+'post-expand-template-inclusion-warning' => "Affute : Chèle pache ale a trop d’modèles. Des inclusions n'sront poin foaites.",
+'post-expand-template-inclusion-category' => "Paches aveuc granmint d'modèles",
+
 # History pages
 'viewpagelogs' => 'Vir chés gasètes del pache-lo',
 'currentrev-asof' => 'Coursaule vérchon in date du $1',
 'revisionasof' => 'Ércordé conme $1',
+'revision-info' => 'Version du $1 pèr $2',
 'previousrevision' => '← érvue dvant',
 'nextrevision' => 'Cangemint pu nouvieu →',
 'currentrevisionlink' => 'Érvision éd qhére',
@@ -430,6 +435,8 @@ Léginde : ({{MediaWiki:Cur}}) = différinches aveuc el vérchon à ch'momint-ch
 # Revision deletion
 'rev-delundel' => 'montrer/mucher',
 'revdel-restore' => 'cange écmint vir',
+'revdel-restore-deleted' => 'canjemints abolis',
+'revdel-restore-visible' => 'canjemints visibes',
 'pagehist' => 'Histoère del pache',
 
 # Merge log
@@ -454,6 +461,17 @@ Léginde : ({{MediaWiki:Cur}}) = différinches aveuc el vérchon à ch'momint-ch
 'nextn' => 'apreu {{PLURAL:$1|$1}}',
 'prevn-title' => 'Dvant $1 {{PLURAL:$1|résultat|résultats}}',
 'viewprevnext' => 'Vir ($1 {{int:pipe-separator}} $2) ($3)',
+'searchmenu-new' => "'''Créer l'pache « [[:$1|$1]] » édseur ech wiki !'''",
+'searchprofile-articles' => "Paches d'étnu",
+'searchprofile-project' => "Paches d’aïude et pi d'prodjé",
+'searchprofile-images' => 'Multimédia',
+'searchprofile-everything' => 'Tout',
+'searchprofile-advanced' => 'Értrache avanchée',
+'searchprofile-articles-tooltip' => 'tracher dins $1',
+'searchprofile-project-tooltip' => 'Tracher dins $1',
+'searchprofile-images-tooltip' => 'Tracher des fichiés multimédias',
+'searchprofile-everything-tooltip' => "Tracher dins tout ch'wikipédia (et ochi dins chés paches éd distchucion)",
+'searchprofile-advanced-tooltip' => "Couésir chés éspaches d'noms pour l'értrache",
 'search-result-size' => '$1 ({{PLURAL:$2|1 mot|$2 mots}})',
 'search-redirect' => '(érdirection $1)',
 'search-section' => '(sekchon $1)',
@@ -461,7 +479,9 @@ Léginde : ({{MediaWiki:Cur}}) = différinches aveuc el vérchon à ch'momint-ch
 'search-interwiki-caption' => 'Proujé analocq',
 'search-interwiki-default' => '$1 résultats:',
 'search-interwiki-more' => '(pus)',
+'searchall' => 'tout',
 'nonefound' => "'''Note''': il y o tasseulemint quéques éspaces éd noms éq sont trachés pèr défeut. <br /> Pou tracher din tous chés contnus (paches éd pérlache, modéles, etc... comprins) insséyer in imploéyant ch'préfixe ''all:'' o bin imploéyer echl éspace éd noms édmindé conme préfixe.",
+'search-nonefound' => 'Y a autchun résultat pour chol dmanne.',
 'powersearch' => 'Érvue avanchée',
 'powersearch-legend' => 'Érvue avanchée',
 'powersearch-ns' => 'Tracher din chés éspaches éd chés noms:',
@@ -503,6 +523,28 @@ Ale doét mie éte pu longue éq $1 {{PLURAL:$1|caracter|caractéres}}.',
 # Associated actions - in the sentence "You do not have permission to X"
 'action-read' => "Vir l'pache-lo",
 'action-edit' => "édite l'pache-lo",
+'action-createpage' => 'créer des paches',
+'action-createtalk' => 'créer des paches éd dichtchussion',
+'action-createaccount' => "créer ech compte d'uzeu",
+'action-minoredit' => 'mértcher chol canjemint conme mineur',
+'action-move' => "érlonmer l'pache-lo",
+'action-move-subpages' => 'érlonmer chol pache et pi ses dsous-paches',
+'action-move-rootuserpages' => "érlonmer l' pache princhipale d’un uzeu",
+'action-movefile' => "érlonmer ch'fichié-lo",
+'action-upload' => 'téléquértcher ech fichié',
+'action-reupload' => "écatir l'anchien fichié",
+'action-upload_by_url' => "téléquértcher ch' fichié à partir d’eune URL",
+'action-writeapi' => "foaire aveuc l'écrivure API",
+'action-delete' => "Défacer l'pache-lo",
+'action-deleterevision' => "défacer ch'canjemint-lo",
+'action-deletedhistory' => 'vir l’histoère muchée éd chol pache',
+'action-browsearchive' => 'tracher des paches défacées',
+'action-undelete' => "n'poin défacer chol pache",
+'action-suppressrevision' => 'vir pi érfoaire chol version muchée',
+'action-suppressionlog' => 'vir ech jornal privé',
+'action-block' => "blotcher l'écrivure éd chol uzeu-lo",
+'action-import' => 'téléquértcher chol pache à partir d’un eute wiki',
+'action-importupload' => "téléquértcher chol pache à partir d'un fichié",
 
 # Recent changes
 'nchanges' => '$1 {{PLURAL:$1|cange|canges}}',
@@ -540,8 +582,10 @@ Ale doét mie éte pu longue éq $1 {{PLURAL:$1|caracter|caractéres}}.',
 'uploadedimage' => '"[[$1]]" quértchée',
 
 # File description page
+'file-anchor-link' => 'Fichié',
 'filehist' => 'Histoère dech fichié',
 'filehist-help' => "Buke su eune date/heure pou vir ch'fichié conme il étoait ach momint-lo.",
+'filehist-revert' => 'invérser',
 'filehist-current' => 'courant',
 'filehist-datetime' => 'Date/Tans',
 'filehist-thumb' => 'Tiote image',
@@ -549,9 +593,11 @@ Ale doét mie éte pu longue éq $1 {{PLURAL:$1|caracter|caractéres}}.',
 'filehist-user' => 'Uzeu',
 'filehist-dimensions' => 'Diminsions',
 'filehist-comment' => 'Fichié éd chés conmints',
-'imagelinks' => 'Loïens dech fichié',
+'imagelinks' => 'Usage dech fichié',
 'linkstoimage' => "{{PLURAL:$1|L'pache d'apreu est liée|Chés $1 paches d'apreu sont liées}} à ch'fichié-lo :",
 'sharedupload' => "Cht'fichié vient éd $1 pi i put ète imploïé par d'eutes proujés.",
+'sharedupload-desc-here' => "Ch'fichié i vient éd $1. I put ète uzer pèr d’eutes prodjés.
+Vir apré ([$2 pache]).",
 'uploadnewversion-linktext' => 'Quértcher eune novèle vérchion del pache-lo',
 
 # Random page
@@ -564,6 +610,7 @@ Ale doét mie éte pu longue éq $1 {{PLURAL:$1|caracter|caractéres}}.',
 'nbytes' => '$1 {{PLURAL:$1|octé|octés}}',
 'nmembers' => '$1 {{PLURAL:$1|mimbe|mimbes}}',
 'prefixindex' => 'Tertous chés paches aveuc préfix',
+'usercreated' => '{{GENDER:$3|Créé}} ech $1 à $2',
 'newpages' => 'Novèles paches',
 'move' => 'Déplacher',
 'movethispage' => "Déplacher l'pache-lo",
@@ -608,6 +655,7 @@ Ale doét mie éte pu longue éq $1 {{PLURAL:$1|caracter|caractéres}}.',
 # Watchlist
 'watchlist' => 'Em lisse à suire',
 'mywatchlist' => "M'lisse à suire",
+'watchlistfor2' => 'Pour $1 $2',
 'addedwatchtext' => "L' pache « [[:$1]] » o té rajoutée à vote [[Special:Watchlist|lisse à suire]].<br /> Chés  canjemints à vnir del pache-lo pi del page éd pérlache sront mis din l'lisse. L'pache sro '''in cros''' din el [[Special:RecentChanges|lisse d'chés darins canjemints]] pou les értreuver fachilmint. Pou értirer chol pache del ''lisse à suire'', bukez su « {{MediaWiki:Unwatch}} ».",
 'removedwatchtext' => "L'pache « [[:$1]] » o té értirée éd vote [[Special:Watchlist|lisse à suire]].",
 'watch' => 'Suire',
@@ -667,6 +715,7 @@ Vlo chés réglages del pache '''$1''' à ch'momint-chi:",
 
 # Undelete
 'undeletelink' => 'vir/érfoaire',
+'undeleteviewlink' => 'Vir',
 
 # Namespace form on various pages
 'namespace' => 'Éspace du nom:',
@@ -684,6 +733,8 @@ Vlo chés réglages del pache '''$1''' à ch'momint-chi:",
 
 'sp-contributions-newbies' => 'Montrer chés contérbuchons éd chés nouvieus conptes seulemint',
 'sp-contributions-blocklog' => 'jornal éd chés blotcåjhes',
+'sp-contributions-logs' => 'Gasètes',
+'sp-contributions-talk' => 'Dviser',
 'sp-contributions-search' => 'Tracher pou chés contérbuchons',
 'sp-contributions-username' => "Adérche IP ou nom d'uzeu",
 'sp-contributions-toponly' => "n'montrer qu'chés darins canjemints",
@@ -756,6 +807,9 @@ Din chés cas-lo, I feut érlonmer ou ratatouiller l'pache aveuc l'main.",
 # Export
 'export' => 'Ésporter chés paches',
 
+# Namespace 8 related
+'allmessagesname' => 'Nom',
+
 # Thumbnails
 'thumbnail-more' => 'Pu grand',
 
@@ -817,6 +871,7 @@ Os pouvez vir l'source",
 'tooltip-rollback' => '« Racacher » cancéle aveuc un clic el (ou chés) modificachon(s) del pache-lo pèr sin darin contérbucheu.',
 'tooltip-undo' => "« Undo » ( ''démangler'' ) értire ch'canjemint-lo pi ouvre l' fénéte d'édichon din ch'mode ''prévir''. <br /> In put mette un motif din ch'résumé.",
 'tooltip-preferences-save' => 'Warder chés préférinches.',
+'tooltip-summary' => 'Intrer un tiot résumè',
 
 # Browsing diffs
 'previousdiff' => '← Pu vieille édition',
index 7ccd26f..8fd0351 100644 (file)
@@ -25,6 +25,13 @@ $messages = array(
 'underline-default' => 'Des nemme, was em Broweser gsaacht hoscht.',
 
 # Dates
+'sunday' => 'Sundaach',
+'monday' => 'Mondaach',
+'tuesday' => 'Dienschdaach',
+'wednesday' => 'Midwoch',
+'thursday' => 'Dunnaschdaach',
+'friday' => 'Fraidaach',
+'saturday' => 'Somschdaach',
 'january' => 'Jänner',
 'february' => 'Fewwer',
 'march' => 'März',
@@ -84,8 +91,12 @@ $messages = array(
 'qbmyoptions' => 'Mai Saide',
 
 # Vector skin
+'vector-action-delete' => 'Lesche',
 'vector-action-move' => 'Verschiewe',
+'vector-action-protect' => 'Schitze',
 'vector-view-edit' => 'Bearwaide',
+'vector-view-view' => 'Lese',
+'actions' => 'Agzione',
 
 'errorpagetitle' => 'Fehler',
 'returnto' => 'Zrick zu $1.',
@@ -253,7 +264,7 @@ du gebbscht do au zu, dass Du des selwerscht gschriwwe hoscht orrer vun ere effe
 De Leschaidrach fa die Said isch do unne als Kwell aagewwe.',
 
 # History pages
-'viewpagelogs' => 'D Lochbiecher fer die Said aagucke',
+'viewpagelogs' => 'Lochbicher fer die Said aagucke',
 'currentrev-asof' => 'Aktuelle Version vun $1',
 'revisionasof' => 'Version vun $1',
 'previousrevision' => '← Ältere Versione',
@@ -359,8 +370,8 @@ Erklärung: '''({{int:cur}})''' = Unnerschied zu jetzert,
 'rclinks' => 'Zeich die letschte $1 Ännerunge in de letschte $2 Dache<br />$3',
 'diff' => 'Unnerschied',
 'hist' => 'Gschicht',
-'hide' => 'versteggeln',
-'show' => 'zaiche',
+'hide' => 'vaschdeggle',
+'show' => 'zaische',
 'minoreditletter' => 'k',
 'newpageletter' => 'N',
 'boteditletter' => 'B',
@@ -396,6 +407,7 @@ Saide uff [[Special:Watchlist|Dainer Beowachdungslischt]] sin '''fett'''.",
 'file-anchor-link' => 'Datei',
 'filehist' => 'Dateigschicht',
 'filehist-help' => 'Drick uff e Zaidpunkt zum aazääche, wie s dort ausgsähne hot.',
+'filehist-revert' => 'zuriggsedze',
 'filehist-current' => 'aktuell',
 'filehist-datetime' => 'Zaidpunkt',
 'filehist-thumb' => 'Vorschaubild',
@@ -403,7 +415,7 @@ Saide uff [[Special:Watchlist|Dainer Beowachdungslischt]] sin '''fett'''.",
 'filehist-user' => 'Benutzer',
 'filehist-dimensions' => 'Moß',
 'filehist-comment' => 'Kommentar',
-'imagelinks' => 'Dateilinks',
+'imagelinks' => 'Dadaivawendung',
 'linkstoimage' => 'Die {{PLURAL:$1|Said verwaist|$1 Saire verwaise}} uff die Datei:',
 'sharedupload' => 'Die Datei isch vun $1 un s kann sai, dass se ach vun annere Projekt gebraucht werd.',
 'uploadnewversion-linktext' => 'E naiere Version vun derre Datei hochlade',
@@ -431,12 +443,12 @@ Saide uff [[Special:Watchlist|Dainer Beowachdungslischt]] sin '''fett'''.",
 'pager-older-n' => '{{PLURAL:$1|vorich 1|voriche $1}}',
 
 # Book sources
-'booksources' => 'Buchquelle',
+'booksources' => 'Buchqwelle',
 'booksources-search-legend' => 'No Buchquelle suche',
 'booksources-go' => 'Geh',
 
 # Special:Log
-'log' => 'Logbiecher',
+'log' => 'Logbicher',
 
 # Special:AllPages
 'allpages' => 'Alle Saide',
@@ -561,7 +573,7 @@ Der Schutzstatus vun derre Said kannscht ännere, awwer des hot kää Aifluss uf
 'linkshere' => "Die Saide verlinke zu '''[[:$1]]''':",
 'isredirect' => 'Wairerlaitungsaid',
 'istemplate' => 'Vorlacheaibindung',
-'isimage' => 'Bildlink',
+'isimage' => "Dadailing'g",
 'whatlinkshere-prev' => '{{PLURAL:$1|vorich|voriche $1}}',
 'whatlinkshere-next' => '{{PLURAL:$1|negscht|negschte $1}}',
 'whatlinkshere-links' => '← Links',
@@ -575,9 +587,9 @@ Der Schutzstatus vun derre Said kannscht ännere, awwer des hot kää Aifluss uf
 'ipbsubmit' => 'Benutzer bloggiere',
 'ipboptions' => '2 Stunne:2 hours,1 Dach:1 day,3 Dache:3 days,1 Woch:1 week,2 Woche:2 weeks,1 Monet:1 month,3 Monet:3 months,6 Monet:6 months,1 Johr:1 year,Fer immer:infinite',
 'ipusubmit' => 'Die Adreß freigewwe',
-'ipblocklist' => 'Gsperrte IP-Adresse un Benutzername',
+'ipblocklist' => 'Gschberrdi IP-Adress un Benudzernome',
 'blocklink' => 'sperre',
-'unblocklink' => 'Sperr uffhewwe',
+'unblocklink' => 'Sperr uffhewe',
 'change-blocklink' => 'Sperr ännere',
 'contribslink' => 'Baidräch',
 'blocklogpage' => 'Sperrlogbuch',
@@ -663,18 +675,18 @@ Du kannscht awwer de Quelltext aagucke',
 'tooltip-p-logo' => 'Haubdsaid',
 'tooltip-n-mainpage' => 'Uff d Hääptsaid geh',
 'tooltip-n-mainpage-description' => 'Haubdsaid aagucke',
-'tooltip-n-portal' => 'Iwwer s Projekt, was de duu kannscht, wo de ebbes finnscht',
+'tooltip-n-portal' => 'Iwwers Brojegd, wude duu kannschd, wu ebbes finne duschd',
 'tooltip-n-currentevents' => 'hinnergundsinformatione finne iwwer naie Eraichnis',
 'tooltip-n-recentchanges' => 'D Lischt vun de letschte Ännerunge in dem Wiki',
 'tooltip-n-randompage' => 'E zufälliche Said lade',
 'tooltip-n-help' => 'De Ort zum rausfinne',
-'tooltip-t-whatlinkshere' => 'Lischt vun alle Wikisaide, wo do her verlinkt sin',
+'tooltip-t-whatlinkshere' => 'Lischt vun alle Wikisaide, wu do her verlinkt sinn',
 'tooltip-t-recentchangeslinked' => 'Letschte Ännerunge in Saide, wu vun do verlinkt sin',
 'tooltip-feed-rss' => 'RSS feed fer die Said',
 'tooltip-feed-atom' => 'Atom feed fer die Said',
 'tooltip-t-contributions' => 'Die letschte Baidräch vun däm Benutzer aagucke',
 'tooltip-t-emailuser' => 'Dem Benutzer e E-Mail schicke',
-'tooltip-t-upload' => 'Dateie nuflade',
+'tooltip-t-upload' => 'Dateije nufflade',
 'tooltip-t-specialpages' => 'Lischt vun alle Spezialsaide',
 'tooltip-t-print' => 'Druckversion vun derre Said',
 'tooltip-t-permalink' => 'E dauerhafte Link zu derre Version vun de Said',
@@ -691,7 +703,7 @@ Du kannscht awwer de Quelltext aagucke',
 'tooltip-diff' => 'Guck, welle Ännerunge Du im Text gmacht hoscht',
 'tooltip-compareselectedversions' => 'D Unnerschied zwische denne zwai ausgwehlte Versione aagucke',
 'tooltip-watch' => 'Die Said zu Dainer Beowachdunglischd zufieche',
-'tooltip-rollback' => '„Zericksetze“ maxcht alle Bearwaidunge vum letschte Bearwaider rickgängich',
+'tooltip-rollback' => '„Zericksetze“ machd alle Bearwaidunge vum letschte Bearwaider rickgängich',
 'tooltip-undo' => '„Zerick“ macht numme die Ännerung rickgängich un zaicht d Vorschau aa.
 Du kannscht e Grund in dr Zammfassung aagewwe',
 
@@ -722,8 +734,8 @@ Annere Links in der glaiche Zail werre als Ausnahme behannelt, d. h. Saide, wu d
 Wenn die Datei verännert worre isch, dann kann s sai, dass die zusätzlich Information fer die verännert Datei nimmi richtich isch.',
 'metadata-expand' => 'Erwaiterte Details aazaiche',
 'metadata-collapse' => 'Erwaiterte Details versteckeln',
-'metadata-fields' => 'Die EXIF-Metadate werre in de Bild-Bschraiwung ach aagezeicht, wenn d Metadate-Tabelle versteckelt isch.
-Annere Metadate sinn standardmäßig versteckelt.
+'metadata-fields' => 'Die EXIF-Medadaade werren inde Bild-Bschraiwung a ogzaischd, wonn die Medadaade-Tabelle verschdegld isch.
+Annere Medadaade sinn noamalawais verschdegld.
 * make
 * model
 * datetimeoriginal
index 4bd5cc3..8055888 100644 (file)
@@ -806,6 +806,15 @@ A smija che a sia stàita scancelà.',
 'edit-already-exists' => 'As peul nen creesse la pàgina.
 A esist già.',
 'defaultmessagetext' => "Test che a-i sarìa se a-i fusso pa 'd modìfiche",
+'content-failed-to-parse' => "Faliment ëd l'anàlisi dël contnù ëd $2 për ël model $1: $3",
+'invalid-content-data' => 'Dat dël contnù pa bon',
+'content-not-allowed-here' => 'Contnù ëd "$1" pa përmëttù an sla pagina [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'test wiki',
+'content-model-text' => 'mach test',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Atension:''' Costa pàgina a l'ha tròpe ciamà costose a le fonsions ëd parser.
@@ -2266,7 +2275,8 @@ l'avìa travajaje ansima anans che a la scancelèisso.
 'undeletedrevisions' => '{{PLURAL:$1|Na revision pijàita|$1 revision pijàite}} andré',
 'undeletedrevisions-files' => "{{PLURAL:$1|Na|$1}} revision e {{PLURAL:$2|n'|$2&nbsp;}}archivi pijàit andré",
 'undeletedfiles' => "{{PLURAL:$1|N'|$1&nbsp;}}archivi pijàit andaré",
-'cannotundelete' => "Riprìstin falì; a peul esse che i fusse antra doi a felo ant l'istess temp e l'àutr a sia riva prima.",
+'cannotundelete' => 'Riprìstin falì:
+$1',
 'undeletedpage' => "'''$1 a l'é stàit pijait andaré'''
 
 Che as varda ël [[Special:Log/delete|Registr djë scancelament]] për ës-ciairé j'ùltim scancelament e arcuperassion.",
@@ -2570,6 +2580,7 @@ L'artìcol ëd destinassion «[[:$1]]» a-i é già. Veul-lo scancelelo për av
 'immobile-target-namespace-iw' => "Na liura interwiki a l'é pa na destinassion vàlida për tramudé na pàgina.",
 'immobile-source-page' => 'Sta pàgina-sì as peul pa tramudesse.',
 'immobile-target-page' => 'As peul pa tramudesse vers cost tìtol ëd destinassion.',
+'bad-target-model' => 'La destinassion vorsùa a dòvra un model ëd contnù diferent. As peul pa convertisse da $1 a $2.',
 'imagenocrossnamespace' => "As peul pa tramudesse n'archivi a në spassi nominal diferent",
 'nonfile-cannot-move-to-file' => "As peul nen tramudesse lòn ch'a l'é pa n'archivi a lë spassi nominal dj'archivi",
 'imagetypemismatch' => "La neuva estension ëd l'archivi a corispond pa a sò tipo",
@@ -2841,7 +2852,7 @@ Sòn a l'é motobin belfé che a sia rivà përchè a-i era n'anliura a un sit e
 'pageinfo-magic-words' => '{{PLURAL:$1|Paròla màgica|Paròle màgiche}} ($1)',
 'pageinfo-hidden-categories' => '{{PLURAL:$1|Categorìa|Categorìe}} stërmà ($1)',
 'pageinfo-templates' => '{{PLURAL:$1|stamp contnù|stamp contnù}} ($1)',
-'pageinfo-toolboxlink' => 'Anformassion an sla pagina',
+'pageinfo-toolboxlink' => 'Anformassion an sla pàgina',
 
 # Patrolling
 'markaspatrolleddiff' => 'Marché coma verificà',
@@ -3106,8 +3117,8 @@ J'àutri a saran stërmà coma stàndard.
 'exif-webstatement' => "Diciarassion ëd drit d'autor an linia",
 'exif-originaldocumentid' => 'Identificativ ùnich dël papé original',
 'exif-licenseurl' => "Anliura ëd la licensa dij drit d'autor",
-'exif-morepermissionsurl' => 'Anformassion an sle license alternativa',
-'exif-attributionurl' => "Quand as deuvra torna cost travaj, për piasì ch'a-j buta l'anliura a",
+'exif-morepermissionsurl' => 'Anformassion an sle license alternative',
+'exif-attributionurl' => "An dovrand n'àutra vira cost travaj, për piasì ch'a-j buta l'anliura a",
 'exif-preferredattributionname' => "Quand as deuvra torna cost travaj, për piasì dé l'arconossiment a",
 'exif-pngfilecomment' => "Coment ëd l'archivi PNG",
 'exif-disclaimer' => 'Avis',
@@ -3119,11 +3130,11 @@ J'àutri a saran stërmà coma stàndard.
 'exif-event' => 'Event fotografà',
 'exif-organisationinimage' => 'Organisassion fotografà',
 'exif-personinimage' => 'Përson-a fotografà',
-'exif-originalimageheight' => "Autëssa dla figura prima ch'a sia ritajà",
-'exif-originalimagewidth' => "Larghëssa dla figura prima ch'a sia ritajà",
+'exif-originalimageheight' => "Autëssa dla figura prima ch'a fussa ritajà",
+'exif-originalimagewidth' => "Larghëssa dla figura prima ch'a fussa ritajà",
 
 # EXIF attributes
-'exif-compression-1' => 'Pa compress',
+'exif-compression-1' => 'Nen comprimù',
 'exif-compression-2' => "CCITT Partìa 3 longheur dla codìfica d'esecussion dla codìfica Huffman modificà ëd dimension 1",
 'exif-compression-3' => 'CCITT Partìa 3 codìfica dël fax',
 'exif-compression-4' => 'CCITT Partìa 4 codìfica dël fax',
@@ -3134,10 +3145,10 @@ J'àutri a saran stërmà coma stàndard.
 'exif-unknowndate' => 'Data nen conossùa',
 
 'exif-orientation-1' => 'Normal',
-'exif-orientation-2' => 'Specolar',
+'exif-orientation-2' => 'A specc',
 'exif-orientation-3' => 'Arvirà ëd 180°',
-'exif-orientation-4' => 'Arvirà dzorsuta',
-'exif-orientation-5' => 'Arvirà dzorsota e ëd 90° contramostra',
+'exif-orientation-4' => 'Arvirà dzor-sota',
+'exif-orientation-5' => 'Arvirà dzor-sota e ëd 90° contramostra',
 'exif-orientation-6' => 'Arvirà ëd 90° contramostra',
 'exif-orientation-7' => 'Arvirà dzorsota e ëd 90° ant ël sens dla mostra',
 'exif-orientation-8' => 'Arvirà ëd 90° ant ël sens dla mostra',
index 30e1ec1..981bd81 100644 (file)
@@ -1035,7 +1035,9 @@ Example: [http://translatewiki.net/w/i.php?title=Project:News&oldid=9999999 Perm
 'explainconflict' => 'Appears at the top of a page when there is an edit conflict.',
 'storedversion' => 'This is used in an edit conflict as the label for the top revision that has been stored, as opposed to your version that has not been stored which is shown at the bottom of the page.',
 'yourdiff' => '',
-'copyrightwarning' => 'Copyright warning displayed under the edit box in editor',
+'copyrightwarning' => 'Copyright warning displayed under the edit box in editor
+*$1 - ...
+*$2 - ...',
 'longpageerror' => 'Warning displayed when trying to save a text larger than the maximum size allowed',
 'protectedpagewarning' => '{{Related|Semiprotectedpagewarning}}',
 'semiprotectedpagewarning' => '{{Related|Semiprotectedpagewarning}}',
@@ -1060,11 +1062,36 @@ Please report at [[Support]] if you are unable to properly translate this messag
 'moveddeleted-notice' => 'Shown on top of a deleted page in normal view modus ([http://translatewiki.net/wiki/Test example]).',
 'edit-conflict' => "An 'Edit conflict' happens when more than one edit is being made to a page at the same time. This would usually be caused by separate individuals working on the same page. However, if the system is slow, several edits from one individual could back up and attempt to apply simultaneously - causing the conflict.",
 'defaultmessagetext' => 'Caption above the default message text shown on the left-hand side of a diff displayed after clicking “Show changes” when creating a new page in the MediaWiki: namespace',
-'content-failed-to-parse' => "Error message indicating that the page\'s content can not be saved because it is syntactically invalid. This may occurr for content types using serialization or a strict markup syntax.",
-'invalid-content-data'             => 'Error message indicating that the page\'s content can not be saved because it is invalid. This may occurr for content types with internal consistency constraints.',
-'content-not-allowed-here'         => 'Error message indicating that the desired content model is not supported in given localtion.
-* $1 is the human readable name of the content model
-* $1 is the title of the page in question.',
+'content-failed-to-parse' => "Error message indicating that the page's content can not be saved because it is syntactically invalid. This may occurr for content types using serialization or a strict markup syntax.
+*$1 – content model ({{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}})
+*$2 – content format as MIME type (e.g. <tt>text/css</tt>)
+*$3 – specific error message",
+'invalid-content-data' => "Error message indicating that the page's content can not be saved because it is invalid. This may occurr for content types with internal consistency constraints.",
+'content-not-allowed-here' => 'Error message indicating that the desired content model is not supported in given localtion.
+* $1 is the human readable name of the content model: {{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}
+* $2 is the title of the page in question.',
+
+# Content models
+'content-model-wikitext' => 'Name for the wikitext content model, used when decribing what type of content a page contains.
+
+This message is substituted in:
+*{{msg-mw|Bad-target-model}}
+*{{msg-mw|Content-not-allowed-here}}',
+'content-model-text' => 'Name for the plain text content model, used when decribing what type of content a page contains.
+
+This message is substituted in:
+*{{msg-mw|Bad-target-model}}
+*{{msg-mw|Content-not-allowed-here}}',
+'content-model-javascript' => 'Name for the JavaScript content model, used when decribing what type of content a page contains.
+
+This message is substituted in:
+*{{msg-mw|Bad-target-model}}
+*{{msg-mw|Content-not-allowed-here}}',
+'content-model-css' => 'Name for the CSS content model, used when decribing what type of content a page contains.
+
+This message is substituted in:
+*{{msg-mw|Bad-target-model}}
+*{{msg-mw|Content-not-allowed-here}}',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'On some (expensive) [[MetaWikipedia:Help:ParserFunctions|parser functions]] (e.g. <code><nowiki>{{#ifexist:}}</nowiki></code>) there is a limit of how many times it may be used. This is an error message shown when the limit is exceeded.
@@ -3200,10 +3227,12 @@ Parameters:
 'immobile-target-namespace-iw' => "This message appears when attempting to move a page, if a person has typed an interwiki link as a namespace prefix in the input box labelled 'To new title'.  The special page 'Movepage' cannot be used to move a page to another wiki.
 
 'Destination' can be used instead of 'target' in this message.",
-'bad-target-model'             => "This message is shown when attempting to move a page, but the move would change the page's content model.
-This may be the case when \$wgContentHandlerUseDB is set to false, because then a page's content model is derived from the page's title.
-* $1: The localized name of the original page's content model.
-* $2: The localized name of the content model used by the destination title.",
+'bad-target-model' => 'This message is shown when attempting to move a page, but the move would change the page\'s content model.
+This may be the case when [[mw:Manual:$wgContentHandlerUseDB|$wgContentHandlerUseDB]] is set to false, because then a page\'s content model is derived from the page\'s title.
+* $1: The localized name of the original page\'s content model:
+**{{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}
+* $2: The localized name of the content model used by the destination title:
+**{{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}',
 'fix-double-redirects' => 'This is a checkbox in [[Special:MovePage]] which allows to move all redirects from the old title to the new title.',
 'protectedpagemovewarning' => 'Related message: [[MediaWiki:protectedpagewarning/{{#titleparts:{{PAGENAME}}|1|2}}]]
 {{Related|Semiprotectedpagewarning}}',
@@ -3482,6 +3511,7 @@ See also {{msg-mw|Anonuser}} and {{msg-mw|Siteusers}}.',
 # Info page
 'pageinfo-title' => 'Page title for action=info. Parameters:
 * $1 is the page name',
+'pageinfo-not-current' => 'Error message displayed when information for an old revision is requested.',
 'pageinfo-header-basic' => 'Table section header in action=info.',
 'pageinfo-header-edits' => 'Table section header in action=info.',
 'pageinfo-header-restrictions' => 'Table section header in action=info.',
@@ -4913,10 +4943,4 @@ $4 is the gender of the target user.',
 'api-error-uploaddisabled' => 'API error message that can be used for client side localisation of API errors.',
 'api-error-verification-error' => 'The word "extension" refers to the part behind the last dot in a file name, that by convention gives a hint about the kind of data format which a files contents are in.',
 
-# Content model IDs for the ContentHandler facility; used by ContentHandler::getContentModel()
-'content-model-wikitext' => 'Name for the wikitext content model, used when decribing what type of content a page contains.',
-'content-model-javascript' => 'Name for the JavaScript content model, used when decribing what type of content a page contains.',
-'content-model-css' => 'Name for the CSS content model, used when decribing what type of content a page contains.',
-'content-model-text' => 'Name for the plain text content model, used when decribing what type of content a page contains.',
-
 );
index 88fbdca..dd972bb 100644 (file)
@@ -1077,6 +1077,15 @@ Se pare că a fost ștearsă.',
 'edit-already-exists' => 'Pagina nouă nu a putut fi creată.
 Ea există deja.',
 'defaultmessagetext' => 'Textul implicit',
+'content-failed-to-parse' => 'Nu s-a putut analiza conținutul de tip $2 pentru modelul $1: $3',
+'invalid-content-data' => 'Date de conținut invalide',
+'content-not-allowed-here' => 'Conținutul de tip „$1” nu este permis pe pagina [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitext',
+'content-model-text' => 'text simplu',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Atenție: Această pagină conține prea multe apelări costisitoare ale funcțiilor parser.
@@ -2529,7 +2538,8 @@ S-ar putea ca legătura să fie greșită, ori versiunea să fi fost restaurată
 'undeletedrevisions' => '{{PLURAL:$1|o versiune restaurată|$1 versiuni restaurate|$1 de versiuni restaurate}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|O versiune|$1 versiuni|$1 de versiuni}} și {{PLURAL:$2|un fișier|$2 fișiere|$2 de fișiere}} recuperate',
 'undeletedfiles' => '{{PLURAL:$1|O versiune recuperată|$1 versiuni recuperate|$1 de versiuni recuperate}}',
-'cannotundelete' => 'Recuperarea a eșuat; este posibil ca altcineva să fi recuperat pagina deja.',
+'cannotundelete' => 'Recuperarea a eșuat:
+$1',
 'undeletedpage' => "'''$1 a fost recuperat'''
 
 Consultați [[Special:Log/delete|jurnalul ștergerilor]] pentru a vedea toate ștergerile și recuperările recente.",
@@ -2841,6 +2851,7 @@ Pagina destinație „[[:$1]]” există deja. Doriți să o ștergeți pentru a
 'immobile-target-namespace-iw' => 'Legătura interwiki nu este o țintă validă pentru redenumire.',
 'immobile-source-page' => 'Această pagină nu poate fi redenumită.',
 'immobile-target-page' => 'Imposibil de redenumit pagina la acel titlu.',
+'bad-target-model' => 'Destinația dorită folosește un alt model de conținut. Nu se poate converti $1 în $2.',
 'imagenocrossnamespace' => 'Fișierul nu poate fi mutat la un spațiu de nume care nu este destinat fișierelor',
 'nonfile-cannot-move-to-file' => 'Entitatea (care nu este un fișier) nu poate fi mutată în spațiul de nume destinat fișierelor',
 'imagetypemismatch' => 'Extensia nouă a fișierului nu se potrivește cu tipul acestuia',
index e6a1910..39bd1d2 100644 (file)
@@ -1075,7 +1075,7 @@ $2
 'viewpagelogs' => 'अस्य पृष्ठस्य लॉंग् इत्येतद् दर्शयतु',
 'nohistory' => 'अस्य पृष्ठस्य कृते पृष्ठेतिहासः न वर्तते।',
 'currentrev' => 'सद्यःकालीना आवृत्तिः',
-'currentrev-asof' => 'वरà¥\8dतमतà¥\80 आवृत्तिः $1 इति समये',
+'currentrev-asof' => 'वरà¥\8dतमाना आवृत्तिः $1 इति समये',
 'revisionasof' => '$1 इत्यस्य आवृत्तिः',
 'revision-info' => '$1इति समयस्य आवृत्तिः $2 इत्यनेन',
 'previousrevision' => '← पुरातनानि संस्करणानि',
@@ -1889,7 +1889,7 @@ See https://www.mediawiki.org/wiki/Manual:Image_Authorization.',
 'filehist-current' => 'सद्योजातम्',
 'filehist-datetime' => 'दिनाङ्कः/समयः',
 'filehist-thumb' => 'अंगुष्ठनखाकारम्',
-'filehist-thumbtext' => '$1 à¤¸à¤®à¤¯à¥\87 à¤µà¤¿à¤¦à¥\8dयमतà¥\8dयाः आवृत्तेः अंगुष्ठनखाकारम्',
+'filehist-thumbtext' => '$1 à¤¸à¤®à¤¯à¥\87 à¤µà¤¿à¤¦à¥\8dयमानायाः आवृत्तेः अंगुष्ठनखाकारम्',
 'filehist-nothumb' => 'अङ्गुष्टनखाकारकं नाश्ति ।',
 'filehist-user' => 'योजकः',
 'filehist-dimensions' => 'आयामाः',
index c7ed509..2ac8d0f 100644 (file)
@@ -866,7 +866,6 @@ $2
 * '''ෆයර්ෆොක්ස්/ සෆාරි:''' ''Reload'' ඔබන අතරතුර ''Shift'' ඔබන්න, නැතහොත්  ''Ctrl-F5'' හෝ''Ctrl-R'' (මැක්හීදී ''Command-R'' ) ඔබන්න
 * '''ගූගල් ක්‍රෝම්:''' ''Ctrl-Shift-R'' ඔබන්න(මැක්හී ''Command-Shift-R'' )
 * '''ඉන්ටර්නෙට් එක්ස්ප්ලෝර:''' ''Refresh'' ඔබන අතරතුර  ''Ctrl''  ඔබන්න, නැතහොත් ''Ctrl-F5'' ඔබන්න
-* '''කොන්කරර්:''' ''Reload'' ඔබන්න හෝ  ''F5'' ඔබන්න
 * '''ඔපෙරා:''' ''Tools → Preferences'' හි කෑෂය හිස් කරන්න",
 'usercssyoucanpreview' => "'''හෝඩුවාව:'''සුරැකුමට පෙර, ඔබගේ නව  CSS පරික්ෂා කරනු වස්, \"{{int:පෙර-දසුන පෙන්වන්න}}\" බොත්තම භාවිතා කරන්න.",
 'userjsyoucanpreview' => "'''හෝඩුවාව:'''සුරැකුමට පෙර, ඔබගේ නව  ජාවා ස්ක්‍රිප්ට් පරික්ෂා කරනු වස්, \"{{int:පෙර-දසුන පෙන්වන්න}}\" බොත්තම භාවිතා කරන්න.",
@@ -1115,7 +1114,8 @@ $1",
 'revdelete-only-restricted' => '$2 දිනැති අයිතමය සැඟවීමේ දෝෂය , $1:අනෙකුත් සැඟවීම් විකල්පයන් අතුරින් එකක් තෝරාගන්නේ නැතිව, පරිපාලකයන්ගේ දර්ශනයෙන් අයිතමයන් සැඟවීම  ඔබහට සිදුකල නොහැක.',
 'revdelete-reason-dropdown' => '*මකා දැමීමේ පොදු හේතු
 **කතු හිමිකම් උල්ලංඝනය
-**නුසුදුසු පුද්ගලික කොරතුරු
+**නුසුදුසු පරිකථන හෝ පුද්ගලික කොරතුරු
+**නුසුදුසු පරිශීලක නම
 **අපහාසාත්මක විය හැකි තොරතුරු',
 'revdelete-otherreason' => 'වෙනත්/අමතර හේතු:',
 'revdelete-reasonotherlist' => 'වෙනත් හේතු',
@@ -1125,7 +1125,7 @@ $1",
 # Suppression log
 'suppressionlog' => 'යටපත්කිරීම් පිළිබඳ සටහන',
 'suppressionlogtext' => 'පරිපාලකයන්ගෙන් සැඟවුනු අන්තර්ගතය සම්බන්ධ මකාදැමීම් හා වාරණ ලැයිස්තුවක් මෙහි පහත දැක්වේ.
-දà·\90නට à¶\9aà·\8aâ\80\8dරà·\92යà·\8fතà·\8aමà¶\9a à·\80න à¶­à·\84නමà·\8a à·\84à·\8f à·\80à·\8fරණයනà·\8a à¶½à·\90යà·\92à·\83à·\8aතà·\94à·\80à¶\9aà·\8a à·\83ඳà·\84à·\8f [[Special:BlockList|à\85නà·\8aතරà·\8aජà·\8fල à·\80à·\8fරණ à¶½à·\90යà·\92à·\83à·\8aතà·\94à·\80]] à¶¶à¶½à¶±à·\8aන.',
+දැනට ක්‍රියාත්මක වන තහනම් හා වාරණයන් ලැයිස්තුවක් සඳහා [[Special:BlockList|වාරණ ලැයිස්තුව]] බලන්න.',
 
 # History merging
 'mergehistory' => 'පිටු ඉතිහාසයන් ඒකාබද්ධ කරන්න',
@@ -1732,7 +1732,7 @@ URLහි නීතික බව හා ප්‍රවේශ්‍ය බව 
 'backend-fail-create' => '$1 ගොනුව ලිවිය නොහැකි විය.',
 'backend-fail-maxsize' => '{{PLURAL:$2|බයිට එකකට|බයිට $2 කට}} වඩා විහාල බැවින්  $1 ගොනුව ලිවිය නොහැකි විය.',
 'backend-fail-readonly' => 'ගබඩා බැක්එන්ඩය "$1" දැනට කියවීම-පමණක් සඳහා වෙයි. දක්වා ඇති හේතුව නම්: "\'\'$2\'\'"',
-'backend-fail-usable' => 'අවසර ප්‍රමාණවත් නොවීම නිසාවෙන් හෝ නාමාවලී/බහාලුම් නොමැති වීම නිසාවෙන් $1 ගොනුව ලිවිය නොහැකි විය.',
+'backend-fail-usable' => 'අවසර ප්‍රමාණවත් නොවීම නිසාවෙන් හෝ නාමාවලී/බහාලුම් නොමැති වීම නිසාවෙන් "$1" ගොනුව කියවිය හෝ ලිවිය හෝ නොහැකි විය.',
 
 # Lock manager
 'lockmanager-notlocked' => '"$1" හී අගුළු ඇරිය නොහැක; එය අගුළු දමාද නොමැත.',
index 5fcadbf..712c6c1 100644 (file)
@@ -439,7 +439,7 @@ $messages = array(
 'vector-action-protect' => 'Zamknúť',
 'vector-action-undelete' => 'Obnoviť',
 'vector-action-unprotect' => 'Zmeniť stav ochrany',
-'vector-simplesearch-preference' => 'Povoliť rozšírené návrhy hľadania (iba pre tému Vector)',
+'vector-simplesearch-preference' => 'Povoliť zjednodušené pole hľadania (iba pre tému Vector)',
 'vector-view-create' => 'Vytvoriť',
 'vector-view-edit' => 'Upraviť',
 'vector-view-history' => 'Zobraziť históriu',
@@ -659,8 +659,11 @@ Požiadavka: $2',
 'protectedpagetext' => 'Táto stránka bola zamknutá aby sa zamedzilo úpravám.',
 'viewsourcetext' => 'Môžete si zobraziť a kopírovať zdroj tejto stránky:',
 'viewyourtext' => "Môžete si prehliadnuť a skopírovať zdrojový kód '''vašich zmien''' tejto stránky:",
-'protectedinterface' => 'Táto stránka poskytuje text používateľského rozhrania a je zamknutá, aby sa predišlo jej zneužitiu.',
-'editinginterface' => "'''Upozornenie:''' Upravujete stránku, ktorá poskytuje text používateľského rozhrania. Zmeny tejto stránky ovplyvnia vzhľad používateľského rozhrania ostatných používateľov. Zmeny prosím vykonávajte prostredníctvom [//translatewiki.net/wiki/Main_Page?setlang=sk translatewiki.net], projektu pre lokalizáciu MediaWiki.",
+'protectedinterface' => 'Táto stránka poskytuje text používateľského rozhrania tejto wiki a je zamknutá, aby sa predišlo jej zneužitiu.
+Ak chcete pridať alebo zmeniť preklady pre všetky wiki, prosím, použite [//translatewiki.net/wiki/Main_Page?setlang=sk translatewiki.net], projekt lokalizácie MediaWiki.',
+'editinginterface' => "'''Upozornenie:''' Upravujete stránku, ktorá poskytuje text používateľského rozhrania.
+Zmeny tejto stránky ovplyvnia vzhľad používateľského rozhrania ostatným používateľom.
+Ak chcete pridať alebo zmeniť preklady pre všetky wiki, prosím, použite [//translatewiki.net/wiki/Main_Page?setlang=sk translatewiki.net], projekt lokalizácie MediaWiki.",
 'sqlhidden' => '(SQL príkaz je skrytý)',
 'cascadeprotected' => 'Táto stránka bola zamknutá proti úpravám, pretože je použitá na {{PLURAL:$1|nasledovnej stránke, ktorá je zamknutá|nasledovných stránkach, ktoré sú zamknuté}} voľbou „kaskádového zamknutia“:
 $2',
@@ -950,7 +953,7 @@ Môžete [[Special:Search/{{PAGENAME}}|vyhľadávať názov tejto stránky]] v o
 alebo [{{fullurl:{{FULLPAGENAME}}|action=edit}} upravovať túto stránku]</span>.',
 'noarticletext-nopermission' => 'Táto stránka momentálne neobsahuje žiadny text.
 Môžete [[Special:Search/{{PAGENAME}}|hľadať názov tejto stránky]] v texte iných stránok
-alebo <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} si pozrieť súvisiace záznamy]</span>.',
+alebo <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hľadať v súvisiacich záznamoch]</span>, ale nemáte oprávnenie túto stránku vytvoriť.',
 'missing-revision' => 'Revízia #$1 stránky s názvom „{{PAGENAME}}“ neexistuje.
 
 Pravdepodobne ste nasledovali zastaraný odkaz na historickú verziu stránky, ktorá bola medzičasom odstránená.
@@ -1057,6 +1060,15 @@ Zdá sa, že bola zmazaná.',
 'edit-already-exists' => 'Nebolo možné vytvoriť novú stránku.
 Už existuje.',
 'defaultmessagetext' => 'Predvolený text správy',
+'content-failed-to-parse' => 'Nepodarilo sa spracovať obsah $2 pre model $1: $3',
+'invalid-content-data' => 'Neplatné dáta obsahu',
+'content-not-allowed-here' => 'Obsah „$1“ nie je povolený na stránke [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitext',
+'content-model-text' => 'čistý text',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Upozornenie: Táto stránka obsahuje príliš mnoho volaní funkcií syntaktického analyzátora, ktoré nadmerne zaťažujú server.
@@ -1078,6 +1090,7 @@ Tieto argumenty boli vynechané.',
 'expansion-depth-exceeded-warning' => 'Stránka prekročila povolenú hĺbku expanzie',
 'parser-unstrip-loop-warning' => 'Zistené zacyklenie volania rozširovacej značky',
 'parser-unstrip-recursion-limit' => 'Prektočený limit rekurzie volania rozširovacej značky ($1)',
+'converter-manual-rule-error' => 'Bola zistená chyba v pravidle manuálnej konverzie jazyka',
 
 # "Undo" feature
 'undo-success' => 'Úpravu je možné vrátiť. Prosím skontrolujte tento rozdiel, čím overíte, že táto úprava je tá, ktorú chcete, a následne uložte zmeny, čím ukončíte vrátenie.',
@@ -1405,7 +1418,7 @@ Tu je náhodne vytvorená hodnota, ktorú môžete použiť: $1',
 'timezoneregion-indian' => 'Indický oceán',
 'timezoneregion-pacific' => 'Tichý oceán',
 'allowemail' => 'Povoliť prijímanie e-mailov od iných používateľov',
-'prefs-searchoptions' => 'Voľby hľadania',
+'prefs-searchoptions' => 'Hľadanie',
 'prefs-namespaces' => 'Menné priestory',
 'defaultns' => 'Inak vyhľadávať v týchto menných priestoroch:',
 'default' => 'predvolený',
@@ -2495,7 +2508,8 @@ Ak bola od zmazania vytvorená nová stránka s rovnakým názvom, obnovené rev
 'undeletedrevisions' => '{{PLURAL:$1|jedna verzia bola obnovená|$1 verzie boli obnovené|$1 verzií bolo obnovených}}',
 'undeletedrevisions-files' => '{{PLURAL:$1|Jedna revízia|$1 revízie|$1 revízií}} a {{PLURAL:$2|jeden súbor bol obnovený|$2 súbory boli obnovené|$2 súborov bolo obnovených}}',
 'undeletedfiles' => '{{PLURAL:$1|Jeden súbor bol obnovený|$1 súbory boli obnovené|$1 súborov bolo obnovených}}',
-'cannotundelete' => 'Obnovenie sa nepodarilo; pravdepodobne niekto iný obnovil stránku skôr ako vy.',
+'cannotundelete' => 'Obnovenie sa nepodarilo:
+$1',
 'undeletedpage' => "'''$1 bol obnovený'''
 
 Zoznam posledných mazaní a obnovení nájdete v [[Special:Log/delete|Zázname mazaní]].",
@@ -2809,6 +2823,7 @@ Cieľová stránka „[[:$1]]“ už existuje. Chcete ho vymazať a vytvoriť ta
 'immobile-target-namespace-iw' => 'Interwiki odkaz nie je platným cieľom na presun stránky.',
 'immobile-source-page' => 'Túto stránku nemožno presunúť.',
 'immobile-target-page' => 'Nie je možné presunúť na cieľovú stránku z daným názvom.',
+'bad-target-model' => 'Požadovaný cieľ používa iný model obsahu. Nie je možné konvertovať z $1 na $2.',
 'imagenocrossnamespace' => 'Obrázok nemožno presunúť mimo menného priestoru obrázkov',
 'nonfile-cannot-move-to-file' => 'Nie je možné presunúť objekt, ktorý nie je súbor do menného priestoru Súbor',
 'imagetypemismatch' => 'Nová prípona súboru nezodpovedá jeho typu',
@@ -2887,6 +2902,7 @@ Všetky transwiki importy sa zaznamenávajú v [[Special:Log/import|Zázname imp
 'import-interwiki-templates' => 'Vložiť všetky šablóny',
 'import-interwiki-submit' => 'Importovať',
 'import-interwiki-namespace' => 'Cieľový menný priestor:',
+'import-interwiki-rootpage' => 'Koreňová stránka cieľa (nepovinné):',
 'import-upload-filename' => 'Názov súboru:',
 'import-comment' => 'komentár:',
 'importtext' => 'Prosím, exportujte súbor zo zdrojovej wiki použitím [[Special:Export|nástroja na export]].
@@ -2919,6 +2935,9 @@ Uložte ho na svoj disk a nahrajte sem.',
 'import-error-interwiki' => 'Stránka „$1“ nie je importovaná, pretože jej názov je vyhradený pre externé odkazy (interwiki).',
 'import-error-special' => 'Stránka „$1“ nie je importovaná, pretože patrí do špeciálneho menného priestoru, ktorý nepovoľuje stránky.',
 'import-error-invalid' => 'Stránka „$1“ nie je importovaná, pretože jej názov je neplatný.',
+'import-options-wrong' => '{{PLURAL:$2|Nesprávna voľba|Nesprávne voľby}}: <nowiki>$1</nowiki>',
+'import-rootpage-invalid' => 'Uvedená koreňová stránka nie je platný názov stránky.',
+'import-rootpage-nosubpage' => 'Menný priestor „$1“ koreňovej stránky nepodporuje podstránky.',
 
 # Import log
 'importlogpage' => 'Záznam importov',
@@ -3072,12 +3091,32 @@ Pravdepodobne to spôsobil odkaz na externú internetovú lokalitu, ktorá sa na
 'pageinfo-title' => 'Informácie o „$1“',
 'pageinfo-header-basic' => 'Základné údaje',
 'pageinfo-header-edits' => 'História úprav',
+'pageinfo-header-restrictions' => 'Ochrana stránky',
+'pageinfo-header-properties' => 'Vlastnosti stránky',
+'pageinfo-display-title' => 'Zobraziť názov',
+'pageinfo-default-sort' => 'Predvolený kľúč zoraďovania:',
+'pageinfo-length' => 'Dĺžka stránky (v bajtoch)',
 'pageinfo-article-id' => 'ID stránky',
+'pageinfo-robot-policy' => 'Stav vyhľadávača',
+'pageinfo-robot-index' => 'Indexovať stránku',
+'pageinfo-robot-noindex' => 'Neindexovať stránku',
 'pageinfo-views' => 'Počet zobrazení',
-'pageinfo-watchers' => 'Počet sledovateľov',
+'pageinfo-watchers' => 'Počet používateľov sledujúcich stránku',
+'pageinfo-redirects-name' => 'Presmerovania na túto stránku',
+'pageinfo-subpages-name' => 'Podstránky tejto stránky',
+'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|presmerovanie|presmerovania|presmerovaní}}; $3 {{PLURAL:$3|nie je presmerovanie|nie sú presmerovania}})',
+'pageinfo-firstuser' => 'Tvorca stránky',
+'pageinfo-firsttime' => 'Dátum vytvorenia stránky',
+'pageinfo-lastuser' => 'Naposledy upravil',
 'pageinfo-lasttime' => 'Dátum poslednej úpravy',
 'pageinfo-edits' => 'Celkový počet úprav',
 'pageinfo-authors' => 'Celkový počet autorov',
+'pageinfo-recent-edits' => 'Počet nedávnych úprav (za posledných $1)',
+'pageinfo-recent-authors' => 'Počet nedávnych jedinečných autorov',
+'pageinfo-magic-words' => 'Magické {{PLURAL:$1|slovo|slová}} ($1)',
+'pageinfo-hidden-categories' => '{{PLURAL:$1|Skrytá kategória|Skryté kategórie}} ($1)',
+'pageinfo-templates' => '{{PLURAL:$1|Vložená šablóna|Vložené šablóny}} ($1)',
+'pageinfo-toolboxlink' => 'Informácie o stránke',
 
 # Skin names
 'skinname-standard' => 'Klasický',
@@ -3132,6 +3171,7 @@ Jeho spustením môžete kompromitovať svoj systém.",
 'file-info-size-pages' => '$1 × $2 pixlov, veľkosť súboru: $3, typ MIME: $4, $5 {{PLURAL:$5|stránka|stránky|stránok}}',
 'file-nohires' => 'Nie je dostupné vyššie rozlíšenie.',
 'svg-long-desc' => 'SVG súbor, $1 × $2 pixelov, veľkosť súboru: $3',
+'svg-long-desc-animated' => 'Animovaný súbor SVG, nominálne $1 × $2 pixlov, veľkosť súboru: $3',
 'show-big-image' => 'Obrázok vo vyššom rozlíšení',
 'show-big-image-preview' => 'Veľkosť tohto náhľadu: $1.',
 'show-big-image-other' => 'Iné {{PLURAL:$2|rozlíšenie|rozlíšenia}}: $1 .',
@@ -3141,6 +3181,8 @@ Jeho spustením môžete kompromitovať svoj systém.",
 'file-info-png-looped' => 'opakované',
 'file-info-png-repeat' => 'prehrané $1-krát{{PLURAL:$1|||}}',
 'file-info-png-frames' => '$1 {{PLURAL:$1|rámec|rámce|rámcov}}',
+'file-no-thumb-animation' => "'''Pozn.: Z dôvodu technických obmedzení nebudú náhľady tohto súboru animované.'''",
+'file-no-thumb-animation-gif' => "'''Pozn.: Z dôvodu technických obmedzení nebudú náhľady súborov GIF vo vysokom rozlíšení (ako je tento súbor) animované.'''",
 
 # Special:NewFiles
 'newimages' => 'Galéria nových obrázkov',
@@ -3661,6 +3703,7 @@ Platnosť tohto potvrdzovacieho kódu vyprší $4.',
 # Scary transclusion
 'scarytranscludedisabled' => '[Transklúzia interwiki je vypnutá]',
 'scarytranscludefailed' => '[Nepodarilo sa priniesť šablónu pre $1]',
+'scarytranscludefailed-httpstatus' => '[Stiahnutie šablóny zlyhalo pre $1: HTTP $2]',
 'scarytranscludetoolong' => '[URL je príliš dlhé]',
 
 # Delete conflict
index ea0db4d..4faee60 100644 (file)
@@ -973,6 +973,12 @@ Izgleda, da je bila izbrisana.',
 'edit-already-exists' => 'Ni bilo mogoče ustvariti nove strani, ker že obstaja.',
 'defaultmessagetext' => 'Prednastavljeno besedilo',
 
+# Content models
+'content-model-wikitext' => 'wikibesedilo',
+'content-model-text' => 'golo besedilo',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''Opozorilo:''' Ta stran vsebuje preveč klicev funkcije razčlenjevalnika kode.
 
@@ -1836,8 +1842,8 @@ Prosimo, ponovno preverite pravilnost URL-a in delovanje strani.',
 Prosimo, preverite delovanje strani, počakajte kratek čas in poskusite ponovno.
 Morda želite poskusiti ob času manjše zasedenosti.',
 
-'license' => 'Dovoljenje:',
-'license-header' => 'Dovoljenje',
+'license' => 'Licenca:',
+'license-header' => 'Licenca',
 'nolicense' => 'Nobeno',
 'license-nopreview' => '(Predogled ni na voljo)',
 'upload_source_url' => ' (veljaven, javnosti dostopen URL)',
@@ -1905,7 +1911,7 @@ Morda želite urediti njeno opisno stran na tamkajšnji [$2 opisni strani datote
 'filerevert-legend' => 'Vrni datoteko',
 'filerevert-intro' => "Vračate datoteko '''[[Media:$1|$1]]''' na [$4 različico $3, $2].",
 'filerevert-comment' => 'Razlog:',
-'filerevert-defaultcomment' => 'Vrnjeno na različico $2, $1',
+'filerevert-defaultcomment' => 'Vrnjeno na različico $2, $1.',
 'filerevert-submit' => 'Vrni',
 'filerevert-success' => "Datoteka '''[[Media:$1|$1]]''' je bila vrnjena na [$4 različico $3, $2].",
 'filerevert-badversion' => 'Ne najdem preteklih lokalnih verzij datoteke s podanim časovnim žigom.',
@@ -2312,7 +2318,7 @@ Za zapise nedavnih brisanj glej $2.',
 'dellogpage' => 'Dnevnik brisanja',
 'dellogpagetext' => 'Spodaj je prikazan seznam nedavnih brisanj.',
 'deletionlog' => 'dnevnik brisanja',
-'reverted' => 'Obnovljeno na prejšnjo redakcijo',
+'reverted' => 'Vrnjeno na prejšnjo redakcijo.',
 'deletecomment' => 'Razlog:',
 'deleteotherreason' => 'Drugi/dodatni razlogi:',
 'deletereasonotherlist' => 'Drug razlog',
@@ -2447,8 +2453,8 @@ Morda imate napačno povezavo ali pa je bila redakcija obnovljena ali odstranjen
 'undeletedrevisions' => '{{PLURAL:$1|obnovljena $1 redakcija|obnovljeni $1 redakciji|obnovljene $1 redakcije|obnovljenih $1 redakcij}}',
 'undeletedrevisions-files' => '$1 {{PLURAL:$1|redakcija|redakciji|redakcije|redakcij}} in $2 {{PLURAL:$2|datoteka|datoteki|datoteke|datotek}} {{PLURAL:$1+$2|obnovljena|obnovljeni|obnovljene|obnovljenih}}',
 'undeletedfiles' => '{{PLURAL:$1|obnovljena je $1 datoteka|obnovljeni sta $1 datoteki|obnovljene so $1 datoteke|obnovljenih je $1 datotek}}',
-'cannotundelete' => 'Obnova ni uspela;
-morda je stran obnovil že kdo drug.',
+'cannotundelete' => 'Obnova je spodletela:
+$1',
 'undeletedpage' => "'''Obnovili ste stran $1.'''
 
 Nedavna brisanja in obnove so zapisani v [[Special:Log/delete|dnevniku brisanja]].",
@@ -2959,7 +2965,7 @@ Prosimo, poskusite znova.',
 'tooltip-watchlistedit-raw-submit' => 'Posodobi spisek nadzorov',
 'tooltip-recreate' => 'Ponovno ustvari stran, čeprav je bila izbrisana',
 'tooltip-upload' => 'Pričnite z nalaganjem',
-'tooltip-rollback' => 'Funkcija »Vrni« z enim klikom povrne vsa urejanja zadnjega urejevalca te strani',
+'tooltip-rollback' => 'Možnost »Vrni« z enim klikom povrne vsa urejanja zadnjega urejevalca te strani.',
 'tooltip-undo' => '"Razveljavi" vrne to urejanje in odpre predogled v oknu za urejanje.
 Omogoča vnos pojasnila v povzetku urejanja.',
 'tooltip-preferences-save' => 'Shrani nastavitve',
@@ -3061,7 +3067,7 @@ Z njenim zagonom lahko ogrozite vaš sistem.",
 'file-info' => 'Velikost datoteke: $1, MIME-vrsta: <code>$2</code>',
 'file-info-size' => '$1 × $2 točk, velikost datoteke: $3, vrsta MIME: $4',
 'file-info-size-pages' => '$1 × $2 točk, velikost datoteke: $3, vrsta MIME: $4, $5 {{PLURAL:$5|stran|strani}}',
-'file-nohires' => 'Višja ločljivost slike ni na razpolago.',
+'file-nohires' => 'Višja ločljivost slike ni na voljo.',
 'svg-long-desc' => 'datoteka SVG, v izvirniku $1 × $2 slikovnih točk, velikost datoteke: $3',
 'svg-long-desc-animated' => 'animirana datoteka SVG, v izvirniku $1 × $2 slikovnih točk, velikost datoteke: $3',
 'show-big-image' => 'Slika v višji ločljivosti',
@@ -3709,7 +3715,7 @@ Uporabite lahko tudi [[Special:EditWatchlist|standardni urejevalnik]].',
 'version-hook-name' => 'Ime razširitve',
 'version-hook-subscribedby' => 'Naročen s strani',
 'version-version' => '(Različica $1)',
-'version-license' => 'Dovoljenje',
+'version-license' => 'Licenca',
 'version-poweredby-credits' => "Ta wiki poganja '''[//www.mediawiki.org/ MediaWiki]''', vse pravice pridržave © 2001-$1 $2.",
 'version-poweredby-others' => 'drugi',
 'version-license-info' => 'MediaWiki je prosto programje; lahko ga razširjate in / ali spreminjate pod pogoji GNU General Public License, kot ga je objavila Free Software Foundation; bodisi License različice 2 ali (po vaši izbiri) katere koli poznejše različice.
index dbdc979..757211e 100644 (file)
@@ -40,6 +40,7 @@
  * @author Rotsee
  * @author S.Örvarr.S
  * @author Sannab
+ * @author Sendelbach
  * @author Sertion
  * @author Skalman
  * @author Stefan2
@@ -1085,6 +1086,15 @@ Det verkar som att den har raderats.',
 'edit-already-exists' => 'Sidan kunde inte skapas.
 Den finns redan.',
 'defaultmessagetext' => 'Standardtext för meddelande',
+'content-failed-to-parse' => 'Det gick inte att parsa $2 innehåll för $1 modell: $3',
+'invalid-content-data' => 'Ogiltig innehållsdata',
+'content-not-allowed-here' => 'innehåll av "$1" är inte tillåtet på sidan [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'wikitext',
+'content-model-text' => 'oformaterad text',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Varning: Denna sida innehåller för många anrop av resurskrävande parserfunktioner.
@@ -2536,7 +2546,8 @@ I sådana fall måste du se till att den senaste raderade versionen inte är ikr
 'undeletedrevisions' => '{{PLURAL:$1|en version återställd|$1 versioner återställda}}',
 'undeletedrevisions-files' => '$1 {{PLURAL:$1|version|versioner}} och $2 {{PLURAL:$2|fil|filer}} återställda',
 'undeletedfiles' => '{{PLURAL:$1|en fil återställd|$1 filer återställda}}',
-'cannotundelete' => 'Återställning misslyckades; kanske någon redan har återställt sidan.',
+'cannotundelete' => 'Återställning misslyckades:
+$1',
 'undeletedpage' => "'''$1 har återställts'''
 
 Se [[Special:Log/delete|raderingsloggen]] för en förteckning över de senaste raderingarna och återställningarna.",
@@ -2838,6 +2849,7 @@ Den titel du vill flytta sidan till, "[[:$1]]", finns redan. Vill du radera den
 'immobile-target-namespace-iw' => 'Interwikilänk är inte ett giltigt mål för sidflyttar.',
 'immobile-source-page' => 'Denna sida är inte flyttbar.',
 'immobile-target-page' => 'Kan inte flytta till det målnamnet.',
+'bad-target-model' => 'Den önskade destinationen använder en annan innehållsmodell. Kan inte konvertera från $1 till $2.',
 'imagenocrossnamespace' => 'Kan inte flytta filer till andra namnrymder än filnamnrymden',
 'nonfile-cannot-move-to-file' => 'Kan inte flytta icke-fil till filnamnrymden',
 'imagetypemismatch' => 'Den nya filändelsen motsvarar inte filtypen',
@@ -3713,6 +3725,7 @@ Denna bekräftelsekod kommer att sluta fungera efter $4.',
 # Scary transclusion
 'scarytranscludedisabled' => '[Interwiki-inklusion är inte aktiverad]',
 'scarytranscludefailed' => '[Hämtning av mall för $1 misslyckades]',
+'scarytranscludefailed-httpstatus' => '[Hämtning av mall för $1 misslyckades: HTTP $2]',
 'scarytranscludetoolong' => '[För lång URL]',
 
 # Delete conflict
index 6cf6da3..d29825e 100644 (file)
@@ -885,6 +885,11 @@ $2
 అది ఇప్పటికే ఉంది.',
 'defaultmessagetext' => 'అప్రమేయ సందేశపు పాఠ్యం',
 
+# Content models
+'content-model-wikitext' => 'వికీపాఠ్యం',
+'content-model-text' => 'సాదా పాఠ్యం',
+'content-model-javascript' => 'జావాస్క్రిప్ట్',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'హెచ్చరిక: ఈ పేజీలో ఖరీదైన పార్సరు పిలుపులు చాలా ఉన్నాయి.
 
@@ -1984,6 +1989,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'mailnologin' => 'పంపించవలసిన చిరునామా లేదు',
 'mailnologintext' => 'ఇతరులకు ఈ-మెయిలు పంపించాలంటే, మీరు [[Special:UserLogin|లాగిన్‌]] అయి ఉండాలి, మరియు మీ [[Special:Preferences|అభిరుచుల]]లో సరైన ఈ-మెయిలు చిరునామా ఇచ్చి ఉండాలి.',
 'emailuser' => 'ఈ వాడుకరికి ఈ-మెయిలుని పంపించండి',
+'emailuser-title-target' => 'ఈ {{GENDER:$1|వాడుకరికి}} ఈమెయిలు పంపించండి',
 'emailpage' => 'వాడుకరికి ఈ-మెయిలుని పంపించు',
 'emailpagetext' => 'వాడుకరికి ఈమెయిలు సందేశము పంపించుటకు క్రింది ఫారంను ఉపయోగించవచ్చు. [[Special:Preferences|మీ వాడుకరి అభిరుచుల]]లో మీరిచ్చిన ఈ-మెయిలు చిరునామా "నుండి" ఆ సందేశం వచ్చినట్లుగా ఉంటుంది, కనుక వేగుని అందుకునేవారు నేరుగా మీకు జవాబివ్వగలుగుతారు.',
 'usermailererror' => 'మెయిలు ఆబ్జెక్టు ఈ లోపాన్ని చూపింది:',
@@ -2737,6 +2743,7 @@ $UNWATCHURL కి వెళ్ళండి.
 'pageinfo-views' => 'వీక్షణల సంఖ్య',
 'pageinfo-watchers' => 'పేజీ వీక్షకుల సంఖ్య',
 'pageinfo-edits' => 'మొత్తం మార్పుల సంఖ్య',
+'pageinfo-toolboxlink' => 'పేజీ సమాచారం',
 
 # Skin names
 'skinname-standard' => 'సంప్రదాయ',
index 827dd6d..e582b50 100644 (file)
@@ -760,6 +760,7 @@ $1',
 'revdelete-success' => "'''Тағйири намоёнии нусха бо муваффақият анҷом шуд.'''",
 'logdelete-success' => "'''Тағйири намоёнии маврид бо муваффақият анҷом шуд.'''",
 'revdel-restore' => 'Тағйири падидорӣ',
+'revdel-restore-visible' => 'нусхаҳои намоён',
 'pagehist' => 'Таърихи саҳифа',
 'deletedhist' => 'Таърихи ҳазфшуда',
 'revdelete-edit-reasonlist' => 'Вироиш ҳазф далелҳо',
@@ -1177,7 +1178,7 @@ $1',
 'filehist-dimensions' => 'Андоза',
 'filehist-filesize' => 'Андозаи парванда',
 'filehist-comment' => 'Тавзеҳ',
-'imagelinks' => 'Ð\9fайвандҳои парванда',
+'imagelinks' => 'Ð\98Ñ\81Ñ\82иÑ\84одаи парванда',
 'linkstoimage' => '{{PLURAL:$1|Саҳифаҳои|$1 Саҳифаи}} зерин ба ин акс пайванданд:',
 'nolinkstoimage' => 'Ҳеҷ саҳифае ба ин акс пайванд надорад.',
 'sharedupload' => 'Ин парванда аз $1 мебошад ва шояд аз тарафи дигар лоиҳаҳо истифода шавад.',
index ebcf4ae..9a0981e 100644 (file)
@@ -1078,6 +1078,9 @@ Silinmiş görünüyor.',
 Sayfa zaten mevcut.',
 'defaultmessagetext' => 'Varsayılan mesaj metni',
 
+# Content models
+'content-model-javascript' => 'JavaScript',
+
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Uyarı: Bu sayfa çok fazla zengin derleyici fonksiyonu çağrısı içeriyor.
 
index 44df07a..b37c03d 100644 (file)
@@ -8,6 +8,7 @@
  * @file
  *
  * @author Alfredie
+ * @author Arlin
  * @author Kaganer
  * @author Reedy
  * @author Sahran
@@ -108,45 +109,45 @@ $messages = array(
 'thu' => 'پ',
 'fri' => 'ج',
 'sat' => 'ش',
-'january' => 'Ù\82Û\95ھرÙ\89تاÙ\86',
-'february' => 'ھۇت',
-'march' => 'Ù\86Û\95Û\8bرÛ\87ز',
-'april' => 'ئۇمۇت',
-'may_long' => 'باھار',
-'june' => 'سÛ\95Ù¾Û\95ر',
-'july' => 'چىللە',
-'august' => 'تÙ\88Ù\85Û\87ز',
-'september' => 'مىزان',
-'october' => 'ئوغۇز',
-'november' => 'ئوغلاق',
-'december' => 'كۆنەك',
-'january-gen' => 'Ù\82Û\95ھرÙ\89تاÙ\86',
-'february-gen' => 'ھۇت',
-'march-gen' => 'Ù\86Û\95Û\8bرÛ\87ز',
-'april-gen' => 'ئۇمۇت',
-'may-gen' => 'باھار',
-'june-gen' => 'سÛ\95Ù¾Û\95ر',
-'july-gen' => 'چىللە',
-'august-gen' => 'تÙ\88Ù\85Û\87ز',
-'september-gen' => 'مىزان',
-'october-gen' => 'ئوغۇز',
-'november-gen' => 'ئوغلاق',
-'december-gen' => 'كۆنەك',
-'jan' => 'Ù\82Û\95ھرÙ\89تاÙ\86',
-'feb' => 'ھۇت',
-'mar' => 'Ù\86Û\95Û\8bرÛ\87ز',
-'apr' => 'ئۇمۇت',
-'may' => 'باھار',
-'jun' => 'سÛ\95Ù¾Û\95ر',
-'jul' => 'چىللە',
-'aug' => 'تÙ\88Ù\85Û\87ز',
-'sep' => 'مىزان',
-'oct' => 'ئوغۇز',
-'nov' => 'ئوغلاق',
-'dec' => 'كۆنەك',
+'january' => 'Ù\8aاÙ\86Û\8bار',
+'february' => 'فېۋرال',
+'march' => 'Ù\85ارت',
+'april' => 'ئاپرېل',
+'may_long' => 'ماي',
+'june' => 'ئÙ\89Ù\8aÛ\87Ù\86',
+'july' => 'ئىيۇل',
+'august' => 'ئاÛ\8bغÛ\87ست',
+'september' => 'سىنتەبىر',
+'october' => 'ئۆكتەبىر',
+'november' => 'نويابىر',
+'december' => 'دېكابىر',
+'january-gen' => 'Ù\8aاÙ\86Û\8bار',
+'february-gen' => 'فېۋرال',
+'march-gen' => 'Ù\85ارت',
+'april-gen' => 'ئاپرېل',
+'may-gen' => 'ماي',
+'june-gen' => 'ئÙ\89Ù\8aÛ\87Ù\86',
+'july-gen' => 'ئىيۇل',
+'august-gen' => 'ئاÛ\8bغÛ\87ست',
+'september-gen' => 'سىنتەبىر',
+'october-gen' => 'ئۆكتەبىر',
+'november-gen' => 'نويابىر',
+'december-gen' => 'دېكابىر',
+'jan' => 'Ù\8aاÙ\86Û\8bار',
+'feb' => 'فېۋرال',
+'mar' => 'Ù\85ارت',
+'apr' => 'ئاپرېل',
+'may' => 'ماي',
+'jun' => 'ئÙ\89Ù\8aÛ\87Ù\86',
+'jul' => 'ئىيۇل',
+'aug' => 'ئاÛ\8bغÛ\87ست',
+'sep' => 'سىنتەبىر',
+'oct' => 'ئۆكتەبىر',
+'nov' => 'نويابىر',
+'dec' => 'دېكابىر',
 
 # Categories related messages
-'pagecategories' => '{{PLURAL:$1|تۈر|تۈر}}',
+'pagecategories' => '{{PLURAL:$1|تۈر|تۈرلەر}}',
 'category_header' => '"$1" تۈردىكى بەتلەر',
 'subcategories' => 'تارماق تۈر',
 'category-media-header' => '"$1" تۈردىكى ۋاسىتە',
@@ -168,7 +169,7 @@ $messages = array(
 'linkprefix' => '/^(.*?)([a-zA-Z\\x80-\\xff]+)$/sD',
 
 'about' => 'ھەققىدە',
-'article' => 'Ù\85Û\95زÙ\85Û\87Ù\86 Ø¨Û\90تÙ\89',
+'article' => 'Ù\85Û\87Ù\86دÛ\95رÙ\89جÛ\95',
 'newwindow' => '(يېڭى كۆزنەكتە ئاچ)',
 'cancel' => 'ۋاز كەچ',
 'moredotdotdot' => 'تەپسىلىي…',
@@ -196,7 +197,7 @@ $messages = array(
 'vector-action-protect' => 'قوغدا',
 'vector-action-undelete' => 'ئەسلىگە قايتۇر',
 'vector-action-unprotect' => 'قوغداش ئۆزگەرت',
-'vector-simplesearch-preference' => 'ئالىي ئىزدەش تەكلىپىنى ئاچ (Vector تېرىدىلا)',
+'vector-simplesearch-preference' => 'ئاددىي ئىزدەش ئىستون ئاچ (پەقەت ۋېكتور قېلىپ)',
 'vector-view-create' => 'قۇر',
 'vector-view-edit' => 'تەھرىر',
 'vector-view-history' => 'تارىخ كۆرسەت',
@@ -300,6 +301,7 @@ $1',
 [[Special:Version|نەشر بېتى]] نى كۆرۈڭ.',
 
 'ok' => 'ماقۇل',
+'pagetitle' => '$1 - {{SITENAME}}',
 'pagetitle-view-mainpage' => '{{SITENAME}}',
 'backlinksubtitle' => '← $1',
 'retrievedfrom' => '"$1" دىن ئېرىشكەن',
@@ -333,7 +335,7 @@ $1',
 'site-atom-feed' => '$1 نىڭ Atom قانالى',
 'page-rss-feed' => '"$1" نىڭ RSS قانىلى',
 'page-atom-feed' => '"$1" نىڭ Atom قانىلى',
-'feed-atom' => 'ئاتوم',
+'feed-atom' => 'Atom',
 'feed-rss' => 'RSS',
 'red-link-title' => '$1 (بەت مەۋجۇد ئەمەس)',
 'sort-descending' => 'كېمەيگۈچى تەرتىپ',
@@ -370,9 +372,9 @@ URL نى خاتا كىرگۈزۈپ قالدىڭىز ياكى خاتا ئۇلان
 'dberrortext' => 'ساندان سۈرۈشتۈرۈشتە گرامماتىكىلىق خاتالىق يۈز بەردى.
 يۇمشاق دېتالنىڭ ئۆزىدىكى خاتالىقتىن كېلىپ چىققان بولۇشى مۇمكىن.
 ئاخىرقى قېتىملىق ساندان سۈرۈشتۈرۈش بۇيرۇقى:
-<blockquote><tt>$1</tt></blockquote>
\\"<tt>$2</tt>\\"فۇنكسىيىدىن كەلگەن.
-MySQL قايتۇرغان خاتالىق \\"<tt>$3: $4</tt>\\".',
+<blockquote><code>$1</code></blockquote>
"<code>$2</code>"فۇنكسىيىدىن كەلگەن.
+ساندان قايتۇرغان خاتالىق "<samp>$3: $4</samp>".',
 'dberrortextcl' => 'ساندان سۈرۈشتۈرۈشتە گرامماتىكىلىق خاتالىق يۈز بەردى.
 ئاخىرقى قېتىملىق ساندان سۈرۈشتۈرۈش بۇيرۇقى:
 "$1"
@@ -435,7 +437,8 @@ MySQL قايتۇرغان خاتالىقى"$3: $4"',
 'protectedpagetext' => 'بۇ بەت تەھرىرلەشنىڭ ئالدىنى ئېلىش ئۈچۈن قۇلۇپلانغان.',
 'viewsourcetext' => 'سىز بۇ بەتنى ئەسلى كودىنى كۆرەلەيسىز ۋە كۆچۈرەلەيسىز:',
 'viewyourtext' => "بۇ بەتتىكى '''تەھرىرلىگەنلىرىڭىز'''نىڭ ئەسلى كودىنى كۆرۈپ كۆچۈرەلەيسىز.",
-'protectedinterface' => 'بۇ بەت يۇمشاق دېتالنىڭ كۆرۈنۈش تېكستىنى تەمىنلىگەن، خالىغانچە تەھرىرلەشتىن ساقلىنىش ئۈچۈن قۇلۇپلانغان.',
+'protectedinterface' => 'بۇ بەت يۇمشاق دېتالنىڭ كۆرۈنۈش تېكستىنى تەمىنلىگەن، خالىغانچە تەھرىرلەشتىن ساقلىنىش ئۈچۈن قۇلۇپلانغان.
+مەسىلەن ئەگەر تەرجىمە قىلسىڭىز [//translatewiki.net/wiki/Main_Page?setlang=ug translatewiki.net] ئۇنداقتا MediaWiki يەرلىكلەشتۈرۈش پىلانىنى ئىشلىتىشنى ئويلىشىڭ.',
 'editinginterface' => "'''ئاگاھلاندۇرۇش:''' سىز تەھرىرلەۋاتقان بەت يۇمشاق دېتالنىڭ كۆرۈنۈش تېكستىگە ئىشلىتىلىدۇ.
 
 بۇ بەت ئۆزگەرتىلسە باشقا ئىشلەتكۈچىلەرنىڭ كۆرۈنۈش ئۇسلۇبىغا تەسىر كۆرسىتىدۇ.
@@ -745,7 +748,7 @@ $2
 <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} مۇناسىۋەتلىك خاتىرىسىنى ئىزدىيەلەيسىز،],
 [{{fullurl:{{FULLPAGENAME}}|action=edit}} بۇ بەتنى تەھرىرلىيەلەيسىز]</span>',
 'noarticletext-nopermission' => 'بۇ بەتتە ھازىرچە مەزمۇن يوق.
- سىز باشقا بەتتە [[Special:Search/{{PAGENAME}}|بۇ بەتنىڭ ماۋزۇسىنى ئىزدىيەلەيسىز]] ياكى <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}] مۇناسىۋەتلىك خاتىرىسىنى ئىزدىيەلەيسىز،</span>',
+ سىز باشقا بەتتە [[Special:Search/{{PAGENAME}}|بۇ بەتنىڭ ماۋزۇسىنى ئىزدىيەلەيسىز]] ياكى <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}}] مۇناسىۋەتلىك خاتىرىسىنى ئىزدىيەلەيسىز،</span>لىكىن سزنىڭ بەت قۇرۇش ھوقوقىڭز يوق.',
 'missing-revision' => '"{{PAGENAME}}" ئاتلىق بەتنىڭ تۈزىتىلگەن نەشرى #$1 مەۋجۇت ئەمەس.
 
 ئادەتتە بۇ ئۆچۈرۈلگەن بىر بەتنىڭ ئۇلانمىسىغا كىرگەنلىك سەۋەبىدىن بولىدۇ.
@@ -759,7 +762,6 @@ $2
 * '''Mozilla / Firefox / Safari:''' دا ''Shift'' كۇنۇپكىسىنى بېسىپ تۇرۇپ ''قايتا يۈكلە''نى ياكى ''Ctrl-F5'' ياكى ''Ctrl-R'' (''Mac تا Command-R'')؛
 * '''Google Chrome:''' دا ''Ctrl-Shift-R'' (''Command-Shift-R''  Mac)
 *'''Internet Explorer:''' دا ''Ctrl'' نى بېسىپ تۇرۇپ ''يېڭىلا,'' ياكى ''Ctrl-F5''؛
-* '''Konqueror: دا ''' ''قايتا يۈكلە'' ياكى ''F5''؛
 * '''Opera:''' دا ''قورال → مايىللىق''؛ نى بېسىپ غەملەكنى تازىلاڭ.",
 'usercssyoucanpreview' => "ئەسكەرتىش:''' ساقلاشتىن ئىلگىرى  \"{{int:showpreview}}\" توپچىنى ئىشلىتىپ يېڭى CSS نى سىناڭ.",
 'userjsyoucanpreview' => "ئەسكەرتىش:''' ساقلاشتىن ئىلگىرى  \"{{int:showpreview}}\" توپچىنى ئىشلىتىپ يېڭى JS نى سىناڭ.",
@@ -862,6 +864,7 @@ $2
 'edit-already-exists' => 'يېڭى بەت قۇرالمىدى
 ئۇ مەۋجۇد.',
 'defaultmessagetext' => 'كۆڭۈلدىكى ئۇچۇر تېكستى',
+'content-failed-to-parse' => '$2 نى $1 گە ئانالىز قلش مەغلۇپ بولدى: $3',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''ئاگاھلاندۇرۇش:''' بۇ بەت ناھايىتى كۆپ يۇقىرى سەرپىياتتىكى گىرامماتىكىلىق ئىقتىدارنى چاقىرغان.\\n
@@ -1225,7 +1228,9 @@ $1",
 'username' => 'ئىشلەتكۇچى ئىسمى:',
 'uid' => 'ئىشلەتكۈچى كىملىك:',
 'prefs-memberingroups' => '{{PLURAL:$1|بىر|كۆپ}} گۇرۇپپا ئەزاسى:',
+'prefs-memberingroups-type' => '$1',
 'prefs-registration' => 'خەتلەتكەن ۋاقىت:',
+'prefs-registration-date-time' => '$1',
 'yourrealname' => 'ﺗﻮﻟﯘﻕ ئىسىم:',
 'yourlanguage' => 'تىل:',
 'yourvariant' => 'مەزمۇن تىل شالغۇتى:',
@@ -1291,6 +1296,7 @@ HTML بەلگىسىنى تەكشۈرۈڭ.',
 'userrights-notallowed' => 'ھېساباتىڭىزنىڭ ئىشلەتكۈچى ھوقۇقىنى قوشۇش ياكى ئۆزگەرتىش ھوقۇقى يوق.',
 'userrights-changeable-col' => 'سىز ئۆزگەرتەلەيدىغان گۇرۇپپا',
 'userrights-unchangeable-col' => 'سىز ئۆزگەرتەلمەيدىغان گۇرۇپپا',
+'userrights-irreversible-marker' => '$1*',
 
 # Groups
 'group' => 'گۇرۇپپا:',
@@ -1445,9 +1451,11 @@ HTML بەلگىسىنى تەكشۈرۈڭ.',
 'minoreditletter' => 'ئازراقلا',
 'newpageletter' => 'يېڭى',
 'boteditletter' => 'ماشىنا ئادەم',
+'unpatrolledletter' => '!',
 'number_of_watching_users_pageview' => '[$1  {{PLURAL:$1|ئىشلەتكۈچى|ئىشلەتكۈچى}}كۆزىتىۋاتىدۇ]',
 'rc_categories' => 'تۈر چېگرىسى ("|" بىلەن ئايرىلىدۇ )',
 'rc_categories_any' => 'خالىغان',
+'rc-change-size' => '$1',
 'newsectionsummary' => '* $1 * يېڭى ئابزاس',
 'rc-enhanced-expand' => 'تەپسىلاتىنى كۆرسەت (JavaScript قوللىشى زۆرۈر)',
 'rc-enhanced-hide' => 'تەپسىلاتىنى يوشۇر',
@@ -1885,6 +1893,7 @@ URL نىڭ توغرىلىقى ۋە تور بېكەتنى زىيارەت قىلى
 # Book sources
 'booksources' => 'كىتاب مەنبەسى',
 'booksources-search-legend' => 'كىتاب مەنبەسى ئىزدە',
+'booksources-isbn' => 'ISBN:',
 'booksources-go' => 'يۆتكەل',
 'booksources-text' => 'تۆۋەندىكىسى بىر قىسىم تور كىتابخانىلىرىنىڭ تىزىملىكى، ئىچىدە سىز ئىزدىمەكچى بولغان كىتابلارنىڭ تېخىمۇ كۆپ ئۇچۇرى بولۇشى مۇمكىن:',
 'booksources-invalid-isbn' => 'تەمىنلىگەن ISBN نومۇرى توغرا ئەمەس. ئەسلى كۆچۈرگەن مەنبەدىكى نومۇردا خاتالىق بار يوقلۇقىنى تەكشۈرۈڭ.',
@@ -1970,6 +1979,7 @@ URL نىڭ توغرىلىقى ۋە تور بېكەتنى زىيارەت قىلى
 'listgrouprights-rights' => 'ھوقۇق',
 'listgrouprights-helppage' => 'Help: گۇرۇپپا ھوقۇقى',
 'listgrouprights-members' => '(ئەزالار تىزىملىكى)',
+'listgrouprights-right-revoked' => '<span class="listgrouprights-revoked">$1 <code>($2)</code></span>',
 'listgrouprights-addgroup' => ' {{PLURAL:$2|بىر|بىر قانچە}} گۇرۇپپىغا قوشالايدۇ: $1',
 'listgrouprights-removegroup' => ' {{PLURAL:$2|بىر|بىر قانچە}} گۇرۇپپىدىن چىقىرىۋېتەلەيدۇ: $1',
 'listgrouprights-addgroup-all' => 'ھەممە گۇرۇپپىغا قوش',
@@ -2246,6 +2256,7 @@ $2 نىڭ ئاخىرقى تۈزىتىلگەن نەشرىگە ئۆزگەرتىل
 
  [[Special:Log/delete|ئۆچۈرۈش خاتىرىسى]]دىن پايدىلىنىپ ئۆچۈر ۋە ئەسلىگە كەلتۈر خاتىرىسىنى كۆرۈڭ.",
 'undelete-header' => 'يېقىنقى خاتىرىنى سۈرۈشتۈرمەكچى بولسىڭىز [[Special:Log/delete|ئۆچۈرۈش خاتىرىسى]]دىن پايدىلىنىڭ.',
+'undelete-search-title' => 'ئۆچۈرۈئتلگەن بەتنى ئزدەش',
 'undelete-search-box' => 'ئۆچۈرۈلگەن بەتنى ئىزدە',
 'undelete-search-prefix' => 'باشلانغان بەتنى كۆرسەت:',
 'undelete-search-submit' => 'ئىزدەش',
@@ -2261,6 +2272,7 @@ $2 نىڭ ئاخىرقى تۈزىتىلگەن نەشرىگە ئۆزگەرتىل
 $1',
 'undelete-show-file-confirm' => '$2 $3 دىكى \\"<nowiki>$1</nowiki>\\" نىڭ ئۆچۈرۈلگەن تۈزىتىلگەن نەشرىنى راستىنلا كۆرەمسىز؟',
 'undelete-show-file-submit' => 'ھەئە',
+'undelete-revisionrow' => '$1 $2 ($3) $4 . . $5 $6 $7',
 
 # Namespace form on various pages
 'namespace' => 'ئات بوشلۇقى',
@@ -2441,6 +2453,7 @@ $1',
 'proxyblockreason' => 'IP ئادرېسىڭىز ئوچۇق ۋاكالەتچى، ئۇ ئاللىبۇرۇن چەكلەنگەن.
 ئىنتېرنېت مۇلازىمىتى تەمىنلىگۈچى سودىگەر ياكى تېخنىكىلىق قوللىغۇچى بىلەن ئالاقىلىشىڭ ھەمدە ئۇلارغا بۇ ئېغىر بىخەتەرلىك مەسىلىسىنى ئۇقتۇرۇڭ.',
 'proxyblocksuccess' => 'تامام',
+'sorbs' => 'DNSBL',
 'sorbsreason' => 'IP ئادرېسىڭىز {{SITENAME}} دا DNSBL تەرىپىدىن ئوچۇق ۋاكالەتچى تىزىملىكىگە قوشۇلغان.',
 'sorbs_create_account_reason' => 'IP ئادرېسىڭىز {{SITENAME}} دا DNSBL تەرىپىدىن ئوچۇق ۋاكالەتچى تىزىملىكىگە قوشۇلغان.
 شۇڭا سىز يېڭى ھېسابات قۇرالمايسىز.',
@@ -2576,6 +2589,7 @@ $1',
 بەت چىقىرىشتا، تۆۋەندىكى تېكست رامكىسىغا بەت ماۋزۇسىنى  كىرگۈزۈپ، ھەر بىر قۇردا بىر ماۋزۇ، ھەمدە بەت تارىخ بار  ئىلگىرىكى تۈزىتىلگەن نەشرىنى تاللامسىز يوق، ياكى پەقەت  ئاخىرقى قېتىملىق تەھرىر ئۇچۇرى بار نۆۋەتتىكى تۈزىتىلگەن  نەشرىنى چىقىرىشنى تاللاڭ.
 
 ئۇنىڭدىن باشقا ئۇلانمىدىن پايدىلىنىپ ھۆججەت چىقىرالايسىز،  مەسىلەن سىز [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] دىن پايدىلىنىپ  "[[{{MediaWiki:Mainpage}}]]"بەت چىقىرالايسىز.',
+'exportall' => 'بارلىق بەتنى چىقىرىش',
 'exportcuronly' => 'ھەممە تارىخنى ئەمەس بەلكى نۆۋەتتىكى تۈزىتىلگەن نەشرىنىلا ئۆز ئىچىگە ئالىدۇ.',
 'exportnohistory' => "----
 '''دىققەت:''' ئىقتىدار سەۋەبلىك بۇ جەدۋەلدىن ھەممە تارىخنى چىقىرىش چەكلەنگەن.",
@@ -2611,6 +2625,7 @@ $1',
 'thumbnail_error' => 'كىچىك رەسىم قۇرۇش خاتالىقى: $1',
 'djvu_page_error' => 'DjVu بېتى دائىرىدىن ھالقىپ كەتتى',
 'djvu_no_xml' => 'DjVu ھۆججىتىدىن XML گە ئېرىشەلمىدى',
+'thumbnail-dest-create' => 'قارار ھۈجەتتە ۋاقتلىق كىچىك ھۈجەت ساقلىغل بولمدى',
 'thumbnail_invalid_params' => 'ئىناۋەتسىز كىچىك رەسىم پارامېتىرى',
 'thumbnail_dest_directory' => 'نىشان مۇندەرىجە قۇرالمىدى',
 'thumbnail_image-type' => 'سۈرەت فورماتىنى قوللىمايدۇ',
@@ -2740,6 +2755,40 @@ $1',
 'tooltip-preferences-save' => 'مايىللىق ساقلا',
 'tooltip-summary' => 'قىسقىچە ئۈزۈندە كىرگۈزۈڭ',
 
+# Stylesheets
+'common.css' => '/* CSS placed here will be applied to all skins */',
+'standard.css' => '/* CSS placed here will affect users of the Standard skin */',
+'nostalgia.css' => '/* CSS placed here will affect users of the Nostalgia skin */',
+'cologneblue.css' => '/* CSS placed here will affect users of the Cologne Blue skin */',
+'monobook.css' => '/* CSS placed here will affect users of the Monobook skin */',
+'myskin.css' => '/* CSS placed here will affect users of the MySkin skin */',
+'chick.css' => '/* CSS placed here will affect users of the Chick skin */',
+'simple.css' => '/* CSS placed here will affect users of the Simple skin */',
+'modern.css' => '/* CSS placed here will affect users of the Modern skin */',
+'vector.css' => '/* CSS placed here will affect users of the Vector skin */',
+'print.css' => '/* CSS placed here will affect the print output */',
+'noscript.css' => '/* CSS placed here will affect users with JavaScript disabled */',
+'group-autoconfirmed.css' => '/* CSS placed here will affect autoconfirmed users only */',
+'group-bot.css' => '/* CSS placed here will affect bots only */',
+'group-sysop.css' => '/* CSS placed here will affect sysops only */',
+'group-bureaucrat.css' => '/* CSS placed here will affect bureaucrats only */',
+
+# Scripts
+'common.js' => '/* Any JavaScript here will be loaded for all users on every page load. */',
+'standard.js' => '/* Any JavaScript here will be loaded for users using the Standard skin */',
+'nostalgia.js' => '/* Any JavaScript here will be loaded for users using the Nostalgia skin */',
+'cologneblue.js' => '/* Any JavaScript here will be loaded for users using the Cologne Blue skin */',
+'monobook.js' => '/* Any JavaScript here will be loaded for users using the MonoBook skin */',
+'myskin.js' => '/* Any JavaScript here will be loaded for users using the MySkin skin */',
+'chick.js' => '/* Any JavaScript here will be loaded for users using the Chick skin */',
+'simple.js' => '/* Any JavaScript here will be loaded for users using the Simple skin */',
+'modern.js' => '/* Any JavaScript here will be loaded for users using the Modern skin */',
+'vector.js' => '/* Any JavaScript here will be loaded for users using the Vector skin */',
+'group-autoconfirmed.js' => '/* Any JavaScript here will be loaded for autoconfirmed users only */',
+'group-bot.js' => '/* Any JavaScript here will be loaded for bots only */',
+'group-sysop.js' => '/* Any JavaScript here will be loaded for sysops only */',
+'group-bureaucrat.js' => '/* Any JavaScript here will be loaded for bureaucrats only */',
+
 # Metadata
 'notacceptable' => 'wiki مۇلازىمىتىرى سىزنىڭ خېرىدار تەرىپىڭىز ئوقۇيالايدىغان سانلىق مەلۇمات فورماتى بىلەن تەمىنلىيەلمەيدۇ.',
 
@@ -2766,12 +2815,29 @@ $1',
 
 # Info page
 'pageinfo-title' => '"$1" نىڭ ئۇچۇرى',
-'pageinfo-header-edits' => 'تەھرىر',
+'pageinfo-header-basic' => 'ئاساسىي ئۇچۇر',
+'pageinfo-header-edits' => 'تەھرىر خاتىرىسى',
+'pageinfo-header-restrictions' => 'بەت  قوغداش',
+'pageinfo-header-properties' => 'بەت خاراكتېرى',
+'pageinfo-display-title' => 'كۆرسىتىدغان نام',
+'pageinfo-article-id' => 'بەت ID',
 'pageinfo-views' => 'كۆرۈنۈش سانى',
-'pageinfo-watchers' => 'كۆزەتكۈچىلەر سانى',
+'pageinfo-watchers' => 'بەت كۆزەتكۈچىلەر سانى',
+'pageinfo-redirects-value' => '$1',
 'pageinfo-edits' => 'تەھرىر سانى',
 'pageinfo-authors' => 'يازغۇچىلار سانى',
 
+# Skin names
+'skinname-standard' => 'Classic',
+'skinname-nostalgia' => 'Nostalgia',
+'skinname-cologneblue' => 'Cologne Blue',
+'skinname-monobook' => 'MonoBook',
+'skinname-myskin' => 'MySkin',
+'skinname-chick' => 'Chick',
+'skinname-simple' => 'Simple',
+'skinname-modern' => 'Modern',
+'skinname-vector' => 'Vector',
+
 # Patrolling
 'markaspatrolleddiff' => 'چارلاش بەلگىسى قوي',
 'markaspatrolledtext' => 'بۇ بەتكە چارلاش بەلگىسى قوي',
@@ -2807,6 +2873,7 @@ $1',
 'mediawarning' => "'''ئاگاھلاندۇرۇش''': بۇ ھۆججەتتە زەھەرخەندە كود بولۇشى مۇمكىن، ئۇنى ئىجرا قىلسىڭىز سىستېمىڭىزغا خەۋپ ئېلىپ كېلىشى مۇمكىن.",
 'imagemaxsize' => "سۈرەت چوڭلۇق چەكلىمىسى: <br />''(ھۆججەت چۈشەندۈرۈش بېتى ئۈچۈن)''",
 'thumbsize' => 'كىچىك سۈرەت چوڭلۇقى:',
+'widthheight' => '$1 × $2',
 'widthheightpage' => '$1 × $2, $3 {{PLURAL:$3|بەت|بەت}}',
 'file-info' => 'ھۆججەت چوڭلۇقى: $1, MIME تىپى: $2',
 'file-info-size' => '$1 × $2 پىكسېل، ھۆججەت چوڭلۇقى: $3، MIME تىپى: $4',
@@ -2835,6 +2902,13 @@ $1',
 'bydate' => 'چېسلا بويىچە',
 'sp-newimages-showfrom' => '$2 دىن $1 باشلاپ يېڭى ھۆججەت كۆرسىتىۋاتىدۇ',
 
+# Video information, used by Language::formatTimePeriod() to format lengths in the above messages
+'video-dims' => '$1, $2 × $3',
+'seconds-abbrev' => '$1s',
+'minutes-abbrev' => '$1m',
+'hours-abbrev' => '$1h',
+'days-abbrev' => '$1d',
+
 # Bad image list
 'bad_image_list' => 'تۆۋەندىكى فورماتتا يېزىڭ:
 
@@ -2843,6 +2917,40 @@ $1',
  بۇ ھۆججەت قايسى بەتلەردە كۆرسىتىلىشىدىن قەتئىي نەزەر،
  ئوخشاش بىر قۇرنىڭ ئاخىرىدىكى ئۇلانما مۇستەسنا دەپ قارىلىدۇ،',
 
+/*
+Short names for language variants used for language conversion links.
+To disable showing a particular link, set it to 'disable', e.g.
+'variantname-zh-sg' => 'disable',
+Variants for Chinese language
+*/
+'variantname-zh-hans' => 'hans',
+'variantname-zh-hant' => 'hant',
+'variantname-zh-cn' => 'cn',
+'variantname-zh-tw' => 'tw',
+'variantname-zh-hk' => 'hk',
+'variantname-zh-mo' => 'mo',
+'variantname-zh-sg' => 'sg',
+'variantname-zh-my' => 'my',
+'variantname-zh' => 'zh',
+
+# Variants for Gan language
+'variantname-gan-hans' => 'hans',
+'variantname-gan-hant' => 'hant',
+'variantname-gan' => 'gan',
+
+# Variants for Serbian language
+'variantname-sr-ec' => 'sr-ec',
+'variantname-sr-el' => 'sr-el',
+'variantname-sr' => 'sr',
+
+# Variants for Kazakh language
+'variantname-kk-kz' => 'kk-kz',
+'variantname-kk-tr' => 'kk-tr',
+'variantname-kk-cn' => 'kk-cn',
+'variantname-kk-cyrl' => 'kk-cyrl',
+'variantname-kk-arab' => 'kk-arab',
+'variantname-kk' => 'kk',
+
 # Metadata
 'metadata' => 'مېتا سانلىق مەلۇماتى',
 'metadata-help' => 'بۇ ھۆججەت كېڭەيتىلگەن تەپسىلاتنى ئۆز ئىچىگە ئالغان. بۇ ئۇچۇرلارنى رەقەملىك ئاپپارات ياكى سكاننېر قۇرغان ياكى رەقەملەشتۈرۈش جەريانىدا قوشۇلغان بولۇشى مۇمكىن.
index e02c793..867e1de 100644 (file)
@@ -2636,7 +2636,7 @@ $1',
 'sp-contributions-newbies' => 'Показати лише внесок з нових облікових записів',
 'sp-contributions-newbies-sub' => 'Внесок новачків',
 'sp-contributions-newbies-title' => 'Внесок з нових облікових записів',
-'sp-contributions-blocklog' => 'пÑ\80оÑ\82окол блокувань',
+'sp-contributions-blocklog' => 'жÑ\83Ñ\80нал блокувань',
 'sp-contributions-deleted' => 'вилучені редагування користувача',
 'sp-contributions-uploads' => 'завантаження',
 'sp-contributions-logs' => 'журнали',
index c54ceea..86fbd08 100644 (file)
@@ -1037,7 +1037,8 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'listgrouprights-members' => '(a’zolar ro‘yxati)',
 
 # E-mail user
-'emailuser' => 'Bu foydalanuvchiga e-maktub',
+'emailuser' => 'Foydalanuvchiga maktub',
+'defemailsubject' => '{{SITENAME}} — $1 tomonidan maktub',
 'noemailtitle' => 'Elektron pochta manzili mavjud emas',
 'noemailtext' => "Bu foydalanuvchi e-mail manzil ko'rsatgani yo'q.",
 'emailtarget' => 'Oluvchi ishtirokchining ismini kiriting',
@@ -1049,7 +1050,9 @@ Also see [[Special:WantedCategories|wanted categories]].',
 'emailsubject' => 'Sarlavha:',
 'emailmessage' => 'Xabar',
 'emailsend' => 'Joʻnatish',
+'emailccsubject' => '$1ga maktubingizning nusxasi: $2',
 'emailsent' => "Xat jo'natildi",
+'emailsenttext' => "Sizning elektron maktubingiz jo'natildi.",
 
 # User Messenger
 'usermessage-summary' => 'Tizimli xabar qoldirish.',
@@ -1496,6 +1499,7 @@ Yaqinda sodir etilgan yoʻqotishlar uchun $2ni koʻring.',
 
 # New logging system
 'logentry-move-move' => '$1 $3 sahifasini $4ga koʻchirdi',
+'logentry-patrol-patrol-auto' => '$1 $3 sahifasining $4 versiyasini avtomatik patrulladi',
 'logentry-newusers-newusers' => '$1 ishtirokchisining hisob yozuvi yaratildi',
 'logentry-newusers-create' => '$1 ishtirokchisining hisob yozuvi yaratildi',
 
index ae36f9c..d44b51b 100644 (file)
@@ -1058,6 +1058,15 @@ Dường như trang này đã bị xóa.',
 'edit-already-exists' => 'Không thể tạo trang mới.
 Nó đã tồn tại.',
 'defaultmessagetext' => 'Nội dung mặc định',
+'content-failed-to-parse' => 'Thất bại phân tích nội dung $2 cho mô hình $1: $3',
+'invalid-content-data' => 'Dữ liệu nội dung không hợp lệ',
+'content-not-allowed-here' => 'Không cho phép đưa nội dung “$1” vào trang [[$2]]',
+
+# Content models
+'content-model-wikitext' => 'mã wiki',
+'content-model-text' => 'văn bản thuần',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => 'Cảnh báo: Trang này có quá nhiều lần gọi hàm cú pháp cần mức độ xử lý cao.
@@ -2509,8 +2518,8 @@ Chỉ có bảo quản viên mới xem được văn bản đầy đủ của nh
 'undeletedrevisions' => '$1 {{PLURAL:$1|bản|bản}} được phục hồi',
 'undeletedrevisions-files' => '$1 {{PLURAL:$1|bản|bản}} và $2 {{PLURAL:$2|tập tin|tập tin}} đã được phục hồi',
 'undeletedfiles' => '$1 {{PLURAL:$1|tập tin|tập tin}} đã được phục hồi',
-'cannotundelete' => 'Phục hồi thất bại;
-một người nào khác đã phục hồi trang này rồi.',
+'cannotundelete' => 'Phục hồi thất bại:
+$1',
 'undeletedpage' => "'''$1 đã được khôi phục'''
 
 Xem nhật trình xóa và phục hồi các trang gần đây tại [[Special:Log/delete|nhật trình xóa]].",
@@ -2810,6 +2819,7 @@ Trang với tên “[[:$1]]” đã tồn tại. Bạn có muốn xóa nó để
 'immobile-target-namespace-iw' => 'Không cho phép di chuyển trang đến một liên kết liên wiki.',
 'immobile-source-page' => 'Bạn không thể di chuyển trang này.',
 'immobile-target-page' => 'Không thể di chuyển đến tựa đề đích.',
+'bad-target-model' => 'Trang đích sử dụng mô hình nội dung khác. Không thể chuyển đổi nội dung từ $1 đến $2.',
 'imagenocrossnamespace' => 'Không thể di chuyển tập tin ra khỏi không gian tên Tập tin',
 'nonfile-cannot-move-to-file' => 'Không thể di chuyển những gì không phải là tập tin vào không gian tên Tập tin',
 'imagetypemismatch' => 'Phần mở rộng trong tên tập tin mới không hợp dạng của tập tin',
index 1cfc057..e892cb2 100644 (file)
@@ -354,6 +354,8 @@ $1',
 'page-rss-feed' => '"$1" RSS nga feed',
 'page-atom-feed' => '"$1" Atom nga feed',
 'red-link-title' => '$1 (waray dida ini nga pakli)',
+'sort-descending' => 'Igpasunodsunod paubos',
+'sort-ascending' => 'Igpasunodsunod paigbaw',
 
 # Short words for each namespace, by default used in the namespace tab in monobook
 'nstab-main' => 'Pakli',
@@ -413,11 +415,13 @@ Alayon la igsumat ini ha [[Special:ListUsers/sysop|administrator]], igsurat la a
 'directorycreateerror' => 'Waray makahimo han direktoryo nga "$1".',
 'filenotfound' => 'Diri nabibilngan an paypay nga "$1"',
 'fileexistserror' => "Diri nasusuratan ha paypay nga ''$1'': Aada na an paypay.",
+'unexpected' => 'Diri ginlalauman nga balor: "$1"="$2".',
 'formerror' => 'Sayop: Diri nasusumite an porma.',
 'badarticleerror' => 'Ini nga pagbuhat diri mahihimo dinhi nga pakli',
 'cannotdelete' => 'An pakli o an fayl nga "$1" diri napapara.
 Bangin na ini ginpara hin iba.',
 'cannotdelete-title' => 'diri nakakapara han pakli "$1"',
+'delete-hook-aborted' => 'Pagpara ginpugngan han kawil.  Waray eksplenasyon an ginhatag.',
 'badtitle' => 'Maraot nga titulo',
 'badtitletext' => 'An ginhangyo nga pakli diri puyde, waray sulod, o sayop nga nasumpay nga inter-pinunongan o inter-wiki nga titulo.
 Bangin mayda usa o damo nga mga agi nga diri puyde magamit ha mga titulo.',
@@ -430,6 +434,7 @@ Funsyon: $1<br />
 Kweri: $2',
 'viewsource' => 'Kitaa an ginkuhaan',
 'viewsource-title' => 'Kitaa an tinikangan para han $1',
+'actionthrottled' => 'Ginpahinay an ginbuhat',
 'actionthrottledtext' => 'Komo uska pangontra ha spam, ikaw in ginlilimitaran paghimo hini nga pagbuhat hin sobra kadamo ha sulod hin gutiay nga oras, ngan ikaw in naglapos hini nga katubtuban.
 Alayon pagutro kahuman hin pipira ka mga minuto.',
 'protectedpagetext' => 'Ini nga pakli in pinasaliporan para mapugngan an mga pagliwat.',
@@ -437,9 +442,14 @@ Alayon pagutro kahuman hin pipira ka mga minuto.',
 'viewyourtext' => "Puydi nim makit-an ngan makopya an tinikangan han '''imo mga pagliwat''' ha dinhi nga pakli:",
 'sqlhidden' => '(nakatago an SQL query)',
 'namespaceprotected' => "Diri ka gintutugutan pagliwat han mga pakli ha ngaran-lat'ang nga '''$1'''.",
+'customcssprotected' => 'Diri ka gintutugotan pagliwat hini nga CSS nga pakli, tungod nga nagsusulod ini hin kanan iba nga tawo personal nga karuyagon.',
+'customjsprotected' => 'Diri ka gintutugotan pagliwat hini nga JavaScript nga pakli, tungod nga nagsusulod ini hin kanan iba nga tawo personal nga karuyagon.',
 'ns-specialprotected' => 'Diri maliliwat an mga ispisyal nga pakli.',
 'titleprotected' => 'Ini nga titulo pinasalipod ha paghimo ni [[User:$1|$1]].
 An katadungan nga ginhatag amo in "\'\'$2\'\'".',
+'filereadonlyerror' => 'Diri maliliwat ini nga paypay "$1" tungod an ginsusudlan han paypay nga "$2" in aada la ha pagbasa-la nga kahimtang.
+
+An magdudurmara nga nagtrangka hini in naghatag hini nga eksplenasyon: "$3".',
 'exception-nologin' => 'Diri nakalog-in',
 'exception-nologin-text' => 'Ini nga pakli o pagbuhat in nagkikinahanglan nga ikaw in mag-log-in ha dinhi nga wiki.',
 
@@ -478,7 +488,13 @@ Ayaw paghingalimot hin pagbalyo han imo [[Special:Preferences|{{SITENAME}} mga g
 Alayon pagpili hin lain nga ngaran.',
 'loginerror' => 'Sayop hin pagsakob',
 'createaccounterror' => 'Diri makakahimo hin akawnt: $1',
+'nocookieslogin' => '{{SITENAME}} in nagkikinahanglan hin mga kuki para makapagpalog-in hin mga gumaramit.  An im mga kuki in diri nagana.
+Alayon paganaha hira ngan utro liwat.',
 'loginsuccesstitle' => 'Malinamposon an pagsulod',
+'loginsuccess' => "'''Ikaw in nakalog-in ha {{SITENAME}} komo \"\$1\".'''",
+'nosuchuser' => 'Waray gumaramit an may-ada ngaran nga "$1".
+It mga agnay-hi-gumaramit in case sensitive.
+Panginano-a it imo pagbaybay, o [[Special:UserLogin/signup|paghimo hin bag-o nga akawnt]].',
 'nosuchusershort' => 'Waray nagamit it may ngaran nga "$1".
 Kitaa kun amo it im pagbaybay.',
 'nouserspecified' => 'Dapat nim magbutang hin agnay hit gumaramit.',
@@ -489,6 +505,7 @@ Alayon pagutro pagbutang.',
 Alayon pagutro pagbutang.',
 'passwordtooshort' => 'An tigaman-pagsulod dapat diri maubos hit {{PLURAL:$1|1 nga agi|$1 nga agi}}.',
 'password-name-match' => 'An imo tigaman-pagsulod in kinahanglan iba ha imo agnay-hiton-gumaramit.',
+'password-login-forbidden' => 'An paggamit hini nga agnay-hit-gumaramit ngan tigaman-pagsulod in diri gintutugotan.',
 'mailmypassword' => 'Ig-e-mail an bag-o nga tigaman-pagsulod',
 'passwordremindertitle' => 'Bag-o nga diri-pirmihan nga tigaman-pagsulod para han {{SITENAME}}',
 'noemail' => 'Waray e-mail nga adres nga ginrekord para han nágámit "$1".',
@@ -525,6 +542,12 @@ Temporaryo nga tigaman han pagsakob: $2',
 'passwordreset-emailsent' => 'Ginpadara hin usa ka pahinumdom nga e-mail.',
 
 # Special:ChangeEmail
+'changeemail' => 'Igliwan an e-mail address',
+'changeemail-header' => 'Igliwan an e-mail address akawnt',
+'changeemail-text' => 'Igkompleto ini nga porma para makapagliwan han imo e-mail address.  Kinahanglanon mo igbutang an imo tigaman-pagsulod para makompirma ini nga pagbag-o.',
+'changeemail-no-info' => 'Kinahanglanon mo mag-log-in para ka direkta makasakob hini nga pakli.',
+'changeemail-oldemail' => 'Yana nga e-mail address:',
+'changeemail-newemail' => 'Bag-o nga e-mail address:',
 'changeemail-none' => '(waray)',
 'changeemail-submit' => 'Igbalyo an e-mail',
 'changeemail-cancel' => 'Pasagdi',
@@ -616,6 +639,13 @@ An taramdan han pagpara ngan pagbalhin para han pakli in ginhahatag ha ubos para
 'edit-no-change' => 'Ginpabay-an an im pagliwat, mahitungod nga waray pagbalyo nga nabuhat ha nakasurat.',
 'edit-already-exists' => 'Diri nakakahimo hin bag-o nga pakli.
 Aada na ito.',
+'defaultmessagetext' => 'Aada-nga-daan nga teksto han mensahe',
+
+# Content models
+'content-model-wikitext' => 'wikiteksto',
+'content-model-text' => 'yano nga teksto',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'post-expand-template-inclusion-warning' => "'''Pahimatngon:''' An batakan nga ginlakip in sobra kadako.
@@ -656,7 +686,11 @@ Leyenda: '''({{int:cur}})''' = kaibhan ha giuurhii nga pag-bag-o, '''({{int:last
 'history-feed-item-nocomment' => '$1 ha $2',
 
 # Revision deletion
+'rev-deleted-comment' => '(gintanggal an kaagi han dalikyat nga sumat)',
 'rev-deleted-user' => '(gintanggal an agnay hiton gumaramit)',
+'rev-deleted-event' => '(gintanggal an talaan han mga buhat)',
+'rev-deleted-user-contribs' => '[gintanggal an agnay-hit-gumaramit o IP address - an pagliwat in gintago tikang han mga amot]',
+'rev-suppressed-no-diff' => "Diri mo makikita ini nga kaibhan tungod nga usa ha mga rebisyon in '''ginpara'''.",
 'rev-delundel' => 'igpakita/igtago',
 'rev-showdeleted' => 'igpakita',
 'revdelete-show-file-confirm' => 'Sigurado ka nga gusto mo makita an ginpara nga pagliwat han file "<nowiki>$1</nowiki>" tikang $2 ha $3?',
@@ -668,6 +702,12 @@ Leyenda: '''({{int:cur}})''' = kaibhan ha giuurhii nga pag-bag-o, '''({{int:last
 'revdel-restore' => 'igliwat an nakikit-an',
 'revdel-restore-deleted' => 'napara nga mga pagbag-o',
 'revdel-restore-visible' => 'Mga nakikit-an nga pagbabag-o',
+'pagehist' => 'Kaagi han pakli',
+'deletedhist' => 'Ginpara nga kaagi',
+'revdelete-hide-current' => 'Sayop in natago ha butang nga may petsa $2, $1: Ini an yana nga rebisyon.
+Diri ini matatago.',
+'revdelete-show-no-access' => 'May-ada sayo nga nagpapakita ha butang nga may petsa $2, $1.  Ini nga butang in nakamarka nga "diri malalabtan".
+Diri mo ini malalabtan.',
 'revdelete-otherreason' => 'Lain/dugang nga katadungan:',
 'revdelete-reasonotherlist' => 'Lain nga katadongan',
 'revdelete-edit-reasonlist' => 'Igliwat an mga katadungan han pagpara',
@@ -722,6 +762,7 @@ Leyenda: '''({{int:cur}})''' = kaibhan ha giuurhii nga pag-bag-o, '''({{int:last
 'search-suggest' => 'Buot sidngon mo ba: $1',
 'search-interwiki-caption' => 'Mga bugto nga proyekto',
 'search-interwiki-default' => '$1 nga resulta:',
+'search-relatedarticle' => 'kasumapy',
 'searchrelated' => 'kadugtong',
 'searchall' => 'ngatanan',
 'showingresultsheader' => "{{PLURAL:$5|Resulta '''$1''' han '''$3'''|Mga resulta '''$1 - $2''' han '''$3'''}} para ha '''$4'''",
@@ -729,11 +770,16 @@ Leyenda: '''({{int:cur}})''' = kaibhan ha giuurhii nga pag-bag-o, '''({{int:last
 'powersearch' => 'Abansado nga pagbiling',
 'powersearch-legend' => 'Abansado nga pagbiling',
 'powersearch-field' => 'Bilnga an',
+'powersearch-togglelabel' => 'Panginano-a:',
 'powersearch-toggleall' => 'Ngatanan',
 'powersearch-togglenone' => 'Waray',
 'search-external' => 'Gawas nga pamiling',
+'searchdisabled' => '{{SITENAME}} nga pamiling in ginparong.
+Pamilnga la anay pinaagi ha Google ha pagkayana.
+Ginpapasabot nga an sulod han mga panudlok han {{SITENAME}} in bangin daan an.',
 
 # Quickbar
+'qbsettings' => 'Quickbar',
 'qbsettings-none' => 'Waray',
 'qbsettings-fixedleft' => 'Ginayad an wala',
 'qbsettings-fixedright' => 'Gin-ayad an to-o',
@@ -753,7 +799,12 @@ Leyenda: '''({{int:cur}})''' = kaibhan ha giuurhii nga pag-bag-o, '''({{int:last
 'prefs-rc' => 'Kalalabay la nga mga pagbabag-o',
 'prefs-watchlist-days' => 'Mga adlaw nga makikita ha barantayan:',
 'prefs-resetpass' => 'Igliwan an tigaman-pagsulod',
+'prefs-rendering' => 'Hitsura',
+'saveprefs' => 'Igtipig',
+'resetprefs' => 'Pabay-i an diri nakatipig nga mga pagbabag-o',
+'restoreprefs' => 'Igbalik ngatanan ngada ha kahimtang nga aada-nga-daan',
 'prefs-editing' => 'Ginliliwat',
+'prefs-edit-boxsize' => 'Kadako han bintana han pagliwat.',
 'rows' => 'Mga rumbay pahigda:',
 'columns' => 'Mga rumbay patindog:',
 'searchresultshead' => 'Bilnga',
@@ -761,6 +812,8 @@ Leyenda: '''({{int:cur}})''' = kaibhan ha giuurhii nga pag-bag-o, '''({{int:last
 'savedprefs' => 'Gintipig an im karuyag.',
 'timezonelegend' => 'Zona hin oras',
 'localtime' => 'Oras nga lokal',
+'servertime' => 'Oras han serbidor:',
+'guesstimezone' => 'Butanga tikang han panngaykay(browser)',
 'timezoneregion-africa' => 'Aprika',
 'timezoneregion-america' => 'Amerika',
 'timezoneregion-antarctica' => 'Antarktika',
@@ -936,15 +989,52 @@ An taramdan han pagpara ngan pagbalhin para hini nga pakli in ginhahatag para ha
 'illegal-filename' => 'An ngaran han fayl in diri gintutugutan.',
 'unknown-error' => 'Nahitabo an waray kasasabti nga sayop.',
 'uploadwarning' => 'Pahimatngon han pagkarga paigbaw',
+'savefile' => 'Igtipig an paypay',
 'uploadedimage' => 'ginkarga-paigbaw "[[$1]]"',
+'overwroteimage' => 'Ginkaraga an bag-o nga bersyon han "[[$1]]"',
+'uploaddisabled' => 'Waray ginpagana an pagkarga paigbaw',
+'copyuploaddisabled' => 'An pagkarga paigbaw pinaagi hin URL in waray ginpagana',
+'uploadfromurl-queued' => 'An imo ginkarga-paigbaw hin nakapila.',
+'uploaddisabledtext' => 'An mga pagkarga-paigbaw in diri ginpapagana.',
+'php-uploaddisabledtext' => 'An mga pagkarga-paigbaw han paypay in diri ginpapagana ha PHP.
+Alayon panginanoi an kahimtang han file_uploads.',
+'uploadscripted' => 'Ini nga paypay in nagsusulod hin HTML o script code nga puydi masayopan paghubad an web browser.',
 'uploadvirus' => 'Ini nga fayl may-ada sulod nga bayrus!
 Mga detalye: $1',
 'upload-source' => 'Tinikangan nga fayl',
 'sourcefilename' => 'Tinikangan nga ngaran han fayl:',
+'sourceurl' => 'Tinikangan nga URL:',
+'destfilename' => 'Kakadtoan nga ngaran-hin-paypay:',
+'upload-maxfilesize' => 'Pinakadamo nga kadako han paypay: $1',
+'upload-description' => 'Pangilal-an han paypay',
+'upload-options' => 'Mga pirilion han pagkarga paigbaw',
+'watchthisupload' => 'Bantayi ini nga paypay',
+'upload-success-subj' => 'Malinamposan an imo pagkarga-paigbaw.',
+'upload-success-msg' => 'An imo pagkarga-paigbaw tikang ha [$2] in malinamposon.  Ini in aada dinhi: [[:{{ns:file}}:$1]]',
+'upload-failure-subj' => 'May-ada problema an pagkarga-paigbaw',
+'upload-failure-msg' => 'May-ada problema an imo pagkarga-paigbaw tikang ha [$2]:
+
+$1',
 'upload-warning-subj' => 'Pahimatngon han pagkarga paigbaw',
 
+'upload-proto-error' => 'Sayop nga protocol',
+'upload-file-error' => 'Sayop ha sulod',
 'upload-unknown-size' => 'Waray kasabti an kadako',
 
+# File backend
+'backend-fail-delete' => 'Diri nakakapara han paypay nga "$1".',
+'backend-fail-alreadyexists' => 'May-ada na paypay nga "$1".',
+'backend-fail-store' => 'Diri nakakatipig han paypay "$1" ha "$".',
+'backend-fail-copy' => 'Diri nakakakopya han paypay nga "$1" ngada "$2".',
+'backend-fail-move' => 'Diri nakakabalhin han paypay "$1" ngada "$2".',
+'backend-fail-opentemp' => 'Diri nakakaabre han temporaryo nga paypay.',
+'backend-fail-writetemp' => 'Diri nakakasurat ngada ha temporaryo nga paypay.',
+'backend-fail-closetemp' => 'Diri nasasara an temporaryo nga paypay.',
+'backend-fail-read' => 'Diri nababasahan han paypay nga "$1".',
+'backend-fail-create' => 'Diri nasusuratan an paypay nga "$1".',
+'backend-fail-maxsize' => 'Diri nasusuratan an paypay nga "$1" tungod nga mas dako ini kaysa hin {{PLURAL:"$2|usa nga byte|$2 nga mga byte}}.',
+'backend-fail-readonly' => 'An panluyo nga tiripigan nga "$1" in ha pagkayana in panbasa-la.  An rason nga ginhatag in: "\'\'$2\'\'"',
+
 # img_auth script messages
 'img-auth-accessdenied' => 'Diri gintutugutan makasulod',
 
@@ -1020,7 +1110,7 @@ An paglaladawan han iya [$2 fayl han paglaladawan nga pakli] didto in ginpapakit
 'statistics-header-hooks' => 'Lain nga mga estadistika',
 'statistics-articles' => 'Unod nga mga pakli',
 'statistics-pages' => 'Mga pakli',
-'statistics-pages-desc' => 'Ngatanan nga mga pakli ha sulod hini nga wiki, lakip an<br />hiruhimangraw nga mga pakli, mga redirect, ngan iba pa',
+'statistics-pages-desc' => 'Ngatanan nga mga pakli ha sulod hini nga wiki, lakip an hiruhimangraw nga mga pakli, mga redirect, ngan iba pa',
 'statistics-files' => 'Mga paypay nga iginkarga pasaka',
 'statistics-edits' => 'Mga pagliwat hit pakli tikang gintukod hini nga {{SITENAME}}',
 'statistics-edits-average' => 'Average nga mga pagliwat kada pakli',
@@ -1211,7 +1301,11 @@ Kitaa an $2 para hin talaan han mga gibag-ohi nga mga ginpamara.',
 'restriction-move' => 'Balhina',
 'restriction-create' => 'Himo-a',
 
+# Restriction levels
+'restriction-level-all' => 'bisan ano nga katupngan',
+
 # Undelete
+'undelete' => 'Igpakita an mga ginpara nga mga pakli',
 'undeletelink' => 'igpakita/igbalik',
 'undeleteviewlink' => 'kitaa',
 'undeletecomment' => 'Katadungan:',
@@ -1285,7 +1379,9 @@ Kitaa an $2 para hin talaan han mga gibag-ohi nga mga ginpamara.',
 'blocklist-target' => 'Gin-iigo',
 'blocklist-expiry' => 'Napan-os',
 'blocklist-by' => 'Ginpupugngan an admin',
+'blocklist-reason' => 'Rason:',
 'ipblocklist-submit' => 'Bilnga',
+'ipblocklist-localblock' => 'Lokal nga pagpugong',
 'blocklink' => 'igpugong',
 'unblocklink' => 'igtanggal an pagpugong',
 'change-blocklink' => 'igliwan an papugong',
@@ -1293,6 +1389,7 @@ Kitaa an $2 para hin talaan han mga gibag-ohi nga mga ginpamara.',
 'blocklogpage' => 'Talaan han pagpugong',
 'blocklogentry' => 'ginpugngan hi [[$1]] nga natatapos ha takna hin $2 $3',
 'block-log-flags-nocreate' => 'diri gintutugutan an paghimo hin akawnt',
+'blockme' => 'Pugngi ako',
 'proxyblocksuccess' => 'Human na.',
 
 # Developer tools
@@ -1318,6 +1415,7 @@ Kitaa an $2 para hin talaan han mga gibag-ohi nga mga ginpamara.',
 'export-addcattext' => 'Igdugang an mga pakli tikang ha kaarangay:',
 'export-addcat' => 'Dugngi',
 'export-addnstext' => "Igdugang an mga pakli tikang ha ngaran-lat'ang:",
+'export-addns' => 'Dugngi',
 
 # Namespace 8 related
 'allmessagesname' => 'Ngaran',
@@ -1335,6 +1433,7 @@ Kitaa an $2 para hin talaan han mga gibag-ohi nga mga ginpamara.',
 # Special:Import
 'import-upload-filename' => 'Ngaran han paypay:',
 'import-comment' => 'Komento:',
+'importnopages' => 'Waray pakli nga ginpapaangbit.',
 
 # Tooltip help for the actions
 'tooltip-pt-userpage' => 'An imo pakli hin gumaramit',
@@ -1399,10 +1498,16 @@ Makikit-an nimo an ginkuhaaan',
 
 # Attribution
 'othercontribs' => 'Ginbasihan ha binuhat ni $1.',
+'others' => 'mga iba',
+'siteusers' => '{{SITENAME}} {{PLURAL:$2|gumaramit|mga gumaramit}} $1',
 
 # Info page
+'pageinfo-header-basic' => 'Panguna nga pananabotan',
 'pageinfo-header-edits' => 'Kaagi han pagliwat',
 'pageinfo-header-restrictions' => 'Panalipod han pakli',
+'pageinfo-length' => 'Kahilaba han pakli (ha mga byte)',
+'pageinfo-article-id' => 'ID han pakli',
+'pageinfo-robot-policy' => 'Pamilnga an kahimtang han makina',
 'pageinfo-robot-index' => 'Matutudlok',
 'pageinfo-robot-noindex' => 'Diri matutudlok',
 'pageinfo-views' => 'Ihap han mga naglantaw',
@@ -1472,22 +1577,35 @@ An iba in daan nakatago.
 'exif-sharpness' => 'Pagkatarom',
 'exif-gpstimestamp' => 'GPS nga oras (atomiko nga relo)',
 'exif-gpsspeedref' => 'Sukol han kalaksi',
+'exif-countrydest' => 'Ginpapakita an nasod',
+'exif-countrycodedest' => 'Ginpapakita an kodigo han nasod',
+'exif-provinceorstatedest' => 'Ginpapakita an lalawigan o estado',
+'exif-citydest' => 'Ginpapakita an syudad',
+'exif-sublocationdest' => 'Ginpapakita an bahin-lokasyon han syudad',
+'exif-objectname' => 'Halipot nga titulo',
 'exif-headline' => 'Katukiban',
 'exif-source' => 'Tinikangan',
 'exif-writer' => 'Manunurat',
 'exif-languagecode' => 'Yinaknan',
 'exif-iimcategory' => 'Kaarangay',
+'exif-datetimeexpires' => 'Ayaw gamita kahuman han',
+'exif-datetimereleased' => 'Ginpagawas han',
+'exif-cameraownername' => 'Tag-iya han kamera',
 
 'exif-exposureprogram-1' => 'Mano-mano',
 
 'exif-subjectdistance-value' => '$1 ka mga metro',
 
+'exif-meteringmode-0' => 'Waray kasabti',
+
 'exif-lightsource-0' => 'Waray kasabti',
 'exif-lightsource-9' => 'Maupay nga panahon',
 'exif-lightsource-10' => 'Madampog nga panahon',
 
 'exif-focalplaneresolutionunit-2' => 'pulgadas',
 
+'exif-gaincontrol-0' => 'Waray',
+
 'exif-contrast-1' => 'Mahumok',
 'exif-contrast-2' => 'Matig-a',
 
@@ -1596,6 +1714,7 @@ An iba in daan nakatago.
 
 # Special:Version
 'version' => 'Bersyon',
+'version-skins' => 'Mga panit',
 'version-version' => '(Bersion $1)',
 'version-license' => 'Lisensya',
 'version-software-product' => 'Produkto',
@@ -1608,11 +1727,18 @@ An iba in daan nakatago.
 
 # Special:FileDuplicateSearch
 'fileduplicatesearch-submit' => 'Pamilnga',
-'fileduplicatesearch-noresults' => 'Waray nabilngan nga paypay nga an ngaran "$".',
+'fileduplicatesearch-noresults' => 'Waray nabilngan nga paypay nga an ngaran in "$".',
 
 # Special:SpecialPages
 'specialpages' => 'Mga pinaurog nga pakli',
+'specialpages-group-login' => 'Magpalista nga masakob / paghimo hin bag-o nga akawnt',
+'specialpages-group-users' => 'Mga gumaramit ngan mga katungod',
+'specialpages-group-highuse' => 'Mga pakli nga damo nagamit',
+'specialpages-group-pages' => 'Talaan hin mga pakli',
 'specialpages-group-pagetools' => 'Mga higamit han pakli',
+'specialpages-group-wiki' => 'Datos ngan mga higamit han Wiki',
+'specialpages-group-redirects' => 'Ginreredirek an mga pakli nga pinaurog',
+'specialpages-group-spam' => 'Mga higamit han spam',
 
 # Special:BlankPage
 'blankpage' => 'Blanko nga pakli',
index cc7e5a6..6f5ba40 100644 (file)
@@ -341,7 +341,7 @@ $messages = array(
 'vector-action-protect' => 'שיצן',
 'vector-action-undelete' => 'מבטל זיין אויסמעקן',
 'vector-action-unprotect' => 'ענדערונג באַשיצונג',
-'vector-simplesearch-preference' => '×\90ַק×\98×\99×\95×\95×\99ר×\9f ×¤Ö¿×\90ַר×\91ר×\99×\99×\98ער×\98×¢ ×\96×\95×\9a ×¤Ö¿×\90רש×\9c×\90Ö¸×\92×\9f (נאר וועקטאר)',
+'vector-simplesearch-preference' => '×\93ער×\9e×¢×\92×\9c×¢×\9b×\9f ×¤Ö¿×\90ַרפש×\95×\98ער×\98×\9f ×\96×\95×\9a ×¤×\90ַס (נאר וועקטאר)',
 'vector-view-create' => 'שאַפֿן',
 'vector-view-edit' => 'רעדאַקטירן',
 'vector-view-history' => 'ווײַזן היסטאָריע',
@@ -969,6 +969,7 @@ $2
 'edit-already-exists' => 'נישט מעגליך צו שאַפֿן נייע בלאט.
 ער עקזיסטירט שוין.',
 'defaultmessagetext' => 'גרונטלעכער מעלדונג טעקסט',
+'invalid-content-data' => 'אומגילטיקע אינהאלט דאטן',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => "'''אזהרה:''' דער בלאט אנטהאלט צופיל טייערע פארזירער רופן.
@@ -1422,6 +1423,7 @@ $1",
 'right-upload' => 'ארויפלאדן טעקעס',
 'right-reupload' => 'איבערשרײַבן עקסיסטירנדע טעקע',
 'right-reupload-own' => "איבערשרײַבן עקזיסטירנדע טעקעס וואָס מ'האט אַליין אַרויפֿגעלאָדן",
+'right-reupload-shared' => 'אריבערשרייבן טעקעס אויפן געמיינזאם מעדיע רעפאזיטאריום',
 'right-upload_by_url' => 'ארויפֿלאָדן טעקעס פֿון אַ URL',
 'right-purge' => 'ליידיקן דעם זייטל־זאפאס פאר א בלאט אן באשטעטיקונג',
 'right-autoconfirmed' => 'רעדאקטירן האלב-געשיצטע בלעטער',
@@ -1599,6 +1601,7 @@ $1",
 'badfilename' => 'טעקע נאמען איז געטוישט צו "$1".',
 'filetype-mime-mismatch' => 'טעקע סופֿיקס ".$1" שטימט נישט מיטן MIME טיפ פון דער טעקע($2).',
 'filetype-badmime' => 'טעקעס מיטן  MIME טיפ "$1" טאר מען נישט ארויפלאדן.',
+'filetype-bad-ie-mime' => 'נישט מעגלעך ארויפלאד די טעקע ווייל אינטערנעץ עקספלארער וועט זי דערקענען ווי "$1", וואס איז א נישט דערלויבטער און פאטענציאעל געפערליכער טעקע טיפ.',
 'filetype-unwanted-type' => "'''\".\$1\"''' איז אן אומרעקאמענדירטער טעקע־טיפ. {{PLURAL:\$3|רעקאמענדירטער טעקע־טיפ איז|רעקאמענדירטע טעקע־טיפן זענען}} \$2.",
 'filetype-banned-type' => '\'\'\'".$1"\'\'\' {{PLURAL:$4|איז נישט קיין דערלויבטער טעקע־טיפ |זענען נישט קיין דערלויבטע טעקע־טיפן}}. {{PLURAL:$3|דערלויבטער טעקע־טיפ איז|דערלויבטע טעקע־טיפן זענען}} $2.',
 'filetype-missing' => 'די טעקע האט נישט קיין פארברייטערונג (למשל ".jpg").',
@@ -1624,6 +1627,9 @@ $1",
 * נאמען פון דער טעקע וואס ווערט ארויפגעלאָדן: <strong>[[:$1]]</strong>
 * נאמען פון דער פֿאראנענער טעקע: <strong>[[:$2]]</strong>
 זײַט אזוי גוט און קלויבט אן אנדער נאמען.',
+'file-thumbnail-no' => "דער טעקע־נאמען הייבט אן מיט <strong>$1</strong>.
+זי זעט אויס ווי א פארקלענערט בילד ''(מיניאטור)''.
+טאמער האט איר דאס בילד אין פולער רעזאלוציע טוט עס ארויפלאדן, אנדערשט זייט אזוי גוט און ענדערט דעם טעקע־נאמען.",
 'fileexists-forbidden' => 'א טעקע מיט דעם נאָמען עקזיסטירט שוין, און מען קען זי נישט אַריבערשרײַבן. 
 אויב איר ווילט דאך אַרויפֿלאָדן אײַער טעקע, ביטע גיין צוריק און ניצן אַן אַנדער נאָמען. 
 [[File:$1|thumb|center|$1]]',
@@ -1735,6 +1741,7 @@ $1",
 'license-header' => 'ליצענץ:',
 'nolicense' => 'גארנישט',
 'license-nopreview' => '(פֿאראויסקוק נישט פֿאַראַן)',
+'upload_source_url' => ' (א גילטיקע , צוגעגנלעכער URL)',
 'upload_source_file' => '(א טעקע אויף אײַער קאמפיוטער)',
 
 # Special:ListFiles
@@ -1796,6 +1803,7 @@ $1",
 'filerevert-defaultcomment' => 'צוריקגעשטעלט צו דער ווערסיע פֿון $2, $1',
 'filerevert-submit' => 'צוריקדרייען',
 'filerevert-success' => "'''[[Media:$1|$1]]''' צוריקגשטעלט צו דער [$4 ווערסיע פֿון $3, $2].",
+'filerevert-badversion' => 'נישט פאראן קיין פריערדיקע לאקאלע ווערסיע פון דער טעקע מיטן געזוכטן צייטשטעמפל.',
 
 # File deletion
 'filedelete' => 'מעק אויס $1',
@@ -2314,7 +2322,7 @@ $UNWATCHURL
 'undeletedrevisions' => '{{PLURAL:$1|1 רעוויזיע|$1 רעוויזיעס}} צוריקגעשטעלט',
 'undeletedrevisions-files' => '{{PLURAL:$1|1 רעוויזיע|$1 רעוויזיעס}} און  {{PLURAL:$2|1 טעקע|$2 טעקעס}} צוריקגעשטעלט',
 'undeletedfiles' => '{{PLURAL:$1|1 טעקע|$1 טעקעס}} צוריקגעשטעלט',
-'cannotundelete' => 'צוריקשטעלונג איז דורכגעפאלן; עס איז מעגליך אז אן אנדערע האט דאס שוין צוריקגעשטעלט.',
+'cannotundelete' => 'צוריקשטעלונג איז דורכגעפאלן: $1',
 'undeletedpage' => "'''דער בלאט $1 איז געווארן צוריקגעשטעלט.'''
 
 זעט דעם [[Special:Log/delete| אויסמעקן לאג]] פֿאר א ליסטע פון די לעצטע אויסגעמעקטע און צוריקגעשטעלטע בלעטער.",
@@ -2323,6 +2331,7 @@ $UNWATCHURL
 'undelete-search-box' => 'זוכן אויסגעמעקטע בלעטער',
 'undelete-search-prefix' => 'ווײַז בלעטער וואס הייבן אן מיט:',
 'undelete-search-submit' => 'זוכן',
+'undelete-no-results' => 'נישט געטראפן קיין צוגעפאסטע בלעטער אין אויסמעקונג ארכיוו.',
 'undelete-error' => 'גרייז ביים צוריקשטעלן בלאט',
 'undelete-error-short' => 'טעות ביים צוריקשטעלן טעקע: $1',
 'undelete-error-long' => 'גרײַזן געטראפֿן בײַם ווידערשטעלן די טעקע:
@@ -2336,6 +2345,7 @@ $1',
 'namespace' => 'נאמענטייל:',
 'invert' => 'ווײַז אַלע אויסער די',
 'namespace_association' => 'אָנגעבונדענער נאָמענטייל',
+'tooltip-namespace_association' => 'צייכנט דאס קעסטל כדי איינשליסן דעם שמועס אדער סוביעקט נאמענטייל וואס געהערט צום אויסגעקליבענעם נאמענטייל',
 'blanknamespace' => '(הויפט)',
 
 # Contributions
@@ -2618,6 +2628,8 @@ $1',
 'imageinvalidfilename' => 'דער ציל טעקע נאָמען איז נישט גילטיק.',
 'fix-double-redirects' => 'דערהײַנטיקן ווײַטערפֿירונגען צום ארגינעלן טיטל',
 'move-leave-redirect' => 'איבערלאזן א ווײַטערפֿירונג',
+'file-exists-sharedrepo' => "ס'איז שוין פאראן א טעקע מיטן געקליבענעם נאמען אויף א געמיינזאם רעפאזיטאריום.
+זייט אזוי גוט קלייבט אן אנדער נאמען.",
 
 # Export
 'export' => 'עקספארטירן בלעטער',
@@ -2721,6 +2733,7 @@ $1',
 'import-error-interwiki' => 'דעם בלאט "$1"  קען מען נישט אימפארטירן ווייל זיין נאמען איז רעזערווירט פאר דרויסנדיקער פארבינדונג (אינטערוויקי).',
 'import-error-special' => 'דעם בלאט "$1" קען מען נישט אימפארטירן ווייל ער געהערט צו א באזונדערן נאמענטייל וואס אנטהאלט נישט קיין בלעטער.',
 'import-error-invalid' => 'דעם בלאט "$1" קען מען נישט אימפארטירן ווייל זיין נאמען איז אומגילטיק.',
+'import-rootpage-nosubpage' => 'נאמענטייל "$1" פונעם שטאמבלאט ערלויבט נישט קיין אונטערבלעטער.',
 
 # Import log
 'importlogpage' => 'אימפארט לאגבוך',
@@ -3054,6 +3067,7 @@ $1',
 'exif-saturation' => 'זעטיקונג',
 'exif-sharpness' => 'שארף',
 'exif-devicesettingdescription' => 'אפאראט שטעלונגען אראפמאלונג',
+'exif-imageuniqueid' => 'בילד־ID',
 'exif-gpslatituderef' => 'צפון אדער דרום גארטל־ליניע',
 'exif-gpslatitude' => 'גארטל־ליניע',
 'exif-gpslongituderef' => 'מזרח אדער מערב לענג',
@@ -3083,6 +3097,7 @@ $1',
 'exif-keywords' => 'שליסלווערטער',
 'exif-worldregioncreated' => "וועלטראיאן וואו מ'האט גענומען דאס בילד",
 'exif-countrycreated' => "לאנד וואו מ'האט געמאכט דאס בילד",
+'exif-countrycodecreated' => "קאד פארן לאנד וואו מ'האט געמאכט דאס בילד",
 'exif-provinceorstatecreated' => "פראווינץ אדער שטאַט וואו מ'האט גענומען דאס בילד",
 'exif-citycreated' => "שטאָט וואו מ'האט געמאכט דאס בילד",
 'exif-worldregiondest' => 'וועלטראיאן געוויזן',
@@ -3113,6 +3128,7 @@ $1',
 'exif-cameraownername' => 'אייגנטימער פון קאמערע',
 'exif-label' => 'צעטל',
 'exif-datetimemetadata' => 'דאטע ווען מעטאדאטן זענען געווען לעצט געענדערט',
+'exif-nickname' => 'אויספארמעלער נאמען פון בילד',
 'exif-rating' => 'שאצונג (פֿון 5)',
 'exif-rightscertificate' => 'רעכטן פארוואלטונג צערטיפיקאט',
 'exif-copyrighted' => 'קאפירעכט סטאַטוס',
@@ -3129,6 +3145,9 @@ $1',
 # EXIF attributes
 'exif-compression-1' => 'אומ-צאמגעקוועטשט',
 
+'exif-copyrighted-true' => 'געשיצט מיט קאפירעכט',
+'exif-copyrighted-false' => 'פובליקער געביט',
+
 'exif-unknowndate' => 'אומבאַוואוסטע דאַטע',
 
 'exif-orientation-1' => 'נארמאַל',
index 8226da9..2136d18 100644 (file)
@@ -2938,7 +2938,7 @@ $1被封禁的理由是:“$2”',
 'spam_deleting' => '正在删除所有包含至$1的版本',
 
 # Info page
-'pageinfo-title' => '"$1" 的信息',
+'pageinfo-title' => '“$1”的信息',
 'pageinfo-header-basic' => '基本信息',
 'pageinfo-header-edits' => '编辑历史',
 'pageinfo-header-restrictions' => '页面保护',
@@ -2950,7 +2950,7 @@ $1被封禁的理由是:“$2”',
 'pageinfo-robot-policy' => '搜索引擎状态',
 'pageinfo-robot-index' => '可索引',
 'pageinfo-robot-noindex' => '不可索引',
-'pageinfo-views' => '视图的数量',
+'pageinfo-views' => '查看次数',
 'pageinfo-watchers' => '页面监视者人数',
 'pageinfo-redirects-name' => '重定向到本页',
 'pageinfo-subpages-name' => '本页的子页面',
@@ -2961,7 +2961,7 @@ $1被封禁的理由是:“$2”',
 'pageinfo-lasttime' => '最后编辑的日期',
 'pageinfo-edits' => '总编辑次数',
 'pageinfo-authors' => '不同编者总计',
-'pageinfo-recent-edits' => '最近的编辑数 ($1天内)',
+'pageinfo-recent-edits' => '最近的编辑数($1内)',
 'pageinfo-recent-authors' => '最近的不同编者数',
 'pageinfo-magic-words' => '魔术字 ($1)',
 'pageinfo-hidden-categories' => '隐藏分类 ($1)',
index 1be7036..f821d63 100644 (file)
@@ -965,6 +965,14 @@ $2
 'edit-already-exists' => '不可以建立一個新頁面。
 它已經存在。',
 'defaultmessagetext' => '預設訊息文字',
+'content-failed-to-parse' => '未能轉換$2 內容成為$1:$3',
+'invalid-content-data' => '內容資料無效',
+'content-not-allowed-here' => '[[$2]]不允許"$1"頁上的內容',
+
+# Content models
+'content-model-text' => '純文字',
+'content-model-javascript' => 'JavaScript',
+'content-model-css' => 'CSS',
 
 # Parser/template warnings
 'expensive-parserfunction-warning' => '警告: 這個頁面有太多耗費的語法功能呼叫。
@@ -2380,7 +2388,7 @@ $UNWATCHURL
 'undeletedrevisions' => '$1個修訂版本已經恢復',
 'undeletedrevisions-files' => '$1 個版本和 $2 個檔案被恢復',
 'undeletedfiles' => '$1 個檔案被恢復',
-'cannotundelete' => 'æ\81¢å¾©å¤±æ\95\97ï¼\9bå\8f¯è\83½ä¹\8bå\89\8då·²ç¶\93被å\85¶ä»\96人æ\81¢å¾©ã\80\82',
+'cannotundelete' => 'æ\81¢å¾©å¤±æ\95\97ï¼\9a$1',
 'undeletedpage' => "'''$1已經被恢復''' 請參考[[Special:Log/delete|刪除日誌]]來查詢刪除及恢復記錄。",
 'undelete-header' => '如要查詢最近的記錄請參閱[[Special:Log/delete|刪除日誌]]。',
 'undelete-search-title' => '搜索已刪除頁面',
@@ -2683,6 +2691,7 @@ $1被封禁的理由是“$2”',
 'immobile-target-namespace-iw' => '垮維基連結在移動頁面中是無效的目標。',
 'immobile-source-page' => '這個頁面不能移動。',
 'immobile-target-page' => '無法移動至目標標題中。',
+'bad-target-model' => '所需的目的地使用不同的內容模式。不可以從$1轉換到 $2 。',
 'imagenocrossnamespace' => '不可以移動檔案到非檔案名字空間',
 'nonfile-cannot-move-to-file' => '不可以移動非檔案到檔案名字空間',
 'imagetypemismatch' => '該新副檔名不匹配它的類型',
@@ -2942,7 +2951,7 @@ $1被封禁的理由是“$2”',
 'spam_deleting' => '所有包含連結至$1的修訂,刪除中',
 
 # Info page
-'pageinfo-title' => '" $1 "的信息',
+'pageinfo-title' => '“$1”的信息',
 'pageinfo-header-basic' => '基本資料',
 'pageinfo-header-edits' => '編輯歷史',
 'pageinfo-header-restrictions' => '保護頁面',
diff --git a/maintenance/archives/patch-fa_sha1.sql b/maintenance/archives/patch-fa_sha1.sql
new file mode 100644 (file)
index 0000000..931bc44
--- /dev/null
@@ -0,0 +1,4 @@
+-- Add fa_sha1 and related index
+ALTER TABLE /*$wgDBprefix*/filearchive
+  ADD COLUMN fa_sha1 varbinary(32) NOT NULL default '';
+CREATE INDEX /*i*/fa_sha1 ON /*$wgDBprefix*/filearchive (fa_sha1(10));
diff --git a/maintenance/archives/patch-sites.sql b/maintenance/archives/patch-sites.sql
new file mode 100644 (file)
index 0000000..8839274
--- /dev/null
@@ -0,0 +1,71 @@
+-- Patch to add the sites and site_identifiers tables.
+-- Licence: GNU GPL v2+
+-- Author: Jeroen De Dauw < jeroendedauw@gmail.com >
+
+
+-- Holds all the sites known to the wiki.
+CREATE TABLE IF NOT EXISTS /*_*/sites (
+-- Numeric id of the site
+  site_id                    INT UNSIGNED        NOT NULL PRIMARY KEY AUTO_INCREMENT,
+
+  -- Global identifier for the site, ie 'enwiktionary'
+  site_global_key            varbinary(32)       NOT NULL,
+
+  -- Type of the site, ie 'mediawiki'
+  site_type                  varbinary(32)       NOT NULL,
+
+  -- Group of the site, ie 'wikipedia'
+  site_group                 varbinary(32)       NOT NULL,
+
+  -- Source of the site data, ie 'local', 'wikidata', 'my-magical-repo'
+  site_source                varbinary(32)       NOT NULL,
+
+  -- Language code of the sites primary language.
+  site_language              varbinary(32)       NOT NULL,
+
+  -- Protocol of the site, ie 'http://', 'irc://', '//'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_protocol              varbinary(32)       NOT NULL,
+
+  -- Domain of the site in reverse order, ie 'org.mediawiki.www.'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_domain                VARCHAR(255)        NOT NULL,
+
+  -- Type dependent site data.
+  site_data                  BLOB                NOT NULL,
+
+  -- If site.tld/path/key:pageTitle should forward users to  the page on
+  -- the actual site, where "key" is the local identifier.
+  site_forward              bool                NOT NULL,
+
+  -- Type dependent site config.
+  -- For instance if template transclusion should be allowed if it's a MediaWiki.
+  site_config               BLOB                NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE UNIQUE INDEX /*i*/sites_global_key ON /*_*/sites (site_global_key);
+CREATE INDEX /*i*/sites_type ON /*_*/sites (site_type);
+CREATE INDEX /*i*/sites_group ON /*_*/sites (site_group);
+CREATE INDEX /*i*/sites_source ON /*_*/sites (site_source);
+CREATE INDEX /*i*/sites_language ON /*_*/sites (site_language);
+CREATE INDEX /*i*/sites_protocol ON /*_*/sites (site_protocol);
+CREATE INDEX /*i*/sites_domain ON /*_*/sites (site_domain);
+CREATE INDEX /*i*/sites_forward ON /*_*/sites (site_forward);
+
+
+
+-- Links local site identifiers to their corresponding site.
+CREATE TABLE IF NOT EXISTS /*_*/site_identifiers (
+  -- Key on site.site_id
+  si_site                    INT UNSIGNED        NOT NULL,
+
+  -- local key type, ie 'interwiki' or 'langlink'
+  si_type                    varbinary(32)       NOT NULL,
+
+  -- local key value, ie 'en' or 'wiktionary'
+  si_key                     varbinary(32)       NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE UNIQUE INDEX /*i*/site_ids_type ON /*_*/site_identifiers (si_type, si_key);
+CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site);
+CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key);
\ No newline at end of file
index e638b17..cc09703 100644 (file)
@@ -35,14 +35,19 @@ class DeleteArchivedFilesImplementation {
                $repo = RepoGroup::singleton()->getLocalRepo();
                # Get "active" revisions from the filearchive table
                $output->handleOutput( "Searching for and deleting archived files...\n" );
-               $res = $dbw->query( "SELECT fa_id,fa_storage_group,fa_storage_key FROM $tbl_arch" );
+               $res = $dbw->query( "SELECT fa_id,fa_storage_group,fa_storage_key,fa_sha1 FROM $tbl_arch" );
                $count = 0;
                foreach ( $res as $row ) {
                        $key = $row->fa_storage_key;
                        $group = $row->fa_storage_group;
                        $id = $row->fa_id;
                        $path = $repo->getZonePath( 'deleted' ) . '/' . $repo->getDeletedHashPath( $key ) . $key;
-                       $sha1 = substr( $key, 0, strcspn( $key, '.' ) );
+                       if( isset( $row->fa_sha1 ) ) {
+                               $sha1 = $row->fa_sha1;
+                       } else {
+                               // old row, populate from key
+                               $sha1 = LocalRepo::getHashFromKey( $key );
+                       }
                        // Check if the file is used anywhere...
                        $inuse = $dbw->selectField( 'oldimage', '1',
                                array( 'oi_sha1' => $sha1,
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 5aefe1c..69cf548 100644 (file)
@@ -43,7 +43,7 @@ if ( isset( $options['d'] ) ) {
        }
        if ( $d > 1 ) {
                $lb = wfGetLB();
-               $serverCount = $lb->getServerCount(); 
+               $serverCount = $lb->getServerCount();
                for ( $i = 0; $i < $serverCount; $i++ ) {
                        $server = $lb->getServerInfo( $i );
                        $server['flags'] |= DBO_DEBUG;
index e273c54..9ad4df4 100644 (file)
@@ -64,6 +64,7 @@ class FindHooks extends Maintenance {
                        $IP . '/includes/actions/',
                        $IP . '/includes/api/',
                        $IP . '/includes/cache/',
+                       $IP . '/includes/content/',
                        $IP . '/includes/context/',
                        $IP . '/includes/db/',
                        $IP . '/includes/diff/',
@@ -170,7 +171,7 @@ class FindHooks extends Maintenance {
        private function getHooksFromFile( $file ) {
                $content = file_get_contents( $file );
                $m = array();
-               preg_match_all( '/(?:wfRunHooks|Hooks\:\:run)\(\s*([\'"])(.*?)\1/', $content, $m );
+               preg_match_all( '/(?:wfRunHooks|Hooks\:\:run|ContentHandler\:\:runLegacyHooks)\(\s*([\'"])(.*?)\1/', $content, $m );
                return $m[2];
        }
 
index eaf170b..2980e66 100644 (file)
@@ -2344,6 +2344,7 @@ $wgMessageStructure = array(
                'immobile-target-namespace-iw',
                'immobile-source-page',
                'immobile-target-page',
+               'bad-target-model',
                'immobile_namespace',
                'imagenocrossnamespace',
                'nonfile-cannot-move-to-file',
@@ -2672,6 +2673,7 @@ $wgMessageStructure = array(
        'info' => array(
                'pageinfo-header',
                'pageinfo-title',
+               'pageinfo-not-current',
                'pageinfo-header-basic',
                'pageinfo-header-edits',
                'pageinfo-header-restrictions',
diff --git a/maintenance/oracle/archives/patch-archive-ar_content_format.sql b/maintenance/oracle/archives/patch-archive-ar_content_format.sql
new file mode 100644 (file)
index 0000000..0c0c0d9
--- /dev/null
@@ -0,0 +1,3 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.archive ADD ar_content_format VARCHAR2(64);
diff --git a/maintenance/oracle/archives/patch-archive-ar_content_model.sql b/maintenance/oracle/archives/patch-archive-ar_content_model.sql
new file mode 100644 (file)
index 0000000..d18fc9e
--- /dev/null
@@ -0,0 +1,3 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.archive ADD ar_content_model VARCHAR2(32);
diff --git a/maintenance/oracle/archives/patch-cat_hidden.sql b/maintenance/oracle/archives/patch-cat_hidden.sql
new file mode 100644 (file)
index 0000000..d1649c7
--- /dev/null
@@ -0,0 +1,4 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.category DROP COLUMN cat_hidden;
+
diff --git a/maintenance/oracle/archives/patch-page-page_content_model.sql b/maintenance/oracle/archives/patch-page-page_content_model.sql
new file mode 100644 (file)
index 0000000..e5839d9
--- /dev/null
@@ -0,0 +1,3 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.page ADD page_content_model VARCHAR2(32);
diff --git a/maintenance/oracle/archives/patch-rc_moved.sql b/maintenance/oracle/archives/patch-rc_moved.sql
new file mode 100644 (file)
index 0000000..2a71315
--- /dev/null
@@ -0,0 +1,4 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.recentchanges DROP ( rc_moved_to_ns, rc_moved_to_title );
+
diff --git a/maintenance/oracle/archives/patch-revision-rev_content_format.sql b/maintenance/oracle/archives/patch-revision-rev_content_format.sql
new file mode 100644 (file)
index 0000000..ebde71c
--- /dev/null
@@ -0,0 +1,3 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.revision ADD rev_content_format VARCHAR2(64);
diff --git a/maintenance/oracle/archives/patch-revision-rev_content_model.sql b/maintenance/oracle/archives/patch-revision-rev_content_model.sql
new file mode 100644 (file)
index 0000000..dd22642
--- /dev/null
@@ -0,0 +1,3 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.revision ADD rev_content_model VARCHAR2(32);
diff --git a/maintenance/oracle/archives/patch-ss_admins.sql b/maintenance/oracle/archives/patch-ss_admins.sql
new file mode 100644 (file)
index 0000000..c2e9242
--- /dev/null
@@ -0,0 +1,4 @@
+define mw_prefix='{$wgDBprefix}';
+
+ALTER TABLE &mw_prefix.site_stats DROP COLUMN ss_admins;
+
index 3f9b376..d0712e3 100644 (file)
@@ -73,7 +73,8 @@ CREATE TABLE &mw_prefix.page (
   page_random        NUMBER(15,14) NOT NULL,
   page_touched       TIMESTAMP(6) WITH TIME ZONE,
   page_latest        NUMBER        DEFAULT 0 NOT NULL, -- FK?
-  page_len           NUMBER        DEFAULT 0 NOT NULL
+  page_len           NUMBER        DEFAULT 0 NOT NULL,
+  page_content_model VARCHAR2(32)
 );
 ALTER TABLE &mw_prefix.page ADD CONSTRAINT &mw_prefix.page_pk PRIMARY KEY (page_id);
 CREATE UNIQUE INDEX &mw_prefix.page_u01 ON &mw_prefix.page (page_namespace,page_title);
@@ -83,7 +84,7 @@ CREATE INDEX &mw_prefix.page_i03 ON &mw_prefix.page (page_is_redirect, page_name
 
 -- Create a dummy page to satisfy fk contraints especially with revisions
 INSERT INTO &mw_prefix.page
-  VALUES (0, 0, ' ', NULL, 0, 0, 0, 0, current_timestamp, 0, 0);
+  VALUES (0, 0, ' ', NULL, 0, 0, 0, 0, current_timestamp, 0, 0, NULL);
 
 /*$mw$*/
 CREATE TRIGGER &mw_prefix.page_set_random BEFORE INSERT ON &mw_prefix.page
@@ -106,7 +107,9 @@ CREATE TABLE &mw_prefix.revision (
   rev_deleted     CHAR(1)         DEFAULT '0' NOT NULL,
   rev_len         NUMBER          NULL,
   rev_parent_id   NUMBER          DEFAULT NULL,
-  rev_sha1               VARCHAR2(32)    NULL
+  rev_sha1               VARCHAR2(32)    NULL,
+  rev_content_model VARCHAR2(32),
+  rev_content_format VARCHAR2(64)
 );
 ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_pk PRIMARY KEY (rev_id);
 ALTER TABLE &mw_prefix.revision ADD CONSTRAINT &mw_prefix.revision_fk1 FOREIGN KEY (rev_page) REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
@@ -142,7 +145,9 @@ CREATE TABLE &mw_prefix.archive (
   ar_len         NUMBER,
   ar_page_id     NUMBER,
   ar_parent_id   NUMBER,
-  ar_sha1                VARCHAR2(32)    NULL
+  ar_sha1                VARCHAR2(32),
+  ar_content_model VARCHAR2(32),
+  ar_content_format VARCHAR2(64)
 );
 ALTER TABLE &mw_prefix.archive ADD CONSTRAINT &mw_prefix.archive_fk1 FOREIGN KEY (ar_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
 CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp);
@@ -197,8 +202,7 @@ CREATE TABLE &mw_prefix.category (
   cat_title VARCHAR2(255) NOT NULL,
   cat_pages NUMBER DEFAULT 0 NOT NULL,
   cat_subcats NUMBER DEFAULT 0 NOT NULL,
-  cat_files NUMBER DEFAULT 0 NOT NULL,
-  cat_hidden NUMBER DEFAULT 0 NOT NULL
+  cat_files NUMBER DEFAULT 0 NOT NULL
 );
 ALTER TABLE &mw_prefix.category ADD CONSTRAINT &mw_prefix.category_pk PRIMARY KEY (cat_id);
 CREATE UNIQUE INDEX &mw_prefix.category_u01 ON &mw_prefix.category (cat_title);
@@ -246,7 +250,6 @@ CREATE TABLE &mw_prefix.site_stats (
   ss_total_pages    NUMBER            DEFAULT -1,
   ss_users          NUMBER            DEFAULT -1,
   ss_active_users   NUMBER            DEFAULT -1,
-  ss_admins         NUMBER            DEFAULT -1,
   ss_images         NUMBER            DEFAULT 0
 );
 CREATE UNIQUE INDEX &mw_prefix.site_stats_u01 ON &mw_prefix.site_stats (ss_row_id);
diff --git a/maintenance/populateFilearchiveSha1.php b/maintenance/populateFilearchiveSha1.php
new file mode 100644 (file)
index 0000000..e9baef9
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Optional upgrade script to populate the fa_sha1 field
+ *
+ * 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
+ * @ingroup Maintenance
+ */
+
+require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+
+/**
+ * Maintenance script to populate the fa_sha1 field.
+ *
+ * @ingroup Maintenance
+ * @since 1.21
+ */
+class PopulateFilearchiveSha1 extends LoggedUpdateMaintenance {
+       public function __construct() {
+               parent::__construct();
+               $this->mDescription = "Populate the fa_sha1 field from fa_storage_key";
+       }
+
+       protected function getUpdateKey() {
+               return 'populate fa_sha1';
+       }
+
+       protected function updateSkippedMessage() {
+               return 'fa_sha1 column of filearchive table already populated.';
+       }
+
+       public function doDBUpdates() {
+               $startTime = microtime( true );
+               $dbw = wfGetDB( DB_MASTER );
+               $table = 'filearchive';
+               $conds = array( 'fa_sha1' => '', 'fa_storage_key IS NOT NULL' );
+               $this->output( "Populating fa_sha1 field from fa_storage_key\n" );
+               $endId = $dbw->selectField( $table, 'MAX(fa_id)', false, __METHOD__ );\r
+
+               $batchSize = $this->mBatchSize;
+               $done = 0;
+
+               do {
+                       $res = $dbw->select(
+                               $table,
+                               array( 'fa_id', 'fa_storage_key' ),
+                               $conds,
+                               __METHOD__,
+                               array( 'LIMIT' => $batchSize )
+                       );
+
+                       $i = 0;
+                       foreach ( $res as $row ) {
+                               $sha1 = LocalRepo::getHashFromKey( $row->fa_storage_key );
+                               $dbw->update( $table,
+                                       array( 'fa_sha1' => $sha1 ),
+                                       array( 'fa_id' => $row->fa_id ),
+                                       __METHOD__
+                               );
+                               $lastId = $row->fa_id;
+                               $i++;
+                       }
+
+                       $done += $i;
+                       if( $i !== $batchSize ) {
+                               break;
+                       }
+
+                       // print status and let slaves catch up
+                       $this->output( sprintf(
+                               "id %d done (up to %d), %5.3f%%  \r", $lastId, $endId, $lastId / $endId * 100 ) );
+                       wfWaitForSlaves();
+               } while( true );
+
+               $processingTime = microtime( true ) - $startTime;
+               $this->output( sprintf( "\nDone %d files in %.1f seconds\n", $done, $processingTime ) );
+
+               return true; // we only updated *some* files, don't log
+       }
+}
+
+$maintClass = "PopulateFilearchiveSha1";
+require_once( RUN_MAINTENANCE_IF_MAIN );
index 1e3eecb..8c91f29 100644 (file)
@@ -79,7 +79,8 @@ CREATE TABLE page (
   page_random        NUMERIC(15,14) NOT NULL  DEFAULT RANDOM(),
   page_touched       TIMESTAMPTZ,
   page_latest        INTEGER        NOT NULL, -- FK?
-  page_len           INTEGER        NOT NULL
+  page_len           INTEGER        NOT NULL,
+  page_content_model TEXT
 );
 CREATE UNIQUE INDEX page_unique_name ON page (page_namespace, page_title);
 CREATE INDEX page_main_title         ON page (page_title text_pattern_ops) WHERE page_namespace = 0;
@@ -104,18 +105,20 @@ CREATE TRIGGER page_deleted AFTER DELETE ON page
 
 CREATE SEQUENCE revision_rev_id_seq;
 CREATE TABLE revision (
-  rev_id          INTEGER      NOT NULL  UNIQUE DEFAULT nextval('revision_rev_id_seq'),
-  rev_page        INTEGER          NULL  REFERENCES page (page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
-  rev_text_id     INTEGER          NULL, -- FK
-  rev_comment     TEXT,
-  rev_user        INTEGER      NOT NULL  REFERENCES mwuser(user_id) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED,
-  rev_user_text   TEXT         NOT NULL,
-  rev_timestamp   TIMESTAMPTZ  NOT NULL,
-  rev_minor_edit  SMALLINT     NOT NULL  DEFAULT 0,
-  rev_deleted     SMALLINT     NOT NULL  DEFAULT 0,
-  rev_len         INTEGER          NULL,
-  rev_parent_id   INTEGER          NULL,
-  rev_sha1        TEXT         NOT NULL DEFAULT ''
+  rev_id             INTEGER      NOT NULL  UNIQUE DEFAULT nextval('revision_rev_id_seq'),
+  rev_page           INTEGER          NULL  REFERENCES page (page_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
+  rev_text_id        INTEGER          NULL, -- FK
+  rev_comment        TEXT,
+  rev_user           INTEGER      NOT NULL  REFERENCES mwuser(user_id) ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED,
+  rev_user_text      TEXT         NOT NULL,
+  rev_timestamp      TIMESTAMPTZ  NOT NULL,
+  rev_minor_edit     SMALLINT     NOT NULL  DEFAULT 0,
+  rev_deleted        SMALLINT     NOT NULL  DEFAULT 0,
+  rev_len            INTEGER          NULL,
+  rev_parent_id      INTEGER          NULL,
+  rev_sha1           TEXT         NOT NULL DEFAULT '',
+  rev_content_model  TEXT,
+  rev_content_format TEXT
 );
 CREATE UNIQUE INDEX revision_unique ON revision (rev_page, rev_id);
 CREATE INDEX rev_text_id_idx        ON revision (rev_text_id);
@@ -153,22 +156,24 @@ ALTER TABLE page_props ADD CONSTRAINT page_props_pk PRIMARY KEY (pp_page,pp_prop
 CREATE INDEX page_props_propname ON page_props (pp_propname);
 
 CREATE TABLE archive (
-  ar_namespace   SMALLINT     NOT NULL,
-  ar_title       TEXT         NOT NULL,
-  ar_text        TEXT, -- technically should be bytea, but not used anymore
-  ar_page_id     INTEGER          NULL,
-  ar_parent_id   INTEGER          NULL,
-  ar_sha1        TEXT         NOT NULL DEFAULT '',
-  ar_comment     TEXT,
-  ar_user        INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
-  ar_user_text   TEXT         NOT NULL,
-  ar_timestamp   TIMESTAMPTZ  NOT NULL,
-  ar_minor_edit  SMALLINT     NOT NULL  DEFAULT 0,
-  ar_flags       TEXT,
-  ar_rev_id      INTEGER,
-  ar_text_id     INTEGER,
-  ar_deleted     SMALLINT     NOT NULL  DEFAULT 0,
-  ar_len         INTEGER          NULL
+  ar_namespace      SMALLINT     NOT NULL,
+  ar_title          TEXT         NOT NULL,
+  ar_text           TEXT, -- technically should be bytea, but not used anymore
+  ar_page_id        INTEGER          NULL,
+  ar_parent_id      INTEGER          NULL,
+  ar_sha1           TEXT         NOT NULL DEFAULT '',
+  ar_comment        TEXT,
+  ar_user           INTEGER          NULL  REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
+  ar_user_text      TEXT         NOT NULL,
+  ar_timestamp      TIMESTAMPTZ  NOT NULL,
+  ar_minor_edit     SMALLINT     NOT NULL  DEFAULT 0,
+  ar_flags          TEXT,
+  ar_rev_id         INTEGER,
+  ar_text_id        INTEGER,
+  ar_deleted        SMALLINT     NOT NULL  DEFAULT 0,
+  ar_len            INTEGER          NULL,
+  ar_content_model  TEXT,
+  ar_content_format TEXT
 );
 CREATE INDEX archive_name_title_timestamp ON archive (ar_namespace,ar_title,ar_timestamp);
 CREATE INDEX archive_user_text            ON archive (ar_user_text);
diff --git a/maintenance/sqlite/archives/patch-sites.sql b/maintenance/sqlite/archives/patch-sites.sql
new file mode 100644 (file)
index 0000000..8839274
--- /dev/null
@@ -0,0 +1,71 @@
+-- Patch to add the sites and site_identifiers tables.
+-- Licence: GNU GPL v2+
+-- Author: Jeroen De Dauw < jeroendedauw@gmail.com >
+
+
+-- Holds all the sites known to the wiki.
+CREATE TABLE IF NOT EXISTS /*_*/sites (
+-- Numeric id of the site
+  site_id                    INT UNSIGNED        NOT NULL PRIMARY KEY AUTO_INCREMENT,
+
+  -- Global identifier for the site, ie 'enwiktionary'
+  site_global_key            varbinary(32)       NOT NULL,
+
+  -- Type of the site, ie 'mediawiki'
+  site_type                  varbinary(32)       NOT NULL,
+
+  -- Group of the site, ie 'wikipedia'
+  site_group                 varbinary(32)       NOT NULL,
+
+  -- Source of the site data, ie 'local', 'wikidata', 'my-magical-repo'
+  site_source                varbinary(32)       NOT NULL,
+
+  -- Language code of the sites primary language.
+  site_language              varbinary(32)       NOT NULL,
+
+  -- Protocol of the site, ie 'http://', 'irc://', '//'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_protocol              varbinary(32)       NOT NULL,
+
+  -- Domain of the site in reverse order, ie 'org.mediawiki.www.'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_domain                VARCHAR(255)        NOT NULL,
+
+  -- Type dependent site data.
+  site_data                  BLOB                NOT NULL,
+
+  -- If site.tld/path/key:pageTitle should forward users to  the page on
+  -- the actual site, where "key" is the local identifier.
+  site_forward              bool                NOT NULL,
+
+  -- Type dependent site config.
+  -- For instance if template transclusion should be allowed if it's a MediaWiki.
+  site_config               BLOB                NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE UNIQUE INDEX /*i*/sites_global_key ON /*_*/sites (site_global_key);
+CREATE INDEX /*i*/sites_type ON /*_*/sites (site_type);
+CREATE INDEX /*i*/sites_group ON /*_*/sites (site_group);
+CREATE INDEX /*i*/sites_source ON /*_*/sites (site_source);
+CREATE INDEX /*i*/sites_language ON /*_*/sites (site_language);
+CREATE INDEX /*i*/sites_protocol ON /*_*/sites (site_protocol);
+CREATE INDEX /*i*/sites_domain ON /*_*/sites (site_domain);
+CREATE INDEX /*i*/sites_forward ON /*_*/sites (site_forward);
+
+
+
+-- Links local site identifiers to their corresponding site.
+CREATE TABLE IF NOT EXISTS /*_*/site_identifiers (
+  -- Key on site.site_id
+  si_site                    INT UNSIGNED        NOT NULL,
+
+  -- local key type, ie 'interwiki' or 'langlink'
+  si_type                    varbinary(32)       NOT NULL,
+
+  -- local key value, ie 'en' or 'wiktionary'
+  si_key                     varbinary(32)       NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE UNIQUE INDEX /*i*/site_ids_type ON /*_*/site_identifiers (si_type, si_key);
+CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site);
+CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key);
\ No newline at end of file
index 4a707fd..a06c21c 100644 (file)
@@ -263,7 +263,7 @@ CREATE TABLE /*_*/page (
   page_len int unsigned NOT NULL,
 
   -- content model, see CONTENT_MODEL_XXX constants
-  page_content_model  int unsigned  default NULL
+  page_content_model varbinary(32) DEFAULT NULL
 ) /*$wgDBTableOptions*/;
 
 CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title);
@@ -322,10 +322,10 @@ CREATE TABLE /*_*/revision (
   rev_sha1 varbinary(32) NOT NULL default '',
 
   -- content model, see CONTENT_MODEL_XXX constants
-  rev_content_model  int unsigned  default NULL,
+  rev_content_model varbinary(32) DEFAULT NULL,
 
   -- content format, see CONTENT_FORMAT_XXX constants
-  rev_content_format int unsigned  default NULL
+  rev_content_format varbinary(64) DEFAULT NULL
 
 ) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
 -- In case tables are created as MyISAM, use row hints for MySQL <5.0 to avoid 4GB limit
@@ -439,10 +439,10 @@ CREATE TABLE /*_*/archive (
   ar_sha1 varbinary(32) NOT NULL default '',
 
   -- content model, see CONTENT_MODEL_XXX constants
-  ar_content_model  int unsigned default NULL,
+  ar_content_model varbinary(32) DEFAULT NULL,
 
   -- content format, see CONTENT_FORMAT_XXX constants
-  ar_content_format int unsigned default NULL
+  ar_content_format varbinary(64) DEFAULT NULL
 
 ) /*$wgDBTableOptions*/;
 
@@ -945,7 +945,10 @@ CREATE TABLE /*_*/filearchive (
   fa_timestamp binary(14) default '',
 
   -- Visibility of deleted revisions, bitfield
-  fa_deleted tinyint unsigned NOT NULL default 0
+  fa_deleted tinyint unsigned NOT NULL default 0,
+
+  -- sha1 hash of file content
+  fa_sha1 varbinary(32) NOT NULL default ''
 ) /*$wgDBTableOptions*/;
 
 -- pick out by image name
@@ -956,6 +959,8 @@ CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_sto
 CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
 -- sort by uploader
 CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
+-- find file by sha1, 10 bytes will be enough for hashes to be indexed
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
 
 
 --
@@ -1498,4 +1503,69 @@ CREATE TABLE /*_*/config (
 -- Should cover *most* configuration - strings, ints, bools, etc.
 CREATE INDEX /*i*/cf_name_value ON /*_*/config (cf_name,cf_value(255));
 
+-- Holds all the sites known to the wiki.
+CREATE TABLE /*_*/sites (
+-- Numeric id of the site
+  site_id                    INT UNSIGNED        NOT NULL PRIMARY KEY AUTO_INCREMENT,
+
+  -- Global identifier for the site, ie 'enwiktionary'
+  site_global_key            varbinary(32)       NOT NULL,
+
+  -- Type of the site, ie 'mediawiki'
+  site_type                  varbinary(32)       NOT NULL,
+
+  -- Group of the site, ie 'wikipedia'
+  site_group                 varbinary(32)       NOT NULL,
+
+  -- Source of the site data, ie 'local', 'wikidata', 'my-magical-repo'
+  site_source                varbinary(32)       NOT NULL,
+
+  -- Language code of the sites primary language.
+  site_language              varbinary(32)       NOT NULL,
+
+  -- Protocol of the site, ie 'http://', 'irc://', '//'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_protocol              varbinary(32)       NOT NULL,
+
+  -- Domain of the site in reverse order, ie 'org.mediawiki.www.'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_domain                VARCHAR(255)        NOT NULL,
+
+  -- Type dependent site data.
+  site_data                  BLOB                NOT NULL,
+
+  -- If site.tld/path/key:pageTitle should forward users to  the page on
+  -- the actual site, where "key" is the local identifier.
+  site_forward              bool                NOT NULL,
+
+  -- Type dependent site config.
+  -- For instance if template transclusion should be allowed if it's a MediaWiki.
+  site_config               BLOB                NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE UNIQUE INDEX /*i*/sites_global_key ON /*_*/sites (site_global_key);
+CREATE INDEX /*i*/sites_type ON /*_*/sites (site_type);
+CREATE INDEX /*i*/sites_group ON /*_*/sites (site_group);
+CREATE INDEX /*i*/sites_source ON /*_*/sites (site_source);
+CREATE INDEX /*i*/sites_language ON /*_*/sites (site_language);
+CREATE INDEX /*i*/sites_protocol ON /*_*/sites (site_protocol);
+CREATE INDEX /*i*/sites_domain ON /*_*/sites (site_domain);
+CREATE INDEX /*i*/sites_forward ON /*_*/sites (site_forward);
+
+-- Links local site identifiers to their corresponding site.
+CREATE TABLE /*_*/site_identifiers (
+  -- Key on site.site_id
+  si_site                    INT UNSIGNED        NOT NULL,
+
+  -- local key type, ie 'interwiki' or 'langlink'
+  si_type                    varbinary(32)       NOT NULL,
+
+  -- local key value, ie 'en' or 'wiktionary'
+  si_key                     varbinary(32)       NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE UNIQUE INDEX /*i*/site_ids_type ON /*_*/site_identifiers (si_type, si_key);
+CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site);
+CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key);
+
 -- vim: sw=2 sts=2 et
index 877f136..e3c993b 100644 (file)
@@ -126,12 +126,18 @@ class UpdateMediaWiki extends Maintenance {
                $updater->doUpdates( $updates );
 
                foreach( $updater->getPostDatabaseUpdateMaintenance() as $maint ) {
-                       if ( $updater->updateRowExists( $maint ) ) {
+                       $child = $this->runChild( $maint );
+
+                       // LoggedUpdateMaintenance is checking the updatelog itself
+                       $isLoggedUpdate = ( $child instanceof LoggedUpdateMaintenance );
+
+                       if ( !$isLoggedUpdate && $updater->updateRowExists( $maint ) ) {
                                continue;
                        }
-                       $child = $this->runChild( $maint );
                        $child->execute();
-                       $updater->insertUpdateRow( $maint );
+                       if ( !$isLoggedUpdate ) {
+                               $updater->insertUpdateRow( $maint );
+                       }
                }
 
                $this->output( "\nDone.\n" );
index 16d09ea..58bd351 100644 (file)
@@ -21,4 +21,4 @@
  * @file
  */
 
-require './opensearch_desc.php'; 
+require './opensearch_desc.php';
index cccc645..c906143 100644 (file)
@@ -178,6 +178,9 @@ return array(
        'jquery.getAttrs' => array(
                'scripts' => 'resources/jquery/jquery.getAttrs.js',
        ),
+       'jquery.hidpi' => array(
+               'scripts' => 'resources/jquery/jquery.hidpi.js',
+       ),
        'jquery.highlightText' => array(
                'scripts' => 'resources/jquery/jquery.highlightText.js',
                'dependencies' => 'jquery.mwExtension',
@@ -621,6 +624,12 @@ return array(
                        'feedback-bugnew',
                ),
        ),
+       'mediawiki.hidpi' => array(
+               'scripts' => 'resources/mediawiki/mediawiki.hidpi.js',
+               'dependencies' => array(
+                       'jquery.hidpi',
+               ),
+       ),
        'mediawiki.htmlform' => array(
                'scripts' => 'resources/mediawiki/mediawiki.htmlform.js',
        ),
index 1e99769..ac25bbd 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Blind 1.8.23
+ * jQuery UI Effects Blind 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 7927a4a..1169d77 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Bounce 1.8.23
+ * jQuery UI Effects Bounce 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index d8b8218..edd51a6 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Clip 1.8.23
+ * jQuery UI Effects Clip 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 91ac575..7fd946f 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects 1.8.23
+ * jQuery UI Effects 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -307,7 +307,7 @@ $.fn.extend({
 /******************************************************************************/
 
 $.extend($.effects, {
-       version: "1.8.23",
+       version: "1.8.24",
 
        // Saves a set of properties in a data storage
        save: function(element, set) {
index 6d25bd3..97e5abd 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Drop 1.8.23
+ * jQuery UI Effects Drop 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 1caeca8..f63e47a 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Explode 1.8.23
+ * jQuery UI Effects Explode 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 6124979..7aa37b1 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Fade 1.8.23
+ * jQuery UI Effects Fade 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 81b15b8..06cc553 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Fold 1.8.23
+ * jQuery UI Effects Fold 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index dee0639..ad9e7bd 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Highlight 1.8.23
+ * jQuery UI Effects Highlight 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 45cdc88..d730bee 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Pulsate 1.8.23
+ * jQuery UI Effects Pulsate 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 44ecee1..52d1871 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Scale 1.8.23
+ * jQuery UI Effects Scale 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index bc1fd19..44b8ea4 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Shake 1.8.23
+ * jQuery UI Effects Shake 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 0a43027..502e6c9 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Slide 1.8.23
+ * jQuery UI Effects Slide 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 64f2a17..4ee4ae8 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Effects Transfer 1.8.23
+ * jQuery UI Effects Transfer 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 6c4883f..83f2825 100644 (file)
@@ -8,8 +8,8 @@ jQuery(function($){
                currentText: '今天',
                monthNames: ['一月','二月','三月','四月','五月','六月',
                '七月','八月','九月','十月','十一月','十二月'],
-               monthNamesShort: ['一','二','三','四','五','六',
-               '七','八','九','十','十一','十二'],
+               monthNamesShort: ['一月','二月','三月','四月','五月','六月',
+               '七月','八月','九月','十月','十一月','十二月'],
                dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
                dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
                dayNamesMin: ['日','一','二','三','四','五','六'],
index 06c4c62..11189d3 100644 (file)
@@ -8,8 +8,8 @@ jQuery(function($){
                currentText: '今天',
                monthNames: ['一月','二月','三月','四月','五月','六月',
                '七月','八月','九月','十月','十一月','十二月'],
-               monthNamesShort: ['一','二','三','四','五','六',
-               '七','八','九','十','十一','十二'],
+               monthNamesShort: ['一月','二月','三月','四月','五月','六月',
+               '七月','八月','九月','十月','十一月','十二月'],
                dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
                dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
                dayNamesMin: ['日','一','二','三','四','五','六'],
index dd51e35..089498b 100644 (file)
@@ -8,8 +8,8 @@ jQuery(function($){
                currentText: '今天',
                monthNames: ['一月','二月','三月','四月','五月','六月',
                '七月','八月','九月','十月','十一月','十二月'],
-               monthNamesShort: ['一','二','三','四','五','六',
-               '七','八','九','十','十一','十二'],
+               monthNamesShort: ['一月','二月','三月','四月','五月','六月',
+               '七月','八月','九月','十月','十一月','十二月'],
                dayNames: ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'],
                dayNamesShort: ['周日','周一','周二','周三','周四','周五','周六'],
                dayNamesMin: ['日','一','二','三','四','五','六'],
index b3340e0..dc1ba60 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Accordion 1.8.23
+ * jQuery UI Accordion 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -518,7 +518,7 @@ $.widget( "ui.accordion", {
 });
 
 $.extend( $.ui.accordion, {
-       version: "1.8.23",
+       version: "1.8.24",
        animations: {
                slide: function( options, additions ) {
                        options = $.extend({
index b634cce..8d69be2 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Autocomplete 1.8.23
+ * jQuery UI Autocomplete 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index db2637e..8326262 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Button 1.8.23
+ * jQuery UI Button 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 1285a6d..b36c1ac 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI 1.8.23
+ * jQuery UI 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -18,7 +18,7 @@ if ( $.ui.version ) {
 }
 
 $.extend( $.ui, {
-       version: "1.8.23",
+       version: "1.8.24",
 
        keyCode: {
                ALT: 18,
index 7ea5b07..1fcea12 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Datepicker 1.8.23
+ * jQuery UI Datepicker 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -12,7 +12,7 @@
  */
 (function( $, undefined ) {
 
-$.extend($.ui, { datepicker: { version: "1.8.23" } });
+$.extend($.ui, { datepicker: { version: "1.8.24" } });
 
 var PROP_NAME = 'datepicker';
 var dpuuid = new Date().getTime();
@@ -1845,7 +1845,7 @@ $.fn.datepicker = function(options){
 $.datepicker = new Datepicker(); // singleton instance
 $.datepicker.initialized = false;
 $.datepicker.uuid = new Date().getTime();
-$.datepicker.version = "1.8.23";
+$.datepicker.version = "1.8.24";
 
 // Workaround for #4055
 // Add another global to avoid noConflict issues with inline event handlers
index 082bf2c..06b85f2 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Dialog 1.8.23
+ * jQuery UI Dialog 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -690,7 +690,7 @@ $.widget("ui.dialog", {
 });
 
 $.extend($.ui.dialog, {
-       version: "1.8.23",
+       version: "1.8.24",
 
        uuid: 0,
        maxZ: 0,
index 6da1aaf..149035c 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Draggable 1.8.23
+ * jQuery UI Draggable 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -237,11 +237,10 @@ $.widget("ui.draggable", $.ui.mouse, {
        },
        
        _mouseUp: function(event) {
-               if (this.options.iframeFix === true) {
-                       $("div.ui-draggable-iframeFix").each(function() { 
-                               this.parentNode.removeChild(this); 
-                       }); //Remove frame helpers
-               }
+               //Remove frame helpers
+               $("div.ui-draggable-iframeFix").each(function() { 
+                       this.parentNode.removeChild(this); 
+               });
                
                //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
                if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event);
@@ -513,7 +512,7 @@ $.widget("ui.draggable", $.ui.mouse, {
 });
 
 $.extend($.ui.draggable, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 $.ui.plugin.add("draggable", "connectToSortable", {
index 4b98b3a..f17c222 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Droppable 1.8.23
+ * jQuery UI Droppable 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -147,7 +147,7 @@ $.widget("ui.droppable", {
 });
 
 $.extend($.ui.droppable, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 $.ui.intersect = function(draggable, droppable, toleranceMode) {
@@ -260,7 +260,12 @@ $.ui.ddmanager = {
 
                        var parentInstance;
                        if (this.options.greedy) {
-                               var parent = this.element.parents(':data(droppable):eq(0)');
+                               // find droppable parents with same scope
+                               var scope = this.options.scope;
+                               var parent = this.element.parents(':data(droppable)').filter(function () {
+                                       return $.data(this, 'droppable').options.scope === scope;
+                               });
+
                                if (parent.length) {
                                        parentInstance = $.data(parent[0], 'droppable');
                                        parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
index e051055..52a1786 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Mouse 1.8.23
+ * jQuery UI Mouse 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 03f2606..8b20179 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Position 1.8.23
+ * jQuery UI Position 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index c1d9f3c..7cea1ba 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Progressbar 1.8.23
+ * jQuery UI Progressbar 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -103,7 +103,7 @@ $.widget( "ui.progressbar", {
 });
 
 $.extend( $.ui.progressbar, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 })( jQuery );
index f6ce694..6cc6f41 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Resizable 1.8.23
+ * jQuery UI Resizable 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -540,7 +540,7 @@ $.widget("ui.resizable", $.ui.mouse, {
 });
 
 $.extend($.ui.resizable, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 /*
index ac5bf04..44c6e8c 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Selectable 1.8.23
+ * jQuery UI Selectable 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -261,7 +261,7 @@ $.widget("ui.selectable", $.ui.mouse, {
 });
 
 $.extend($.ui.selectable, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 })(jQuery);
index 5ea589e..c554e78 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Slider 1.8.23
+ * jQuery UI Slider 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -656,7 +656,7 @@ $.widget( "ui.slider", $.ui.mouse, {
 });
 
 $.extend( $.ui.slider, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 }(jQuery));
index 1d87f65..9e0cac6 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Sortable 1.8.23
+ * jQuery UI Sortable 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -296,7 +296,16 @@ $.widget("ui.sortable", $.ui.mouse, {
                        var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
                        if (!intersection) continue;
 
-                       if(itemElement != this.currentItem[0] //cannot intersect with itself
+                       // Only put the placeholder inside the current Container, skip all
+                       // items form other containers. This works because when moving
+                       // an item from one container to another the
+                       // currentContainer is switched before the placeholder is moved.
+                       //
+                       // Without this moving items in "sub-sortables" can cause the placeholder to jitter
+                       // beetween the outer and inner container.
+                       if (item.instance !== this.currentContainer) continue;
+
+                       if (itemElement != this.currentItem[0] //cannot intersect with itself
                                &&      this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
                                &&      !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
                                && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true)
@@ -1003,15 +1012,16 @@ $.widget("ui.sortable", $.ui.mouse, {
 
                if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
                if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
-               if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element
-                       if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
-                       for (var i = this.containers.length - 1; i >= 0; i--){
-                               if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) {
-                                       delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.containers[i]));
-                                       delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.containers[i]));
-                               }
-                       };
-               };
+
+               // Check if the items Container has Changed and trigger appropriate
+               // events.
+               if (this !== this.currentContainer) {
+                       if(!noPropagation) {
+                               delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
+                               delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
+                       }
+               }
 
                //Post events to containers
                for (var i = this.containers.length - 1; i >= 0; i--){
@@ -1078,7 +1088,7 @@ $.widget("ui.sortable", $.ui.mouse, {
 });
 
 $.extend($.ui.sortable, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 })(jQuery);
index de453cc..0c47f0e 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Tabs 1.8.23
+ * jQuery UI Tabs 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -698,7 +698,7 @@ $.widget( "ui.tabs", {
 });
 
 $.extend( $.ui.tabs, {
-       version: "1.8.23"
+       version: "1.8.24"
 });
 
 /*
index befdcc2..66ef013 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Widget 1.8.23
+ * jQuery UI Widget 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 1ce7d5e..cd8f971 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Accordion 1.8.23
+ * jQuery UI Accordion 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index a9817ce..c7eaff2 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Autocomplete 1.8.23
+ * jQuery UI Autocomplete 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
@@ -13,7 +13,7 @@
 * html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */
 
 /*
- * jQuery UI Menu 1.8.23
+ * jQuery UI Menu 1.8.24
  *
  * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index c1f2600..0dc9857 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Button 1.8.23
+ * jQuery UI Button 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index c24627e..8b953a2 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI CSS Framework 1.8.23
+ * jQuery UI CSS Framework 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 0282eee..37d3a98 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Datepicker 1.8.23
+ * jQuery UI Datepicker 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index ba50ba5..04515f4 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Dialog 1.8.23
+ * jQuery UI Dialog 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index c775a33..90bf308 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Progressbar 1.8.23
+ * jQuery UI Progressbar 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 420c4af..d17873e 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Resizable 1.8.23
+ * jQuery UI Resizable 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 3320274..9850ee7 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Selectable 1.8.23
+ * jQuery UI Selectable 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 650ad7e..fbfe665 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Slider 1.8.23
+ * jQuery UI Slider 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 64ac9bf..f0bee7a 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI Tabs 1.8.23
+ * jQuery UI Tabs 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
index 536c8e0..b7d2f61 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery UI CSS Framework 1.8.23
+ * jQuery UI CSS Framework 1.8.24
  *
  * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about)
  * Dual licensed under the MIT or GPL Version 2 licenses.
diff --git a/resources/jquery/jquery.hidpi.js b/resources/jquery/jquery.hidpi.js
new file mode 100644 (file)
index 0000000..b7335ff
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * Responsive images based on 'srcset' and 'window.devicePixelRatio' emulation where needed.
+ *
+ * Call $().hidpi() on a document or part of a document to replace image srcs in that section.
+ *
+ * $.devicePixelRatio() can be used to supplement window.devicePixelRatio with support on
+ * some additional browsers.
+ */
+( function ( $ ) {
+
+/**
+ * Detect reported or approximate device pixel ratio.
+ * 1.0 means 1 CSS pixel is 1 hardware pixel
+ * 2.0 means 1 CSS pixel is 2 hardware pixels
+ * etc
+ *
+ * Uses window.devicePixelRatio if available, or CSS media queries on IE.
+ *
+ * @method
+ * @returns {number} Device pixel ratio
+ */
+$.devicePixelRatio = function () {
+       if ( window.devicePixelRatio !== undefined ) {
+               // Most web browsers:
+               // * WebKit (Safari, Chrome, Android browser, etc)
+               // * Opera
+               // * Firefox 18+
+               return window.devicePixelRatio;
+       } else if ( window.msMatchMedia !== undefined ) {
+               // Windows 8 desktops / tablets, probably Windows Phone 8
+               //
+               // IE 10 doesn't report pixel ratio directly, but we can get the
+               // screen DPI and divide by 96. We'll bracket to [1, 1.5, 2.0] for
+               // simplicity, but you may get different values depending on zoom
+               // factor, size of screen and orientation in Metro IE.
+               if ( window.msMatchMedia( '(min-resolution: 192dpi)' ).matches ) {
+                       return 2;
+               } else if ( window.msMatchMedia( '(min-resolution: 144dpi)' ).matches ) {
+                       return 1.5;
+               } else {
+                       return 1;
+               }
+       } else {
+               // Legacy browsers...
+               // Assume 1 if unknown.
+               return 1;
+       }
+};
+
+/**
+ * Implement responsive images based on srcset attributes, if browser has no
+ * native srcset support.
+ *
+ * @method
+ * @returns {jQuery} This selection
+ */
+$.fn.hidpi = function () {
+       var $target = this,
+               // @todo add support for dpi media query checks on Firefox, IE
+               devicePixelRatio = $.devicePixelRatio(),
+               testImage = new Image();
+
+       if ( devicePixelRatio > 1 && testImage.srcset === undefined ) {
+               // No native srcset support.
+               $target.find( 'img' ).each( function () {
+                       var $img = $( this ),
+                               srcset = $img.attr( 'srcset' ),
+                               match;
+                       if ( typeof srcset === 'string' && srcset !== '' ) {
+                               match = $.matchSrcSet( devicePixelRatio, srcset );
+                               if (match !== null ) {
+                                       $img.attr( 'src', match );
+                               }
+                       }
+               });
+       }
+
+       return $target;
+};
+
+/**
+ * Match a srcset entry for the given device pixel ratio
+ *
+ * @param {number} devicePixelRatio
+ * @param {string} srcset
+ * @return {mixed} null or the matching src string
+ *
+ * Exposed for testing.
+ */
+$.matchSrcSet = function ( devicePixelRatio, srcset ) {
+       var candidates,
+               candidate,
+               bits,
+               src,
+               i,
+               ratioStr,
+               ratio,
+               selectedRatio = 1,
+               selectedSrc = null;
+       candidates = srcset.split( / *, */ );
+       for ( i = 0; i < candidates.length; i++ ) {
+               candidate = candidates[i];
+               bits = candidate.split( / +/ );
+               src = bits[0];
+               if ( bits.length > 1 && bits[1].charAt( bits[1].length - 1 ) === 'x' ) {
+                       ratioStr = bits[1].substr( 0, bits[1].length - 1 );
+                       ratio = parseFloat( ratioStr );
+                       if ( ratio > devicePixelRatio ) {
+                               // Too big, skip!
+                       } else if ( ratio > selectedRatio ) {
+                               selectedRatio = ratio;
+                               selectedSrc = src;
+                       }
+               }
+       }
+       return selectedSrc;
+};
+
+}( jQuery ) );
index 973ef3d..d4f3bb3 100644 (file)
@@ -1,5 +1,5 @@
 /*!
- * jQuery JavaScript Library v1.8.1
+ * jQuery JavaScript Library v1.8.2
  * http://jquery.com/
  *
  * Includes Sizzle.js
@@ -9,7 +9,7 @@
  * Released under the MIT license
  * http://jquery.org/license
  *
- * Date: Thu Aug 30 2012 17:17:22 GMT-0400 (Eastern Daylight Time)
+ * Date: Thu Sep 20 2012 21:13:05 GMT-0400 (Eastern Daylight Time)
  */
 (function( window, undefined ) {
 var
@@ -186,7 +186,7 @@ jQuery.fn = jQuery.prototype = {
        selector: "",
 
        // The current version of jQuery being used
-       jquery: "1.8.1",
+       jquery: "1.8.2",
 
        // The default length of a jQuery object is 0
        length: 0,
@@ -573,7 +573,7 @@ jQuery.extend({
        },
 
        nodeName: function( elem, name ) {
-               return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+               return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
        },
 
        // args is for internal usage only
@@ -630,7 +630,7 @@ jQuery.extend({
                function( text ) {
                        return text == null ?
                                "" :
-                               text.toString().replace( rtrim, "" );
+                               ( text + "" ).replace( rtrim, "" );
                },
 
        // results is for internal usage only
@@ -776,7 +776,7 @@ jQuery.extend({
                };
 
                // Set the guid of unique handler to the same of original handler, so it can be removed
-               proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+               proxy.guid = fn.guid = fn.guid || jQuery.guid++;
 
                return proxy;
        },
@@ -1143,7 +1143,7 @@ jQuery.extend({
                                // Get a promise for this deferred
                                // If obj is provided, the promise aspect is added to the object
                                promise: function( obj ) {
-                                       return typeof obj === "object" ? jQuery.extend( obj, promise ) : promise;
+                                       return obj != null ? jQuery.extend( obj, promise ) : promise;
                                }
                        },
                        deferred = {};
@@ -1262,7 +1262,7 @@ jQuery.support = (function() {
        a.style.cssText = "top:1px;float:left;opacity:.5";
 
        // Can't get basic test support
-       if ( !all || !all.length || !a ) {
+       if ( !all || !all.length ) {
                return {};
        }
 
@@ -1513,7 +1513,7 @@ jQuery.extend({
 
        deletedIds: [],
 
-       // Please use with caution
+       // Remove at next major release (1.9/2.0)
        uuid: 0,
 
        // Unique for each copy of jQuery on the page
@@ -1565,7 +1565,7 @@ jQuery.extend({
                        // Only DOM nodes need a new unique ID for each element since their data
                        // ends up in the global cache
                        if ( isNode ) {
-                               elem[ internalKey ] = id = jQuery.deletedIds.pop() || ++jQuery.uuid;
+                               elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++;
                        } else {
                                id = internalKey;
                        }
@@ -1739,7 +1739,7 @@ jQuery.fn.extend({
                                        for ( l = attr.length; i < l; i++ ) {
                                                name = attr[i].name;
 
-                                               if ( name.indexOf( "data-" ) === 0 ) {
+                                               if ( !name.indexOf( "data-" ) ) {
                                                        name = jQuery.camelCase( name.substring(5) );
 
                                                        dataAttr( elem, name, data[ name ] );
@@ -2049,7 +2049,7 @@ jQuery.fn.extend({
                                                setClass = " " + elem.className + " ";
 
                                                for ( c = 0, cl = classNames.length; c < cl; c++ ) {
-                                                       if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
+                                                       if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) {
                                                                setClass += classNames[ c ] + " ";
                                                        }
                                                }
@@ -2082,7 +2082,7 @@ jQuery.fn.extend({
                                        // loop over each item in the removal list
                                        for ( c = 0, cl = removes.length; c < cl; c++ ) {
                                                // Remove until there is nothing to remove,
-                                               while ( className.indexOf(" " + removes[ c ] + " ") > -1 ) {
+                                               while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) {
                                                        className = className.replace( " " + removes[ c ] + " " , " " );
                                                }
                                        }
@@ -2136,7 +2136,7 @@ jQuery.fn.extend({
                        i = 0,
                        l = this.length;
                for ( ; i < l; i++ ) {
-                       if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+                       if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
                                return true;
                        }
                }
@@ -2314,7 +2314,7 @@ jQuery.extend({
                                return ret;
 
                        } else {
-                               elem.setAttribute( name, "" + value );
+                               elem.setAttribute( name, value + "" );
                                return value;
                        }
 
@@ -2578,7 +2578,7 @@ if ( !jQuery.support.style ) {
                        return elem.style.cssText.toLowerCase() || undefined;
                },
                set: function( elem, value ) {
-                       return ( elem.style.cssText = "" + value );
+                       return ( elem.style.cssText = value + "" );
                }
        };
 }
@@ -2711,6 +2711,7 @@ jQuery.event = {
                                handler: handler,
                                guid: handler.guid,
                                selector: selector,
+                               needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
                                namespace: namespaces.join(".")
                        }, handleObjIn );
 
@@ -2946,7 +2947,7 @@ jQuery.event = {
                        }
                        // Note that this is a bare JS function and not a jQuery handler
                        handle = ontype && cur[ ontype ];
-                       if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
+                       if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
                                event.preventDefault();
                        }
                }
@@ -2994,7 +2995,7 @@ jQuery.event = {
                var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related,
                        handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
                        delegateCount = handlers.delegateCount,
-                       args = [].slice.call( arguments ),
+                       args = core_slice.call( arguments ),
                        run_all = !event.exclusive && !event.namespace,
                        special = jQuery.event.special[ event.type ] || {},
                        handlerQueue = [];
@@ -3023,7 +3024,9 @@ jQuery.event = {
                                                sel = handleObj.selector;
 
                                                if ( selMatch[ sel ] === undefined ) {
-                                                       selMatch[ sel ] = jQuery( sel, this ).index( cur ) >= 0;
+                                                       selMatch[ sel ] = handleObj.needsContext ?
+                                                               jQuery( sel, this ).index( cur ) >= 0 :
+                                                               jQuery.find( sel, this, null, [ cur ] ).length;
                                                }
                                                if ( selMatch[ sel ] ) {
                                                        matches.push( handleObj );
@@ -3593,7 +3596,7 @@ jQuery.fn.extend({
        },
        undelegate: function( selector, types, fn ) {
                // ( namespace ) or ( selector, types [, fn] )
-               return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+               return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
        },
 
        trigger: function( type, data ) {
@@ -3664,14 +3667,13 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
 });
 /*!\r
  * Sizzle CSS Selector Engine\r
- *  Copyright 2012 jQuery Foundation and other contributors\r
- *  Released under the MIT license\r
- *  http://sizzlejs.com/\r
+ * Copyright 2012 jQuery Foundation and other contributors\r
+ * Released under the MIT license\r
+ * http://sizzlejs.com/\r
  */\r
 (function( window, undefined ) {\r
 \r
-var dirruns,\r
-       cachedruns,\r
+var cachedruns,\r
        assertGetIdNotName,\r
        Expr,\r
        getText,\r
@@ -3680,21 +3682,36 @@ var dirruns,
        compile,\r
        sortOrder,\r
        hasDuplicate,\r
+       outermostContext,\r
 \r
        baseHasDuplicate = true,\r
        strundefined = "undefined",\r
 \r
        expando = ( "sizcache" + Math.random() ).replace( ".", "" ),\r
 \r
+       Token = String,\r
        document = window.document,\r
        docElem = document.documentElement,\r
+       dirruns = 0,\r
        done = 0,\r
-       slice = [].slice,\r
+       pop = [].pop,\r
        push = [].push,\r
+       slice = [].slice,\r
+       // Use a stripped-down indexOf if a native one is unavailable\r
+       indexOf = [].indexOf || function( elem ) {\r
+               var i = 0,\r
+                       len = this.length;\r
+               for ( ; i < len; i++ ) {\r
+                       if ( this[i] === elem ) {\r
+                               return i;\r
+                       }\r
+               }\r
+               return -1;\r
+       },\r
 \r
        // Augment a function for special use by Sizzle\r
        markFunction = function( fn, value ) {\r
-               fn[ expando ] = value || true;\r
+               fn[ expando ] = value == null || value;\r
                return fn;\r
        },\r
 \r
@@ -3741,7 +3758,8 @@ var dirruns,
        pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)",\r
 \r
        // For matchExpr.POS and matchExpr.needsContext\r
-       pos = ":(nth|eq|gt|lt|first|last|even|odd)(?:\\(((?:-\\d)?\\d*)\\)|)(?=[^-]|$)",\r
+       pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +\r
+               "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)",\r
 \r
        // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\r
        rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),\r
@@ -3769,10 +3787,10 @@ var dirruns,
                "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),\r
                "ATTR": new RegExp( "^" + attributes ),\r
                "PSEUDO": new RegExp( "^" + pseudos ),\r
-               "CHILD": new RegExp( "^:(only|nth|last|first)-child(?:\\(" + whitespace +\r
+               "POS": new RegExp( pos, "i" ),\r
+               "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace +\r
                        "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +\r
                        "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),\r
-               "POS": new RegExp( pos, "ig" ),\r
                // For use in libraries implementing .is()\r
                "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" )\r
        },\r
@@ -3854,7 +3872,8 @@ try {
        slice.call( docElem.childNodes, 0 )[0].nodeType;\r
 } catch ( e ) {\r
        slice = function( i ) {\r
-               var elem, results = [];\r
+               var elem,\r
+                       results = [];\r
                for ( ; (elem = this[i]); i++ ) {\r
                        results.push( elem );\r
                }\r
@@ -3868,14 +3887,14 @@ function Sizzle( selector, context, results, seed ) {
        var match, elem, xml, m,\r
                nodeType = context.nodeType;\r
 \r
-       if ( nodeType !== 1 && nodeType !== 9 ) {\r
-               return [];\r
-       }\r
-\r
        if ( !selector || typeof selector !== "string" ) {\r
                return results;\r
        }\r
 \r
+       if ( nodeType !== 1 && nodeType !== 9 ) {\r
+               return [];\r
+       }\r
+\r
        xml = isXML( context );\r
 \r
        if ( !xml && !seed ) {\r
@@ -3919,7 +3938,7 @@ function Sizzle( selector, context, results, seed ) {
        }\r
 \r
        // All others\r
-       return select( selector, context, results, seed, xml );\r
+       return select( selector.replace( rtrim, "$1" ), context, results, seed, xml );\r
 }\r
 \r
 Sizzle.matches = function( expr, elements ) {\r
@@ -3946,6 +3965,25 @@ function createButtonPseudo( type ) {
        };\r
 }\r
 \r
+// Returns a function to use in pseudos for positionals\r
+function createPositionalPseudo( fn ) {\r
+       return markFunction(function( argument ) {\r
+               argument = +argument;\r
+               return markFunction(function( seed, matches ) {\r
+                       var j,\r
+                               matchIndexes = fn( [], seed.length, argument ),\r
+                               i = matchIndexes.length;\r
+\r
+                       // Match elements found at the specified indexes\r
+                       while ( i-- ) {\r
+                               if ( seed[ (j = matchIndexes[i]) ] ) {\r
+                                       seed[j] = !(matches[j] = seed[j]);\r
+                               }\r
+                       }\r
+               });\r
+       });\r
+}\r
+\r
 /**\r
  * Utility function for retrieving the text value of an array of DOM nodes\r
  * @param {Array|Element} elem\r
@@ -3983,7 +4021,7 @@ getText = Sizzle.getText = function( elem ) {
        return ret;\r
 };\r
 \r
-isXML = Sizzle.isXML = function isXML( elem ) {\r
+isXML = Sizzle.isXML = function( elem ) {\r
        // documentElement is verified for cases where it doesn't yet exist\r
        // (such as loading iframes in IE - #4833)\r
        var documentElement = elem && (elem.ownerDocument || elem).documentElement;\r
@@ -4011,23 +4049,23 @@ contains = Sizzle.contains = docElem.contains ?
        };\r
 \r
 Sizzle.attr = function( elem, name ) {\r
-       var attr,\r
+       var val,\r
                xml = isXML( elem );\r
 \r
        if ( !xml ) {\r
                name = name.toLowerCase();\r
        }\r
-       if ( Expr.attrHandle[ name ] ) {\r
-               return Expr.attrHandle[ name ]( elem );\r
+       if ( (val = Expr.attrHandle[ name ]) ) {\r
+               return val( elem );\r
        }\r
-       if ( assertAttributes || xml ) {\r
+       if ( xml || assertAttributes ) {\r
                return elem.getAttribute( name );\r
        }\r
-       attr = elem.getAttributeNode( name );\r
-       return attr ?\r
+       val = elem.getAttributeNode( name );\r
+       return val ?\r
                typeof elem[ name ] === "boolean" ?\r
                        elem[ name ] ? name : null :\r
-                       attr.specified ? attr.value : null :\r
+                       val.specified ? val.value : null :\r
                null;\r
 };\r
 \r
@@ -4040,11 +4078,6 @@ Expr = Sizzle.selectors = {
 \r
        match: matchExpr,\r
 \r
-       order: new RegExp( "ID|TAG" +\r
-               (assertUsableName ? "|NAME" : "") +\r
-               (assertUsableClassName ? "|CLASS" : "")\r
-       ),\r
-\r
        // IE6/7 return a modified href\r
        attrHandle: assertHrefNotNormalized ?\r
                {} :\r
@@ -4105,13 +4138,13 @@ Expr = Sizzle.selectors = {
                                return results;\r
                        },\r
 \r
-               "NAME": function( tag, context ) {\r
+               "NAME": assertUsableName && function( tag, context ) {\r
                        if ( typeof context.getElementsByName !== strundefined ) {\r
                                return context.getElementsByName( name );\r
                        }\r
                },\r
 \r
-               "CLASS": function( className, context, xml ) {\r
+               "CLASS": assertUsableClassName && function( className, context, xml ) {\r
                        if ( typeof context.getElementsByClassName !== strundefined && !xml ) {\r
                                return context.getElementsByClassName( className );\r
                        }\r
@@ -4140,7 +4173,7 @@ Expr = Sizzle.selectors = {
                },\r
 \r
                "CHILD": function( match ) {\r
-                       /* matches from matchExpr.CHILD\r
+                       /* matches from matchExpr["CHILD"]\r
                                1 type (only|nth|...)\r
                                2 argument (even|odd|\d*|\d*n([+-]\d+)?|...)\r
                                3 xn-component of xn+y argument ([+-]?\d*n|)\r
@@ -4170,7 +4203,7 @@ Expr = Sizzle.selectors = {
                        return match;\r
                },\r
 \r
-               "PSEUDO": function( match, context, xml ) {\r
+               "PSEUDO": function( match ) {\r
                        var unquoted, excess;\r
                        if ( matchExpr["CHILD"].test( match[0] ) ) {\r
                                return null;\r
@@ -4182,7 +4215,7 @@ Expr = Sizzle.selectors = {
                                // Only check arguments that contain a pseudo\r
                                if ( rpseudo.test(unquoted) &&\r
                                        // Get excess from tokenize (recursively)\r
-                                       (excess = tokenize( unquoted, context, xml, true )) &&\r
+                                       (excess = tokenize( unquoted, true )) &&\r
                                        // advance to the next closing parenthesis\r
                                        (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {\r
 \r
@@ -4236,76 +4269,55 @@ Expr = Sizzle.selectors = {
                },\r
 \r
                "ATTR": function( name, operator, check ) {\r
-                       if ( !operator ) {\r
-                               return function( elem ) {\r
-                                       return Sizzle.attr( elem, name ) != null;\r
-                               };\r
-                       }\r
-\r
-                       return function( elem ) {\r
-                               var result = Sizzle.attr( elem, name ),\r
-                                       value = result + "";\r
+                       return function( elem, context ) {\r
+                               var result = Sizzle.attr( elem, name );\r
 \r
                                if ( result == null ) {\r
                                        return operator === "!=";\r
                                }\r
-\r
-                               switch ( operator ) {\r
-                                       case "=":\r
-                                               return value === check;\r
-                                       case "!=":\r
-                                               return value !== check;\r
-                                       case "^=":\r
-                                               return check && value.indexOf( check ) === 0;\r
-                                       case "*=":\r
-                                               return check && value.indexOf( check ) > -1;\r
-                                       case "$=":\r
-                                               return check && value.substr( value.length - check.length ) === check;\r
-                                       case "~=":\r
-                                               return ( " " + value + " " ).indexOf( check ) > -1;\r
-                                       case "|=":\r
-                                               return value === check || value.substr( 0, check.length + 1 ) === check + "-";\r
+                               if ( !operator ) {\r
+                                       return true;\r
                                }\r
+\r
+                               result += "";\r
+\r
+                               return operator === "=" ? result === check :\r
+                                       operator === "!=" ? result !== check :\r
+                                       operator === "^=" ? check && result.indexOf( check ) === 0 :\r
+                                       operator === "*=" ? check && result.indexOf( check ) > -1 :\r
+                                       operator === "$=" ? check && result.substr( result.length - check.length ) === check :\r
+                                       operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :\r
+                                       operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" :\r
+                                       false;\r
                        };\r
                },\r
 \r
                "CHILD": function( type, argument, first, last ) {\r
 \r
                        if ( type === "nth" ) {\r
-                               var doneName = done++;\r
-\r
                                return function( elem ) {\r
-                                       var parent, diff,\r
-                                               count = 0,\r
-                                               node = elem;\r
+                                       var node, diff,\r
+                                               parent = elem.parentNode;\r
 \r
                                        if ( first === 1 && last === 0 ) {\r
                                                return true;\r
                                        }\r
 \r
-                                       parent = elem.parentNode;\r
-\r
-                                       if ( parent && (parent[ expando ] !== doneName || !elem.sizset) ) {\r
+                                       if ( parent ) {\r
+                                               diff = 0;\r
                                                for ( node = parent.firstChild; node; node = node.nextSibling ) {\r
                                                        if ( node.nodeType === 1 ) {\r
-                                                               node.sizset = ++count;\r
-                                                               if ( node === elem ) {\r
+                                                               diff++;\r
+                                                               if ( elem === node ) {\r
                                                                        break;\r
                                                                }\r
                                                        }\r
                                                }\r
-\r
-                                               parent[ expando ] = doneName;\r
                                        }\r
 \r
-                                       diff = elem.sizset - last;\r
-\r
-                                       if ( first === 0 ) {\r
-                                               return diff === 0;\r
-\r
-                                       } else {\r
-                                               return ( diff % first === 0 && diff / first >= 0 );\r
-                                       }\r
+                                       // Incorporate the offset (or cast to NaN), then check against cycle size\r
+                                       diff -= last;\r
+                                       return diff === first || ( diff % first === 0 && diff / first >= 0 );\r
                                };\r
                        }\r
 \r
@@ -4340,42 +4352,82 @@ Expr = Sizzle.selectors = {
                        };\r
                },\r
 \r
-               "PSEUDO": function( pseudo, argument, context, xml ) {\r
+               "PSEUDO": function( pseudo, argument ) {\r
                        // pseudo-class names are case-insensitive\r
                        // http://www.w3.org/TR/selectors/#pseudo-classes\r
                        // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\r
+                       // Remember that setFilters inherits from pseudos\r
                        var args,\r
-                               fn = Expr.pseudos[ pseudo ] || Expr.pseudos[ pseudo.toLowerCase() ];\r
-\r
-                       if ( !fn ) {\r
-                               Sizzle.error( "unsupported pseudo: " + pseudo );\r
-                       }\r
+                               fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\r
+                                       Sizzle.error( "unsupported pseudo: " + pseudo );\r
 \r
                        // The user may use createPseudo to indicate that\r
                        // arguments are needed to create the filter function\r
                        // just as Sizzle does\r
-                       if ( !fn[ expando ] ) {\r
-                               if ( fn.length > 1 ) {\r
-                                       args = [ pseudo, pseudo, "", argument ];\r
-                                       return function( elem ) {\r
+                       if ( fn[ expando ] ) {\r
+                               return fn( argument );\r
+                       }\r
+\r
+                       // But maintain support for old signatures\r
+                       if ( fn.length > 1 ) {\r
+                               args = [ pseudo, pseudo, "", argument ];\r
+                               return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\r
+                                       markFunction(function( seed, matches ) {\r
+                                               var idx,\r
+                                                       matched = fn( seed, argument ),\r
+                                                       i = matched.length;\r
+                                               while ( i-- ) {\r
+                                                       idx = indexOf.call( seed, matched[i] );\r
+                                                       seed[ idx ] = !( matches[ idx ] = matched[i] );\r
+                                               }\r
+                                       }) :\r
+                                       function( elem ) {\r
                                                return fn( elem, 0, args );\r
                                        };\r
-                               }\r
-                               return fn;\r
                        }\r
 \r
-                       return fn( argument, context, xml );\r
+                       return fn;\r
                }\r
        },\r
 \r
        pseudos: {\r
-               "not": markFunction(function( selector, context, xml ) {\r
+               "not": markFunction(function( selector ) {\r
                        // Trim the selector passed to compile\r
                        // to avoid treating leading and trailing\r
                        // spaces as combinators\r
-                       var matcher = compile( selector.replace( rtrim, "$1" ), context, xml );\r
+                       var input = [],\r
+                               results = [],\r
+                               matcher = compile( selector.replace( rtrim, "$1" ) );\r
+\r
+                       return matcher[ expando ] ?\r
+                               markFunction(function( seed, matches, context, xml ) {\r
+                                       var elem,\r
+                                               unmatched = matcher( seed, null, xml, [] ),\r
+                                               i = seed.length;\r
+\r
+                                       // Match elements unmatched by `matcher`\r
+                                       while ( i-- ) {\r
+                                               if ( (elem = unmatched[i]) ) {\r
+                                                       seed[i] = !(matches[i] = elem);\r
+                                               }\r
+                                       }\r
+                               }) :\r
+                               function( elem, context, xml ) {\r
+                                       input[0] = elem;\r
+                                       matcher( input, null, xml, results );\r
+                                       return !results.pop();\r
+                               };\r
+               }),\r
+\r
+               "has": markFunction(function( selector ) {\r
                        return function( elem ) {\r
-                               return !matcher( elem );\r
+                               return Sizzle( selector, elem ).length > 0;\r
+                       };\r
+               }),\r
+\r
+               "contains": markFunction(function( text ) {\r
+                       return function( elem ) {\r
+                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\r
                        };\r
                }),\r
 \r
@@ -4425,18 +4477,6 @@ Expr = Sizzle.selectors = {
                        return true;\r
                },\r
 \r
-               "contains": markFunction(function( text ) {\r
-                       return function( elem ) {\r
-                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\r
-                       };\r
-               }),\r
-\r
-               "has": markFunction(function( selector ) {\r
-                       return function( elem ) {\r
-                               return Sizzle( selector, elem ).length > 0;\r
-                       };\r
-               }),\r
-\r
                "header": function( elem ) {\r
                        return rheader.test( elem.nodeName );\r
                },\r
@@ -4476,51 +4516,48 @@ Expr = Sizzle.selectors = {
 \r
                "active": function( elem ) {\r
                        return elem === elem.ownerDocument.activeElement;\r
-               }\r
-       },\r
-\r
-       setFilters: {\r
-               "first": function( elements, argument, not ) {\r
-                       return not ? elements.slice( 1 ) : [ elements[0] ];\r
                },\r
 \r
-               "last": function( elements, argument, not ) {\r
-                       var elem = elements.pop();\r
-                       return not ? elements : [ elem ];\r
-               },\r
+               // Positional types\r
+               "first": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       return [ 0 ];\r
+               }),\r
 \r
-               "even": function( elements, argument, not ) {\r
-                       var results = [],\r
-                               i = not ? 1 : 0,\r
-                               len = elements.length;\r
-                       for ( ; i < len; i = i + 2 ) {\r
-                               results.push( elements[i] );\r
-                       }\r
-                       return results;\r
-               },\r
+               "last": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       return [ length - 1 ];\r
+               }),\r
 \r
-               "odd": function( elements, argument, not ) {\r
-                       var results = [],\r
-                               i = not ? 0 : 1,\r
-                               len = elements.length;\r
-                       for ( ; i < len; i = i + 2 ) {\r
-                               results.push( elements[i] );\r
+               "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       return [ argument < 0 ? argument + length : argument ];\r
+               }),\r
+\r
+               "even": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       for ( var i = 0; i < length; i += 2 ) {\r
+                               matchIndexes.push( i );\r
                        }\r
-                       return results;\r
-               },\r
+                       return matchIndexes;\r
+               }),\r
 \r
-               "lt": function( elements, argument, not ) {\r
-                       return not ? elements.slice( +argument ) : elements.slice( 0, +argument );\r
-               },\r
+               "odd": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       for ( var i = 1; i < length; i += 2 ) {\r
+                               matchIndexes.push( i );\r
+                       }\r
+                       return matchIndexes;\r
+               }),\r
 \r
-               "gt": function( elements, argument, not ) {\r
-                       return not ? elements.slice( 0, +argument + 1 ) : elements.slice( +argument + 1 );\r
-               },\r
+               "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) {\r
+                               matchIndexes.push( i );\r
+                       }\r
+                       return matchIndexes;\r
+               }),\r
 \r
-               "eq": function( elements, argument, not ) {\r
-                       var elem = elements.splice( +argument, 1 );\r
-                       return not ? elements : elem;\r
-               }\r
+               "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {\r
+                       for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) {\r
+                               matchIndexes.push( i );\r
+                       }\r
+                       return matchIndexes;\r
+               })\r
        }\r
 };\r
 \r
@@ -4642,24 +4679,17 @@ Sizzle.error = function( msg ) {
        throw new Error( "Syntax error, unrecognized expression: " + msg );\r
 };\r
 \r
-function tokenize( selector, context, xml, parseOnly ) {\r
-       var matched, match, tokens, type,\r
-               soFar, groups, group, i,\r
-               preFilters, filters,\r
-               checkContext = !xml && context !== document,\r
-               // Token cache should maintain spaces\r
-               key = ( checkContext ? "<s>" : "" ) + selector.replace( rtrim, "$1<s>" ),\r
-               cached = tokenCache[ expando ][ key ];\r
+function tokenize( selector, parseOnly ) {\r
+       var matched, match, tokens, type, soFar, groups, preFilters,\r
+               cached = tokenCache[ expando ][ selector ];\r
 \r
        if ( cached ) {\r
-               return parseOnly ? 0 : slice.call( cached, 0 );\r
+               return parseOnly ? 0 : cached.slice( 0 );\r
        }\r
 \r
        soFar = selector;\r
        groups = [];\r
-       i = 0;\r
        preFilters = Expr.preFilter;\r
-       filters = Expr.filter;\r
 \r
        while ( soFar ) {\r
 \r
@@ -4667,45 +4697,31 @@ function tokenize( selector, context, xml, parseOnly ) {
                if ( !matched || (match = rcomma.exec( soFar )) ) {\r
                        if ( match ) {\r
                                soFar = soFar.slice( match[0].length );\r
-                               tokens.selector = group;\r
                        }\r
                        groups.push( tokens = [] );\r
-                       group = "";\r
-\r
-                       // Need to make sure we're within a narrower context if necessary\r
-                       // Adding a descendant combinator will generate what is needed\r
-                       if ( checkContext ) {\r
-                               soFar = " " + soFar;\r
-                       }\r
                }\r
 \r
                matched = false;\r
 \r
                // Combinators\r
                if ( (match = rcombinators.exec( soFar )) ) {\r
-                       group += match[0];\r
-                       soFar = soFar.slice( match[0].length );\r
+                       tokens.push( matched = new Token( match.shift() ) );\r
+                       soFar = soFar.slice( matched.length );\r
 \r
                        // Cast descendant combinators to space\r
-                       matched = tokens.push({\r
-                               part: match.pop().replace( rtrim, " " ),\r
-                               string: match[0],\r
-                               captures: match\r
-                       });\r
+                       matched.type = match[0].replace( rtrim, " " );\r
                }\r
 \r
                // Filters\r
-               for ( type in filters ) {\r
+               for ( type in Expr.filter ) {\r
                        if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\r
-                               ( match = preFilters[ type ](match, context, xml) )) ) {\r
+                               // The last two arguments here are (context, xml) for backCompat\r
+                               (match = preFilters[ type ]( match, document, true ))) ) {\r
 \r
-                               group += match[0];\r
-                               soFar = soFar.slice( match[0].length );\r
-                               matched = tokens.push({\r
-                                       part: type,\r
-                                       string: match.shift(),\r
-                                       captures: match\r
-                               });\r
+                               tokens.push( matched = new Token( match.shift() ) );\r
+                               soFar = soFar.slice( matched.length );\r
+                               matched.type = type;\r
+                               matched.matches = match;\r
                        }\r
                }\r
 \r
@@ -4714,11 +4730,6 @@ function tokenize( selector, context, xml, parseOnly ) {
                }\r
        }\r
 \r
-       // Attach the full group as a selector\r
-       if ( group ) {\r
-               tokens.selector = group;\r
-       }\r
-\r
        // Return the length of the invalid excess\r
        // if we're just parsing\r
        // Otherwise, throw an error or return tokens\r
@@ -4727,43 +4738,33 @@ function tokenize( selector, context, xml, parseOnly ) {
                soFar ?\r
                        Sizzle.error( selector ) :\r
                        // Cache the tokens\r
-                       slice.call( tokenCache(key, groups), 0 );\r
+                       tokenCache( selector, groups ).slice( 0 );\r
 }\r
 \r
-function addCombinator( matcher, combinator, context, xml ) {\r
+function addCombinator( matcher, combinator, base ) {\r
        var dir = combinator.dir,\r
+               checkNonElements = base && combinator.dir === "parentNode",\r
                doneName = done++;\r
 \r
-       if ( !matcher ) {\r
-               // If there is no matcher to check, check against the context\r
-               matcher = function( elem ) {\r
-                       return elem === context;\r
-               };\r
-       }\r
        return combinator.first ?\r
-               function( elem ) {\r
+               // Check against closest ancestor/preceding element\r
+               function( elem, context, xml ) {\r
                        while ( (elem = elem[ dir ]) ) {\r
-                               if ( elem.nodeType === 1 ) {\r
-                                       return matcher( elem ) && elem;\r
+                               if ( checkNonElements || elem.nodeType === 1  ) {\r
+                                       return matcher( elem, context, xml );\r
                                }\r
                        }\r
                } :\r
-               xml ?\r
-                       function( elem ) {\r
-                               while ( (elem = elem[ dir ]) ) {\r
-                                       if ( elem.nodeType === 1 ) {\r
-                                               if ( matcher( elem ) ) {\r
-                                                       return elem;\r
-                                               }\r
-                                       }\r
-                               }\r
-                       } :\r
-                       function( elem ) {\r
+\r
+               // Check against all ancestor/preceding elements\r
+               function( elem, context, xml ) {\r
+                       // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\r
+                       if ( !xml ) {\r
                                var cache,\r
-                                       dirkey = doneName + "." + dirruns,\r
-                                       cachedkey = dirkey + "." + cachedruns;\r
+                                       dirkey = dirruns + " " + doneName + " ",\r
+                                       cachedkey = dirkey + cachedruns;\r
                                while ( (elem = elem[ dir ]) ) {\r
-                                       if ( elem.nodeType === 1 ) {\r
+                                       if ( checkNonElements || elem.nodeType === 1 ) {\r
                                                if ( (cache = elem[ expando ]) === cachedkey ) {\r
                                                        return elem.sizset;\r
                                                } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) {\r
@@ -4772,7 +4773,7 @@ function addCombinator( matcher, combinator, context, xml ) {
                                                        }\r
                                                } else {\r
                                                        elem[ expando ] = cachedkey;\r
-                                                       if ( matcher( elem ) ) {\r
+                                                       if ( matcher( elem, context, xml ) ) {\r
                                                                elem.sizset = true;\r
                                                                return elem;\r
                                                        }\r
@@ -4780,254 +4781,382 @@ function addCombinator( matcher, combinator, context, xml ) {
                                                }\r
                                        }\r
                                }\r
-                       };\r
+                       } else {\r
+                               while ( (elem = elem[ dir ]) ) {\r
+                                       if ( checkNonElements || elem.nodeType === 1 ) {\r
+                                               if ( matcher( elem, context, xml ) ) {\r
+                                                       return elem;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
 }\r
 \r
-function addMatcher( higher, deeper ) {\r
-       return higher ?\r
-               function( elem ) {\r
-                       var result = deeper( elem );\r
-                       return result && higher( result === true ? elem : result );\r
+function elementMatcher( matchers ) {\r
+       return matchers.length > 1 ?\r
+               function( elem, context, xml ) {\r
+                       var i = matchers.length;\r
+                       while ( i-- ) {\r
+                               if ( !matchers[i]( elem, context, xml ) ) {\r
+                                       return false;\r
+                               }\r
+                       }\r
+                       return true;\r
                } :\r
-               deeper;\r
+               matchers[0];\r
 }\r
 \r
-// ["TAG", ">", "ID", " ", "CLASS"]\r
-function matcherFromTokens( tokens, context, xml ) {\r
-       var token, matcher,\r
-               i = 0;\r
+function condense( unmatched, map, filter, context, xml ) {\r
+       var elem,\r
+               newUnmatched = [],\r
+               i = 0,\r
+               len = unmatched.length,\r
+               mapped = map != null;\r
 \r
-       for ( ; (token = tokens[i]); i++ ) {\r
-               if ( Expr.relative[ token.part ] ) {\r
-                       matcher = addCombinator( matcher, Expr.relative[ token.part ], context, xml );\r
-               } else {\r
-                       matcher = addMatcher( matcher, Expr.filter[ token.part ].apply(null, token.captures.concat( context, xml )) );\r
+       for ( ; i < len; i++ ) {\r
+               if ( (elem = unmatched[i]) ) {\r
+                       if ( !filter || filter( elem, context, xml ) ) {\r
+                               newUnmatched.push( elem );\r
+                               if ( mapped ) {\r
+                                       map.push( i );\r
+                               }\r
+                       }\r
                }\r
        }\r
 \r
-       return matcher;\r
+       return newUnmatched;\r
 }\r
 \r
-function matcherFromGroupMatchers( matchers ) {\r
-       return function( elem ) {\r
-               var matcher,\r
-                       j = 0;\r
-               for ( ; (matcher = matchers[j]); j++ ) {\r
-                       if ( matcher(elem) ) {\r
-                               return true;\r
-                       }\r
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\r
+       if ( postFilter && !postFilter[ expando ] ) {\r
+               postFilter = setMatcher( postFilter );\r
+       }\r
+       if ( postFinder && !postFinder[ expando ] ) {\r
+               postFinder = setMatcher( postFinder, postSelector );\r
+       }\r
+       return markFunction(function( seed, results, context, xml ) {\r
+               // Positional selectors apply to seed elements, so it is invalid to follow them with relative ones\r
+               if ( seed && postFinder ) {\r
+                       return;\r
                }\r
-               return false;\r
-       };\r
-}\r
 \r
-compile = Sizzle.compile = function( selector, context, xml ) {\r
-       var group, i, len,\r
-               cached = compilerCache[ expando ][ selector ];\r
+               var i, elem, postFilterIn,\r
+                       preMap = [],\r
+                       postMap = [],\r
+                       preexisting = results.length,\r
 \r
-       // Return a cached group function if already generated (context dependent)\r
-       if ( cached && cached.context === context ) {\r
-               return cached;\r
-       }\r
+                       // Get initial elements from seed or context\r
+                       elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [], seed ),\r
 \r
-       // Generate a function of recursive functions that can be used to check each element\r
-       group = tokenize( selector, context, xml );\r
-       for ( i = 0, len = group.length; i < len; i++ ) {\r
-               group[i] = matcherFromTokens(group[i], context, xml);\r
-       }\r
+                       // Prefilter to get matcher input, preserving a map for seed-results synchronization\r
+                       matcherIn = preFilter && ( seed || !selector ) ?\r
+                               condense( elems, preMap, preFilter, context, xml ) :\r
+                               elems,\r
 \r
-       // Cache the compiled function\r
-       cached = compilerCache( selector, matcherFromGroupMatchers(group) );\r
-       cached.context = context;\r
-       cached.runs = cached.dirruns = 0;\r
-       return cached;\r
-};\r
+                       matcherOut = matcher ?\r
+                               // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\r
+                               postFinder || ( seed ? preFilter : preexisting || postFilter ) ?\r
 \r
-function multipleContexts( selector, contexts, results, seed ) {\r
-       var i = 0,\r
-               len = contexts.length;\r
-       for ( ; i < len; i++ ) {\r
-               Sizzle( selector, contexts[i], results, seed );\r
-       }\r
-}\r
+                                       // ...intermediate processing is necessary\r
+                                       [] :\r
 \r
-function handlePOSGroup( selector, posfilter, argument, contexts, seed, not ) {\r
-       var results,\r
-               fn = Expr.setFilters[ posfilter.toLowerCase() ];\r
+                                       // ...otherwise use results directly\r
+                                       results :\r
+                               matcherIn;\r
 \r
-       if ( !fn ) {\r
-               Sizzle.error( posfilter );\r
-       }\r
+               // Find primary matches\r
+               if ( matcher ) {\r
+                       matcher( matcherIn, matcherOut, context, xml );\r
+               }\r
 \r
-       if ( selector || !(results = seed) ) {\r
-               multipleContexts( selector || "*", contexts, (results = []), seed );\r
-       }\r
+               // Apply postFilter\r
+               if ( postFilter ) {\r
+                       postFilterIn = condense( matcherOut, postMap );\r
+                       postFilter( postFilterIn, [], context, xml );\r
 \r
-       return results.length > 0 ? fn( results, argument, not ) : [];\r
-}\r
+                       // Un-match failing elements by moving them back to matcherIn\r
+                       i = postFilterIn.length;\r
+                       while ( i-- ) {\r
+                               if ( (elem = postFilterIn[i]) ) {\r
+                                       matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\r
+                               }\r
+                       }\r
+               }\r
 \r
-function handlePOS( groups, context, results, seed ) {\r
-       var group, part, j, groupLen, token, selector,\r
-               anchor, elements, match, matched,\r
-               lastIndex, currentContexts, not,\r
-               i = 0,\r
-               len = groups.length,\r
-               rpos = matchExpr["POS"],\r
-               // This is generated here in case matchExpr["POS"] is extended\r
-               rposgroups = new RegExp( "^" + rpos.source + "(?!" + whitespace + ")", "i" ),\r
-               // This is for making sure non-participating\r
-               // matching groups are represented cross-browser (IE6-8)\r
-               setUndefined = function() {\r
-                       var i = 1,\r
-                               len = arguments.length - 2;\r
-                       for ( ; i < len; i++ ) {\r
-                               if ( arguments[i] === undefined ) {\r
-                                       match[i] = undefined;\r
+               // Keep seed and results synchronized\r
+               if ( seed ) {\r
+                       // Ignore postFinder because it can't coexist with seed\r
+                       i = preFilter && matcherOut.length;\r
+                       while ( i-- ) {\r
+                               if ( (elem = matcherOut[i]) ) {\r
+                                       seed[ preMap[i] ] = !(results[ preMap[i] ] = elem);\r
                                }\r
                        }\r
-               };\r
+               } else {\r
+                       matcherOut = condense(\r
+                               matcherOut === results ?\r
+                                       matcherOut.splice( preexisting, matcherOut.length ) :\r
+                                       matcherOut\r
+                       );\r
+                       if ( postFinder ) {\r
+                               postFinder( null, results, matcherOut, xml );\r
+                       } else {\r
+                               push.apply( results, matcherOut );\r
+                       }\r
+               }\r
+       });\r
+}\r
+\r
+function matcherFromTokens( tokens ) {\r
+       var checkContext, matcher, j,\r
+               len = tokens.length,\r
+               leadingRelative = Expr.relative[ tokens[0].type ],\r
+               implicitRelative = leadingRelative || Expr.relative[" "],\r
+               i = leadingRelative ? 1 : 0,\r
+\r
+               // The foundational matcher ensures that elements are reachable from top-level context(s)\r
+               matchContext = addCombinator( function( elem ) {\r
+                       return elem === checkContext;\r
+               }, implicitRelative, true ),\r
+               matchAnyContext = addCombinator( function( elem ) {\r
+                       return indexOf.call( checkContext, elem ) > -1;\r
+               }, implicitRelative, true ),\r
+               matchers = [ function( elem, context, xml ) {\r
+                       return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\r
+                               (checkContext = context).nodeType ?\r
+                                       matchContext( elem, context, xml ) :\r
+                                       matchAnyContext( elem, context, xml ) );\r
+               } ];\r
 \r
        for ( ; i < len; i++ ) {\r
-               group = groups[i];\r
-               part = "";\r
-               elements = seed;\r
-               for ( j = 0, groupLen = group.length; j < groupLen; j++ ) {\r
-                       token = group[j];\r
-                       selector = token.string;\r
-                       if ( token.part === "PSEUDO" ) {\r
-                               // Reset regex index to 0\r
-                               rpos.exec("");\r
-                               anchor = 0;\r
-                               while ( (match = rpos.exec( selector )) ) {\r
-                                       matched = true;\r
-                                       lastIndex = rpos.lastIndex = match.index + match[0].length;\r
-                                       if ( lastIndex > anchor ) {\r
-                                               part += selector.slice( anchor, match.index );\r
-                                               anchor = lastIndex;\r
-                                               currentContexts = [ context ];\r
-\r
-                                               if ( rcombinators.test(part) ) {\r
-                                                       if ( elements ) {\r
-                                                               currentContexts = elements;\r
-                                                       }\r
-                                                       elements = seed;\r
-                                               }\r
+               if ( (matcher = Expr.relative[ tokens[i].type ]) ) {\r
+                       matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\r
+               } else {\r
+                       // The concatenated values are (context, xml) for backCompat\r
+                       matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\r
+\r
+                       // Return special upon seeing a positional matcher\r
+                       if ( matcher[ expando ] ) {\r
+                               // Find the next relative operator (if any) for proper handling\r
+                               j = ++i;\r
+                               for ( ; j < len; j++ ) {\r
+                                       if ( Expr.relative[ tokens[j].type ] ) {\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               return setMatcher(\r
+                                       i > 1 && elementMatcher( matchers ),\r
+                                       i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ),\r
+                                       matcher,\r
+                                       i < j && matcherFromTokens( tokens.slice( i, j ) ),\r
+                                       j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\r
+                                       j < len && tokens.join("")\r
+                               );\r
+                       }\r
+                       matchers.push( matcher );\r
+               }\r
+       }\r
 \r
-                                               if ( (not = rendsWithNot.test( part )) ) {\r
-                                                       part = part.slice( 0, -5 ).replace( rcombinators, "$&*" );\r
-                                                       anchor++;\r
-                                               }\r
+       return elementMatcher( matchers );\r
+}\r
 \r
-                                               if ( match.length > 1 ) {\r
-                                                       match[0].replace( rposgroups, setUndefined );\r
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {\r
+       var bySet = setMatchers.length > 0,\r
+               byElement = elementMatchers.length > 0,\r
+               superMatcher = function( seed, context, xml, results, expandContext ) {\r
+                       var elem, j, matcher,\r
+                               setMatched = [],\r
+                               matchedCount = 0,\r
+                               i = "0",\r
+                               unmatched = seed && [],\r
+                               outermost = expandContext != null,\r
+                               contextBackup = outermostContext,\r
+                               // We must always have either seed elements or context\r
+                               elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),\r
+                               // Nested matchers should use non-integer dirruns\r
+                               dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E);\r
+\r
+                       if ( outermost ) {\r
+                               outermostContext = context !== document && context;\r
+                               cachedruns = superMatcher.el;\r
+                       }\r
+\r
+                       // Add elements passing elementMatchers directly to results\r
+                       for ( ; (elem = elems[i]) != null; i++ ) {\r
+                               if ( byElement && elem ) {\r
+                                       for ( j = 0; (matcher = elementMatchers[j]); j++ ) {\r
+                                               if ( matcher( elem, context, xml ) ) {\r
+                                                       results.push( elem );\r
+                                                       break;\r
                                                }\r
-                                               elements = handlePOSGroup( part, match[1], match[2], currentContexts, elements, not );\r
                                        }\r
-                                       part = "";\r
+                                       if ( outermost ) {\r
+                                               dirruns = dirrunsUnique;\r
+                                               cachedruns = ++superMatcher.el;\r
+                                       }\r
                                }\r
 \r
-                       }\r
+                               // Track unmatched elements for set filters\r
+                               if ( bySet ) {\r
+                                       // They will have gone through all possible matchers\r
+                                       if ( (elem = !matcher && elem) ) {\r
+                                               matchedCount--;\r
+                                       }\r
 \r
-                       if ( !matched ) {\r
-                               part += selector;\r
+                                       // Lengthen the array for every element, matched or not\r
+                                       if ( seed ) {\r
+                                               unmatched.push( elem );\r
+                                       }\r
+                               }\r
                        }\r
-                       matched = false;\r
-               }\r
 \r
-               if ( part ) {\r
-                       if ( rcombinators.test(part) ) {\r
-                               multipleContexts( part, elements || [ context ], results, seed );\r
-                       } else {\r
-                               Sizzle( part, context, results, seed ? seed.concat(elements) : elements );\r
-                       }\r
-               } else {\r
-                       push.apply( results, elements );\r
-               }\r
-       }\r
+                       // Apply set filters to unmatched elements\r
+                       matchedCount += i;\r
+                       if ( bySet && i !== matchedCount ) {\r
+                               for ( j = 0; (matcher = setMatchers[j]); j++ ) {\r
+                                       matcher( unmatched, setMatched, context, xml );\r
+                               }\r
 \r
-       // Do not sort if this is a single filter\r
-       return len === 1 ? results : Sizzle.uniqueSort( results );\r
-}\r
+                               if ( seed ) {\r
+                                       // Reintegrate element matches to eliminate the need for sorting\r
+                                       if ( matchedCount > 0 ) {\r
+                                               while ( i-- ) {\r
+                                                       if ( !(unmatched[i] || setMatched[i]) ) {\r
+                                                               setMatched[i] = pop.call( results );\r
+                                                       }\r
+                                               }\r
+                                       }\r
 \r
-function select( selector, context, results, seed, xml ) {\r
-       // Remove excessive whitespace\r
-       selector = selector.replace( rtrim, "$1" );\r
-       var elements, matcher, cached, elem,\r
-               i, tokens, token, lastToken, findContext, type,\r
-               match = tokenize( selector, context, xml ),\r
-               contextNodeType = context.nodeType;\r
-\r
-       // POS handling\r
-       if ( matchExpr["POS"].test(selector) ) {\r
-               return handlePOS( match, context, results, seed );\r
-       }\r
+                                       // Discard index placeholder values to get only actual matches\r
+                                       setMatched = condense( setMatched );\r
+                               }\r
 \r
-       if ( seed ) {\r
-               elements = slice.call( seed, 0 );\r
+                               // Add matches to results\r
+                               push.apply( results, setMatched );\r
 \r
-       // To maintain document order, only narrow the\r
-       // set if there is one group\r
-       } else if ( match.length === 1 ) {\r
+                               // Seedless set matches succeeding multiple successful matchers stipulate sorting\r
+                               if ( outermost && !seed && setMatched.length > 0 &&\r
+                                       ( matchedCount + setMatchers.length ) > 1 ) {\r
 \r
-               // Take a shortcut and set the context if the root selector is an ID\r
-               if ( (tokens = slice.call( match[0], 0 )).length > 2 &&\r
-                               (token = tokens[0]).part === "ID" &&\r
-                               contextNodeType === 9 && !xml &&\r
-                               Expr.relative[ tokens[1].part ] ) {\r
+                                       Sizzle.uniqueSort( results );\r
+                               }\r
+                       }\r
 \r
-                       context = Expr.find["ID"]( token.captures[0].replace( rbackslash, "" ), context, xml )[0];\r
-                       if ( !context ) {\r
-                               return results;\r
+                       // Override manipulation of globals by nested matchers\r
+                       if ( outermost ) {\r
+                               dirruns = dirrunsUnique;\r
+                               outermostContext = contextBackup;\r
                        }\r
 \r
-                       selector = selector.slice( tokens.shift().string.length );\r
-               }\r
+                       return unmatched;\r
+               };\r
+\r
+       superMatcher.el = 0;\r
+       return bySet ?\r
+               markFunction( superMatcher ) :\r
+               superMatcher;\r
+}\r
 \r
-               findContext = ( (match = rsibling.exec( tokens[0].string )) && !match.index && context.parentNode ) || context;\r
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\r
+       var i,\r
+               setMatchers = [],\r
+               elementMatchers = [],\r
+               cached = compilerCache[ expando ][ selector ];\r
 \r
-               // Reduce the set if possible\r
-               lastToken = "";\r
-               for ( i = tokens.length - 1; i >= 0; i-- ) {\r
-                       token = tokens[i];\r
-                       type = token.part;\r
-                       lastToken = token.string + lastToken;\r
-                       if ( Expr.relative[ type ] ) {\r
-                               break;\r
+       if ( !cached ) {\r
+               // Generate a function of recursive functions that can be used to check each element\r
+               if ( !group ) {\r
+                       group = tokenize( selector );\r
+               }\r
+               i = group.length;\r
+               while ( i-- ) {\r
+                       cached = matcherFromTokens( group[i] );\r
+                       if ( cached[ expando ] ) {\r
+                               setMatchers.push( cached );\r
+                       } else {\r
+                               elementMatchers.push( cached );\r
                        }\r
-                       if ( Expr.order.test(type) ) {\r
-                               elements = Expr.find[ type ]( token.captures[0].replace( rbackslash, "" ), findContext, xml );\r
-                               if ( elements == null ) {\r
-                                       continue;\r
-                               } else {\r
-                                       selector = selector.slice( 0, selector.length - lastToken.length ) +\r
-                                               lastToken.replace( matchExpr[ type ], "" );\r
+               }\r
 \r
-                                       if ( !selector ) {\r
-                                               push.apply( results, slice.call(elements, 0) );\r
-                                       }\r
+               // Cache the compiled function\r
+               cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\r
+       }\r
+       return cached;\r
+};\r
 \r
-                                       break;\r
+function multipleContexts( selector, contexts, results, seed ) {\r
+       var i = 0,\r
+               len = contexts.length;\r
+       for ( ; i < len; i++ ) {\r
+               Sizzle( selector, contexts[i], results, seed );\r
+       }\r
+       return results;\r
+}\r
+\r
+function select( selector, context, results, seed, xml ) {\r
+       var i, tokens, token, type, find,\r
+               match = tokenize( selector ),\r
+               j = match.length;\r
+\r
+       if ( !seed ) {\r
+               // Try to minimize operations if there is only one group\r
+               if ( match.length === 1 ) {\r
+\r
+                       // Take a shortcut and set the context if the root selector is an ID\r
+                       tokens = match[0] = match[0].slice( 0 );\r
+                       if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&\r
+                                       context.nodeType === 9 && !xml &&\r
+                                       Expr.relative[ tokens[1].type ] ) {\r
+\r
+                               context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0];\r
+                               if ( !context ) {\r
+                                       return results;\r
                                }\r
+\r
+                               selector = selector.slice( tokens.shift().length );\r
                        }\r
-               }\r
-       }\r
 \r
-       // Only loop over the given elements once\r
-       if ( selector ) {\r
-               matcher = compile( selector, context, xml );\r
-               dirruns = matcher.dirruns++;\r
-               if ( elements == null ) {\r
-                       elements = Expr.find["TAG"]( "*", (rsibling.test( selector ) && context.parentNode) || context );\r
-               }\r
+                       // Fetch a seed set for right-to-left matching\r
+                       for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) {\r
+                               token = tokens[i];\r
+\r
+                               // Abort if we hit a combinator\r
+                               if ( Expr.relative[ (type = token.type) ] ) {\r
+                                       break;\r
+                               }\r
+                               if ( (find = Expr.find[ type ]) ) {\r
+                                       // Search, expanding context for leading sibling combinators\r
+                                       if ( (seed = find(\r
+                                               token.matches[0].replace( rbackslash, "" ),\r
+                                               rsibling.test( tokens[0].type ) && context.parentNode || context,\r
+                                               xml\r
+                                       )) ) {\r
+\r
+                                               // If seed is empty or no tokens remain, we can return early\r
+                                               tokens.splice( i, 1 );\r
+                                               selector = seed.length && tokens.join("");\r
+                                               if ( !selector ) {\r
+                                                       push.apply( results, slice.call( seed, 0 ) );\r
+                                                       return results;\r
+                                               }\r
 \r
-               for ( i = 0; (elem = elements[i]); i++ ) {\r
-                       cachedruns = matcher.runs++;\r
-                       if ( matcher(elem) ) {\r
-                               results.push( elem );\r
+                                               break;\r
+                                       }\r
+                               }\r
                        }\r
                }\r
        }\r
 \r
+       // Compile and execute a filtering function\r
+       // Provide `match` to avoid retokenization if we modified the selector above\r
+       compile( selector, match )(\r
+               seed,\r
+               context,\r
+               xml,\r
+               results,\r
+               rsibling.test( selector )\r
+       );\r
        return results;\r
 }\r
 \r
@@ -5037,11 +5166,16 @@ if ( document.querySelectorAll ) {
                        oldSelect = select,\r
                        rescape = /'|\\/g,\r
                        rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,\r
-                       rbuggyQSA = [],\r
+\r
+                       // qSa(:focus) reports false when true (Chrome 21),\r
+                       // A support test would require too much code (would include document ready)\r
+                       rbuggyQSA = [":focus"],\r
+\r
+                       // matchesSelector(:focus) reports false when true (Chrome 21),\r
                        // matchesSelector(:active) reports false when true (IE9/Opera 11.5)\r
                        // A support test would require too much code (would include document ready)\r
                        // just skip matchesSelector for :active\r
-                       rbuggyMatches = [":active"],\r
+                       rbuggyMatches = [ ":active", ":focus" ],\r
                        matches = docElem.matchesSelector ||\r
                                docElem.mozMatchesSelector ||\r
                                docElem.webkitMatchesSelector ||\r
@@ -5088,44 +5222,46 @@ if ( document.querySelectorAll ) {
                        }\r
                });\r
 \r
-               rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );\r
+               // rbuggyQSA always contains :focus, so no need for a length check\r
+               rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") );\r
 \r
                select = function( selector, context, results, seed, xml ) {\r
                        // Only use querySelectorAll when not filtering,\r
                        // when this is not xml,\r
                        // and when no QSA bugs apply\r
                        if ( !seed && !xml && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\r
-                               if ( context.nodeType === 9 ) {\r
-                                       try {\r
-                                               push.apply( results, slice.call(context.querySelectorAll( selector ), 0) );\r
-                                               return results;\r
-                                       } catch(qsaError) {}\r
+                               var groups, i,\r
+                                       old = true,\r
+                                       nid = expando,\r
+                                       newContext = context,\r
+                                       newSelector = context.nodeType === 9 && selector;\r
+\r
                                // qSA works strangely on Element-rooted queries\r
                                // We can work around this by specifying an extra ID on the root\r
                                // and working up from there (Thanks to Andrew Dupont for the technique)\r
                                // IE 8 doesn't work on object elements\r
-                               } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {\r
-                                       var groups, i, len,\r
-                                               old = context.getAttribute("id"),\r
-                                               nid = old || expando,\r
-                                               newContext = rsibling.test( selector ) && context.parentNode || context;\r
-\r
-                                       if ( old ) {\r
-                                               nid = nid.replace( rescape, "\\$&" );\r
+                               if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {\r
+                                       groups = tokenize( selector );\r
+\r
+                                       if ( (old = context.getAttribute("id")) ) {\r
+                                               nid = old.replace( rescape, "\\$&" );\r
                                        } else {\r
                                                context.setAttribute( "id", nid );\r
                                        }\r
+                                       nid = "[id='" + nid + "'] ";\r
 \r
-                                       groups = tokenize(selector, context, xml);\r
-                                       // Trailing space is unnecessary\r
-                                       // There is always a context check\r
-                                       nid = "[id='" + nid + "']";\r
-                                       for ( i = 0, len = groups.length; i < len; i++ ) {\r
-                                               groups[i] = nid + groups[i].selector;\r
+                                       i = groups.length;\r
+                                       while ( i-- ) {\r
+                                               groups[i] = nid + groups[i].join("");\r
                                        }\r
+                                       newContext = rsibling.test( selector ) && context.parentNode || context;\r
+                                       newSelector = groups.join(",");\r
+                               }\r
+\r
+                               if ( newSelector ) {\r
                                        try {\r
                                                push.apply( results, slice.call( newContext.querySelectorAll(\r
-                                                       groups.join(",")\r
+                                                       newSelector\r
                                                ), 0 ) );\r
                                                return results;\r
                                        } catch(qsaError) {\r
@@ -5150,11 +5286,11 @@ if ( document.querySelectorAll ) {
                                // Gecko does not error, returns false instead\r
                                try {\r
                                        matches.call( div, "[test!='']:sizzle" );\r
-                                       rbuggyMatches.push( matchExpr["PSEUDO"].source, matchExpr["POS"].source, "!=" );\r
+                                       rbuggyMatches.push( "!=", pseudos );\r
                                } catch ( e ) {}\r
                        });\r
 \r
-                       // rbuggyMatches always contains :active, so no need for a length check\r
+                       // rbuggyMatches always contains :active and :focus, so no need for a length check\r
                        rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") );\r
 \r
                        Sizzle.matchesSelector = function( elem, expr ) {\r
@@ -5183,10 +5319,12 @@ if ( document.querySelectorAll ) {
 }\r
 \r
 // Deprecated\r
-Expr.setFilters["nth"] = Expr.setFilters["eq"];\r
+Expr.pseudos["nth"] = Expr.pseudos["eq"];\r
 \r
 // Back-compat\r
-Expr.filters = Expr.pseudos;\r
+function setFilters() {}\r
+Expr.filters = setFilters.prototype = Expr.pseudos;\r
+Expr.setFilters = new setFilters();\r
 \r
 // Override sizzle attribute retrieval
 Sizzle.attr = jQuery.attr;
@@ -7123,10 +7261,10 @@ function buildParams( prefix, obj, traditional, add ) {
                add( prefix, obj );
        }
 }
-var // Document location
-       ajaxLocation,
-       // Document location segments
+var
+       // Document location
        ajaxLocParts,
+       ajaxLocation,
 
        rhash = /#.*$/,
        rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
@@ -7643,7 +7781,7 @@ jQuery.extend({
 
                        // Set data for the fake xhr object
                        jqXHR.status = status;
-                       jqXHR.statusText = "" + ( nativeStatusText || statusText );
+                       jqXHR.statusText = ( nativeStatusText || statusText ) + "";
 
                        // Success/Error
                        if ( isSuccess ) {
@@ -7703,14 +7841,11 @@ jQuery.extend({
                // Extract dataTypes list
                s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace );
 
-               // Determine if a cross-domain request is in order
+               // A cross-domain request is in order when we have a protocol:host:port mismatch
                if ( s.crossDomain == null ) {
-                       parts = rurl.exec( s.url.toLowerCase() );
-                       s.crossDomain = !!( parts &&
-                               ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
-                                       ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
-                                               ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
-                       );
+                       parts = rurl.exec( s.url.toLowerCase() ) || false;
+                       s.crossDomain = parts && ( parts.join(":") + ( parts[ 3 ] ? "" : parts[ 1 ] === "http:" ? 80 : 443 ) ) !==
+                               ( ajaxLocParts.join(":") + ( ajaxLocParts[ 3 ] ? "" : ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) );
                }
 
                // Convert data if not already a string
@@ -8405,12 +8540,13 @@ var fxNow, timerId,
        animationPrefilters = [ defaultPrefilter ],
        tweeners = {
                "*": [function( prop, value ) {
-                       var end, unit, prevScale,
+                       var end, unit,
                                tween = this.createTween( prop, value ),
                                parts = rfxnum.exec( value ),
                                target = tween.cur(),
                                start = +target || 0,
-                               scale = 1;
+                               scale = 1,
+                               maxIterations = 20;
 
                        if ( parts ) {
                                end = +parts[2];
@@ -8426,17 +8562,15 @@ var fxNow, timerId,
                                        do {
                                                // If previous iteration zeroed out, double until we get *something*
                                                // Use a string for doubling factor so we don't accidentally see scale as unchanged below
-                                               prevScale = scale = scale || ".5";
+                                               scale = scale || ".5";
 
                                                // Adjust and apply
                                                start = start / scale;
                                                jQuery.style( tween.elem, prop, start + unit );
 
-                                               // Update scale, tolerating zeroes from tween.cur()
-                                               scale = tween.cur() / target;
-
-                                       // Stop looping if we've hit the mark or scale is unchanged
-                                       } while ( scale !== 1 && scale !== prevScale );
+                                       // Update scale, tolerating zero or NaN from tween.cur()
+                                       // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+                                       } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
                                }
 
                                tween.unit = unit;
@@ -9069,7 +9203,8 @@ jQuery.fn.offset = function( options ) {
                        });
        }
 
-       var box, docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, top, left,
+       var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft,
+               box = { top: 0, left: 0 },
                elem = this[ 0 ],
                doc = elem && elem.ownerDocument;
 
@@ -9083,21 +9218,25 @@ jQuery.fn.offset = function( options ) {
 
        docElem = doc.documentElement;
 
-       // Make sure we're not dealing with a disconnected DOM node
+       // Make sure it's not a disconnected DOM node
        if ( !jQuery.contains( docElem, elem ) ) {
-               return { top: 0, left: 0 };
+               return box;
        }
 
-       box = elem.getBoundingClientRect();
+       // If we don't have gBCR, just use 0,0 rather than error
+       // BlackBerry 5, iOS 3 (original iPhone)
+       if ( typeof elem.getBoundingClientRect !== "undefined" ) {
+               box = elem.getBoundingClientRect();
+       }
        win = getWindow( doc );
        clientTop  = docElem.clientTop  || body.clientTop  || 0;
        clientLeft = docElem.clientLeft || body.clientLeft || 0;
        scrollTop  = win.pageYOffset || docElem.scrollTop;
        scrollLeft = win.pageXOffset || docElem.scrollLeft;
-       top  = box.top  + scrollTop  - clientTop;
-       left = box.left + scrollLeft - clientLeft;
-
-       return { top: top, left: left };
+       return {
+               top: box.top  + scrollTop  - clientTop,
+               left: box.left + scrollLeft - clientLeft
+       };
 };
 
 jQuery.offset = {
diff --git a/resources/mediawiki/mediawiki.hidpi.js b/resources/mediawiki/mediawiki.hidpi.js
new file mode 100644 (file)
index 0000000..1979573
--- /dev/null
@@ -0,0 +1,5 @@
+$( function() {
+       // Apply hidpi images on DOM-ready
+       // Some may have already partly preloaded at low resolution.
+       $( 'body' ).hidpi();
+} );
\ No newline at end of file
index b484629..1a72ed1 100644 (file)
@@ -828,7 +828,7 @@ var mw = ( function ( $, undefined ) {
                         * @param module string module name to execute
                         */
                        function execute( module ) {
-                               var key, value, media, i, script, markModuleReady, nestedAddScript;
+                               var key, value, media, i, urls, script, markModuleReady, nestedAddScript;
 
                                if ( registry[module] === undefined ) {
                                        throw new Error( 'Module has not been registered yet: ' + module );
@@ -896,7 +896,12 @@ var mw = ( function ( $, undefined ) {
                                                // Array of urls inside media-type key
                                                } else if ( typeof value === 'object' ) {
                                                        // { "url": { <media>: [url, ..] } }
-                                                       $.each( value, addLink );
+                                                       for ( media in value ) {
+                                                               urls = value[media];
+                                                               for ( i = 0; i < urls.length; i += 1 ) {
+                                                                       addLink( media, urls[i] );
+                                                               }
+                                                       }
                                                }
                                        }
                                }
index 473ee2b..17487f4 100644 (file)
@@ -669,7 +669,7 @@ class CologneBlueTemplate extends BaseTemplate {
                        . "<input type='submit' class=\"searchButton\" name=\"go\" value=\"" . wfMessage( 'searcharticle' )->escaped() . "\" />";
 
                if( $wgUseTwoButtonsSearchForm ) {
-                       $s .= " <input type='submit' class=\"searchButton\" name=\"fulltext\" value=\"" . wfMessage( 'search' )->escaped() . "\" />\n";
+                       $s .= " <input type='submit' class=\"searchButton\" name=\"fulltext\" value=\"" . wfMessage( 'searchbutton' )->escaped() . "\" />\n";
                } else {
                        $s .= '<div><a href="' . $action . '" rel="search">' . wfMessage( 'powersearch-legend' )->escaped() . "</a></div>\n";
                }
index fb0c848..b9f1817 100644 (file)
@@ -671,7 +671,7 @@ class ParserTest {
                        'wgNoFollowLinks' => true,
                        'wgNoFollowDomainExceptions' => array(),
                        'wgThumbnailScriptPath' => false,
-                       'wgUseImageResize' => false,
+                       'wgUseImageResize' => true,
                        'wgLocaltimezone' => 'UTC',
                        'wgAllowExternalImages' => true,
                        'wgUseTidy' => false,
@@ -991,6 +991,16 @@ class ParserTest {
                                "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg",
                                "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/30px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/40px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg",
+                               "$dir/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg",
 
                                "$dir/0/09/Bad.jpg",
 
index 3a15ed5..826df81 100644 (file)
@@ -71,6 +71,12 @@ Template:echo
 {{{1}}}
 !! endarticle
 
+!! article
+Template:attr_str
+!! text
+{{{1}}}="{{{2}}}"
+!! endarticle
+
 ###
 ### Basic tests
 ###
@@ -4046,6 +4052,14 @@ Template parameter as link source
 </p>
 !! end
 
+!!test
+Template-generated attribute string (k='v')
+!!input
+<span {{attr_str|id|v1}}>bar</span>
+!!result
+<p><span id="v1">bar</span>
+</p>
+!!end
 
 !!article
 Template:paramtest2
@@ -4326,7 +4340,7 @@ section=1
 ### <includeonly> and <noinclude> in attributes
 ###
 !!test
-1. includeonly around the entire attribute
+0. includeonly around the entire attribute
 !!input
 <span <includeonly>id="v1"</includeonly><noinclude>id="v2"</noinclude>>bar</span>
 !!result
@@ -4335,7 +4349,7 @@ section=1
 !!end
 
 !!test
-2. includeonly in html attr key
+1. includeonly in html attr key
 !!input
 <span <noinclude>id</noinclude><includeonly>about</includeonly>="foo">bar</span>
 !!result
@@ -4344,7 +4358,7 @@ section=1
 !!end
 
 !!test
-3. includeonly in html attr value
+2. includeonly in html attr value
 !!input
 <span id="<noinclude>v1</noinclude><includeonly>v2</includeonly>">bar</span>
 <span id=<noinclude>"v1"</noinclude><includeonly>"v2"</includeonly>>bar</span>
@@ -4355,7 +4369,7 @@ section=1
 !!end
 
 !!test
-4. includeonly in part of an attr value
+3. includeonly in part of an attr value
 !!input
 <span style="color:<noinclude>red</noinclude><includeonly>blue</includeonly>;">bar</span>
 !!result
@@ -5372,6 +5386,15 @@ Image with caption
 
 !! end
 
+!! test
+Image with empty attribute
+!! input
+[[Image:foobar.jpg|right||Caption text]]
+!! result
+<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image" title="Caption text"><img alt="Caption text" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div>
+
+!! end
+
 !! test
 Image with link parameter, wiki target
 !! input
@@ -5466,7 +5489,7 @@ Thumbnail image with link parameter
 !! input
 [[Image:foobar.jpg|thumb|link=http://example.com/|Title]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="http://example.com/"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="http://example.com/"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Title</div></div></div>
 
 !! end
 
@@ -5540,7 +5563,7 @@ Thumbnail image caption with a free URL
 !! input
 [[Image:foobar.jpg|thumb|http://example.com]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
 
 !! end
 
@@ -5549,7 +5572,7 @@ Thumbnail image caption with a free URL and explicit alt
 !! input
 [[Image:foobar.jpg|thumb|http://example.com|alt=Alteration]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Alteration" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Alteration" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></div></div></div>
 
 !! end
 
@@ -5558,7 +5581,7 @@ BUG 1887: A ISBN with a thumbnail
 !! input
 [[Image:foobar.jpg|thumb|ISBN 1235467890]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a href="/wiki/Special:BookSources/1235467890" class="internal mw-magiclink-isbn">ISBN 1235467890</a></div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><a href="/wiki/Special:BookSources/1235467890" class="internal mw-magiclink-isbn">ISBN 1235467890</a></div></div></div>
 
 !! end
 
@@ -5567,7 +5590,7 @@ BUG 1887: A RFC with a thumbnail
 !! input
 [[Image:foobar.jpg|thumb|This is RFC 12354]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is <a class="external mw-magiclink-rfc" href="//tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is <a class="external mw-magiclink-rfc" href="//tools.ietf.org/html/rfc12354">RFC 12354</a></div></div></div>
 
 !! end
 
@@ -5576,7 +5599,7 @@ BUG 1887: A mailto link with a thumbnail
 !! input
 [[Image:foobar.jpg|thumb|Please mailto:nobody@example.com]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Please <a rel="nofollow" class="external free" href="mailto:nobody@example.com">mailto:nobody@example.com</a></div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>Please <a rel="nofollow" class="external free" href="mailto:nobody@example.com">mailto:nobody@example.com</a></div></div></div>
 
 !! end
 
@@ -5649,7 +5672,7 @@ Image caption containing another image
 !! input
 [[Image:Foobar.jpg|thumb|This is a caption with another [[Image:icon.png|image]] inside it!]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is a caption with another <a href="/index.php?title=Special:Upload&amp;wpDestFile=Icon.png" class="new" title="File:Icon.png">image</a> inside it!</div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This is a caption with another <a href="/index.php?title=Special:Upload&amp;wpDestFile=Icon.png" class="new" title="File:Icon.png">image</a> inside it!</div></div></div>
 
 !! end
 
@@ -5669,7 +5692,7 @@ Bug 3090: External links other than http: in image captions
 !! input
 [[Image:Foobar.jpg|thumb|200px|This caption has [irc://example.net irc] and [https://example.com Secure] ext links in it.]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="200" height="23" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This caption has <a rel="nofollow" class="external text" href="irc://example.net">irc</a> and <a rel="nofollow" class="external text" href="https://example.com">Secure</a> ext links in it.</div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:202px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg" width="200" height="23" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/300px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/400px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>This caption has <a rel="nofollow" class="external text" href="irc://example.net">irc</a> and <a rel="nofollow" class="external text" href="https://example.com">Secure</a> ext links in it.</div></div></div>
 
 !! end
 
@@ -5839,6 +5862,39 @@ pst
 [[Category:Foo (bar)|Foo]]
 !! end
 
+!! test
+Category with template
+!! options
+cat
+pst
+!! input
+[[Category:{{echo|Foo}}]]
+!! result
+[[Category:{{echo|Foo}}]]
+!! end
+
+!! test
+Category with template in sort key
+!! options
+cat
+pst
+!! input
+[[Category:Foo|{{echo|Bar}}]]
+!! result
+[[Category:Foo|{{echo|Bar}}]]
+!! end
+
+!! test
+Category with template in sort key and title
+!! options
+cat
+pst
+!! input
+[[Category:{{echo|Foo}}|{{echo|Bar}}]]
+!! result
+[[Category:{{echo|Foo}}|{{echo|Bar}}]]
+!! end
+
 ###
 ### Inter-language links
 ###
@@ -8799,19 +8855,19 @@ image:foobar.jpg|Blabla|alt=This is a foo-bar.|blabla.
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 105px"><div style="width: 105px">
-                       <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="70" height="8" /></a></div></div>
+                       <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" width="70" height="8" /></a></div></div>
                        <div class="gallerytext">
 <p>some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a>
 </p>
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 105px"><div style="width: 105px">
-                       <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="70" height="8" /></a></div></div>
+                       <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" width="70" height="8" /></a></div></div>
                        <div class="gallerytext">
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 105px"><div style="width: 105px">
-                       <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="This is a foo-bar." src="http://example.com/images/3/3a/Foobar.jpg" width="70" height="8" /></a></div></div>
+                       <div class="thumb" style="width: 100px;"><div style="margin:31px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="This is a foo-bar." src="http://example.com/images/thumb/3/3a/Foobar.jpg/70px-Foobar.jpg" width="70" height="8" /></a></div></div>
                        <div class="gallerytext">
 <p>Blabla|blabla.
 </p>
@@ -8831,14 +8887,14 @@ File:foobar.jpg|{{Test|unamedParam|alt=param}}|alt=galleryalt
 !! result
 <ul class="gallery">
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="galleryalt" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
-<p><a href="/wiki/File:Foobar.jpg" class="image" title="desc"><img alt="inneralt" src="http://example.com/images/3/3a/Foobar.jpg" width="20" height="2" /></a>
+<p><a href="/wiki/File:Foobar.jpg" class="image" title="desc"><img alt="inneralt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/20px-Foobar.jpg" width="20" height="2" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/30px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/40px-Foobar.jpg 2x" /></a>
 </p>
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="galleryalt" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
 <p>This is a test template
 </p>
@@ -8875,7 +8931,7 @@ caption
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
 <p><a href="/wiki/File:Foobar.jpg" title="File:Foobar.jpg">Foobar.jpg</a><br />
 some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a>
@@ -8883,7 +8939,7 @@ some <b>caption</b> <a href="/wiki/Main_Page" title="Main Page">Main Page</a>
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
 <p><a href="/wiki/File:Foobar.jpg" title="File:Foobar.jpg">Foobar.jpg</a><br />
 </p>
@@ -8915,12 +8971,12 @@ foobar.jpg
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
                        </div>
                </div></li>
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
                        </div>
                </div></li>
@@ -9051,7 +9107,7 @@ Width + Height sized image (using px) (height is ignored)
 !! input
 [[Image:foobar.jpg|640x480px]]
 !! result
-<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="640" height="73" /></a>
+<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a>
 </p>
 !!end
 
@@ -9060,7 +9116,7 @@ Width-sized image (using px, no following whitespace)
 !! input
 [[Image:foobar.jpg|640px]]
 !! result
-<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="640" height="73" /></a>
+<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a>
 </p>
 !!end
 
@@ -9069,7 +9125,7 @@ Width-sized image (using px, with following whitespace - test regression from r3
 !! input
 [[Image:foobar.jpg|640px ]]
 !! result
-<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="640" height="73" /></a>
+<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a>
 </p>
 !!end
 
@@ -9078,7 +9134,7 @@ Width-sized image (using px, with preceding whitespace - test regression from r3
 !! input
 [[Image:foobar.jpg| 640px]]
 !! result
-<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="640" height="73" /></a>
+<p><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg" width="640" height="73" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/960px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/1280px-Foobar.jpg 2x" /></a>
 </p>
 !!end
 
@@ -9118,7 +9174,7 @@ Images with the "|" character in the comment
 !! input
 [[image:Foobar.jpg|thumb|An [http://test/?param1=|left|&param2=|x external] URL]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>An <a rel="nofollow" class="external text" href="http://test/?param1=%7Cleft%7C&amp;param2=%7Cx">external</a> URL</div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>An <a rel="nofollow" class="external text" href="http://test/?param1=%7Cleft%7C&amp;param2=%7Cx">external</a> URL</div></div></div>
 
 !!end
 
@@ -10112,7 +10168,7 @@ Free external link invading image caption
 !! input
 [[Image:Foobar.jpg|thumb|http://x|hello]]
 !! result
-<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>hello</div></div></div>
+<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>hello</div></div></div>
 
 !! end
 
@@ -11035,7 +11091,7 @@ File:foobar.jpg|caption|alt=galleryalt|link=InterWikiLink
 !! result
 <ul class="gallery">
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/InterWikiLink"><img alt="galleryalt" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/InterWikiLink"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
 <p>caption
 </p>
@@ -11054,7 +11110,7 @@ File:foobar.jpg|caption|alt=galleryalt|link=http://www.example.org
 !! result
 <ul class="gallery">
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="http://www.example.org"><img alt="galleryalt" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="http://www.example.org"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
 <p>caption
 </p>
@@ -11073,7 +11129,7 @@ File:foobar.jpg|caption|alt=galleryalt|link=" onclick="alert('malicious javascri
 !! result
 <ul class="gallery">
                <li class="gallerybox" style="width: 155px"><div style="width: 155px">
-                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/%22_onclick%3D%22alert(%27malicious_javascript_code!%27);"><img alt="galleryalt" src="http://example.com/images/3/3a/Foobar.jpg" width="120" height="14" /></a></div></div>
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="/wiki/%22_onclick%3D%22alert(%27malicious_javascript_code!%27);"><img alt="galleryalt" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div></div>
                        <div class="gallerytext">
 <p>caption
 </p>
@@ -11130,6 +11186,24 @@ HttP://MediaWiki.Org/
 </p>
 !! end
 
+###
+### Parsoids-specific tests
+### Parsoid-PHP parser incompatibilities
+###
+!!test
+1. SOL-sensitive wikitext tokens as template-args
+!!options
+disabled
+!!input
+{{echo|*a}}
+{{echo|#a}}
+{{echo|:a}}
+!!result
+<p>*a
+#a
+:a
+</p>
+!!end
 
 TODO:
 more images
index ff13702..9c2fb69 100644 (file)
@@ -666,4 +666,22 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
                }
        }
 
+       /**
+        * Returns true iff the given namespace defaults to Wikitext
+        * according to $wgNamespaceContentModels
+        *
+        * @param int $ns The namespace ID to check
+        *
+        * @return bool
+        * @since 1.21
+        */
+       protected function isWikitextNS( $ns ) {
+               global $wgNamespaceContentModels;
+
+               if ( isset( $wgNamespaceContentModels[$ns] ) ) {
+                       return $wgNamespaceContentModels[$ns] === CONTENT_MODEL_WIKITEXT;
+               }
+
+               return true;
+       }
 }
index ebbece2..4f79dfc 100644 (file)
@@ -16,7 +16,7 @@ class CssContentTest extends JavascriptContentTest {
        public function dataGetParserOutput() {
                return array(
                        array("MediaWiki:Test.css", null, "hello <world>\n",
-                               "<pre class=\"mw-code mw-css\" dir=\"ltr\">\nhello &lt;world&gt;\n\n</pre>\n"),
+                               "<pre class=\"mw-code mw-css\" dir=\"ltr\">\nhello &lt;world&gt;\n\n</pre>"),
                        // @todo: more...?
                );
        }
index 4d53d06..e8aabfd 100644 (file)
@@ -317,29 +317,28 @@ class GlobalTest extends MediaWikiTestCase {
                }
                
        }
-       
-       
+
+
        function testDebugFunctionTest() {
-       
+
                global $wgDebugLogFile, $wgDebugTimestamps;
-               
+
                $old_log_file = $wgDebugLogFile;
                $wgDebugLogFile = tempnam( wfTempDir(), 'mw-' );
-               # @todo FIXME: This setting should be tested
+               # @todo FIXME: $wgDebugTimestamps should be tested
+               $old_wgDebugTimestamps = $wgDebugTimestamps;
                $wgDebugTimestamps = false;
-               
-               
-               
+
+
                wfDebug( "This is a normal string" );
                $this->assertEquals( "This is a normal string", file_get_contents( $wgDebugLogFile ) );
                unlink( $wgDebugLogFile );
-               
-               
+
                wfDebug( "This is nöt an ASCII string" );
                $this->assertEquals( "This is nöt an ASCII string", file_get_contents( $wgDebugLogFile ) );
                unlink( $wgDebugLogFile );
-               
-               
+
+
                wfDebug( "\00305This has böth UTF and control chars\003" );
                $this->assertEquals( " 05This has böth UTF and control chars ", file_get_contents( $wgDebugLogFile ) );
                unlink( $wgDebugLogFile );
@@ -347,17 +346,16 @@ class GlobalTest extends MediaWikiTestCase {
                wfDebugMem();
                $this->assertGreaterThan( 5000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
                unlink( $wgDebugLogFile );
-               
+
                wfDebugMem(true);
                $this->assertGreaterThan( 5000000, preg_replace( '/\D/', '', file_get_contents( $wgDebugLogFile ) ) );
                unlink( $wgDebugLogFile );
-               
-               
-               
+
+
                $wgDebugLogFile = $old_log_file;
-               
+               $wgDebugTimestamps = $old_wgDebugTimestamps;
        }
-       
+
        function testClientAcceptsGzipTest() {
                
                $settings = array(
index a3b75d1..b45caa2 100644 (file)
@@ -6,7 +6,7 @@
  * @group Database
  *        ^--- needed, because we do need the database to test link updates
  */
-class JavascriptContentTest extends WikitextContentTest {
+class JavascriptContentTest extends TextContentTest {
 
        public function newContent( $text ) {
                return new JavascriptContent( $text );
@@ -16,7 +16,7 @@ class JavascriptContentTest extends WikitextContentTest {
        public function dataGetParserOutput() {
                return array(
                        array("MediaWiki:Test.js", null, "hello <world>\n",
-                                       "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello &lt;world&gt;\n\n</pre>\n"),
+                                       "<pre class=\"mw-code mw-js\" dir=\"ltr\">\nhello &lt;world&gt;\n\n</pre>"),
                        // @todo: more...?
                );
        }
@@ -81,18 +81,16 @@ class JavascriptContentTest extends WikitextContentTest {
        }
 
        // XXX: currently, preSaveTransform is applied to scripts. this may change or become optional.
-       /*
        public function dataPreSaveTransform() {
                return array(
                        array( 'hello this is ~~~',
-                              "hello this is ~~~",
+                               "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
                        ),
                        array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
-                              'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
+                               'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
                        ),
                );
        }
-       */
 
        public function dataPreloadTransform() {
                return array(
diff --git a/tests/phpunit/includes/TextContentTest.php b/tests/phpunit/includes/TextContentTest.php
new file mode 100644 (file)
index 0000000..ee17a75
--- /dev/null
@@ -0,0 +1,348 @@
+<?php
+
+/**
+ * @group ContentHandler
+ *
+ * @group Database
+ *        ^--- needed, because we do need the database to test link updates
+ */
+class TextContentTest extends MediaWikiTestCase {
+
+       public function setup() {
+               global $wgUser;
+
+               // anon user
+               $wgUser = new User();
+               $wgUser->setName( '127.0.0.1' );
+
+               $this->context = new RequestContext( new FauxRequest() );
+               $this->context->setTitle( Title::newFromText( "Test" ) );
+               $this->context->setUser( $wgUser );
+       }
+
+       public function newContent( $text ) {
+               return new TextContent( $text );
+       }
+
+
+       public function dataGetParserOutput() {
+               return array(
+                       array("TextContentTest_testGetParserOutput", CONTENT_MODEL_TEXT, "hello ''world'' & stuff\n", "hello ''world'' &amp; stuff"),
+                       // @todo: more...?
+               );
+       }
+
+       /**
+        * @dataProvider dataGetParserOutput
+        */
+       public function testGetParserOutput( $title, $model, $text, $expectedHtml ) {
+               $title = Title::newFromText( $title );
+               $content = ContentHandler::makeContent( $text, $title, $model );
+
+               $po = $content->getParserOutput( $title );
+
+               $html = $po->getText();
+               $html = preg_replace( '#<!--.*?-->#sm', '', $html ); // strip comments
+
+               $this->assertEquals( $expectedHtml, trim( $html ) );
+               // @todo: assert more properties
+       }
+
+       public function dataPreSaveTransform() {
+               return array(
+                       array( 'hello this is ~~~',
+                              "hello this is ~~~",
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider dataPreSaveTransform
+        */
+       public function testPreSaveTransform( $text, $expected ) {
+               global $wgContLang;
+
+               $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
+
+               $content = $this->newContent( $text );
+               $content = $content->preSaveTransform( $this->context->getTitle(), $this->context->getUser(), $options );
+
+               $this->assertEquals( $expected, $content->getNativeData() );
+       }
+
+       public function dataPreloadTransform() {
+               return array(
+                       array( 'hello this is ~~~',
+                              "hello this is ~~~",
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider dataPreloadTransform
+        */
+       public function testPreloadTransform( $text, $expected ) {
+               global $wgContLang;
+               $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
+
+               $content = $this->newContent( $text );
+               $content = $content->preloadTransform( $this->context->getTitle(), $options );
+
+               $this->assertEquals( $expected, $content->getNativeData() );
+       }
+
+       public function dataGetRedirectTarget() {
+               return array(
+                       array( '#REDIRECT [[Test]]',
+                               null,
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider dataGetRedirectTarget
+        */
+       public function testGetRedirectTarget( $text, $expected ) {
+               $content = $this->newContent( $text );
+               $t = $content->getRedirectTarget( );
+
+               if ( is_null( $expected ) ) {
+                       $this->assertNull( $t, "text should not have generated a redirect target: $text" );
+               } else {
+                       $this->assertEquals( $expected, $t->getPrefixedText() );
+               }
+       }
+
+       /**
+        * @dataProvider dataGetRedirectTarget
+        */
+       public function isRedirect( $text, $expected ) {
+               $content = $this->newContent( $text );
+
+               $this->assertEquals( !is_null($expected), $content->isRedirect() );
+       }
+
+
+       /**
+        * @todo: test needs database! Should be done by a test class in the Database group.
+        */
+       /*
+       public function getRedirectChain() {
+               $text = $this->getNativeData();
+               return Title::newFromRedirectArray( $text );
+       }
+       */
+
+       /**
+        * @todo: test needs database! Should be done by a test class in the Database group.
+        */
+       /*
+       public function getUltimateRedirectTarget() {
+               $text = $this->getNativeData();
+               return Title::newFromRedirectRecurse( $text );
+       }
+       */
+
+
+       public function dataIsCountable() {
+               return array(
+                       array( '',
+                              null,
+                              'any',
+                              true
+                       ),
+                       array( 'Foo',
+                              null,
+                              'any',
+                              true
+                       ),
+                       array( 'Foo',
+                              null,
+                              'comma',
+                              false
+                       ),
+                       array( 'Foo, bar',
+                              null,
+                              'comma',
+                              false
+                       ),
+               );
+       }
+
+
+       /**
+        * @dataProvider dataIsCountable
+        * @group Database
+        */
+       public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
+               global $wgArticleCountMethod;
+
+               $old = $wgArticleCountMethod;
+               $wgArticleCountMethod = $mode;
+
+               $content = $this->newContent( $text );
+
+               $v = $content->isCountable( $hasLinks, $this->context->getTitle() );
+               $wgArticleCountMethod = $old;
+
+               $this->assertEquals( $expected, $v, "isCountable() returned unexpected value " . var_export( $v, true )
+                                                   . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
+       }
+
+       public function dataGetTextForSummary() {
+               return array(
+                       array( "hello\nworld.",
+                              16,
+                              'hello world.',
+                       ),
+                       array( 'hello world.',
+                              8,
+                              'hello...',
+                       ),
+                       array( '[[hello world]].',
+                              8,
+                              '[[hel...',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider dataGetTextForSummary
+        */
+       public function testGetTextForSummary( $text, $maxlength, $expected ) {
+               $content = $this->newContent( $text );
+
+               $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
+       }
+
+
+       public function testGetTextForSearchIndex( ) {
+               $content = $this->newContent( "hello world." );
+
+               $this->assertEquals( "hello world.", $content->getTextForSearchIndex() );
+       }
+
+       public function testCopy() {
+               $content = $this->newContent( "hello world." );
+               $copy = $content->copy();
+
+               $this->assertTrue( $content->equals( $copy ), "copy must be equal to original" );
+               $this->assertEquals( "hello world.", $copy->getNativeData() );
+       }
+
+       public function testGetSize( ) {
+               $content = $this->newContent( "hello world." );
+
+               $this->assertEquals( 12, $content->getSize() );
+       }
+
+       public function testGetNativeData( ) {
+               $content = $this->newContent( "hello world." );
+
+               $this->assertEquals( "hello world.", $content->getNativeData() );
+       }
+
+       public function testGetWikitextForTransclusion( ) {
+               $content = $this->newContent( "hello world." );
+
+               $this->assertEquals( "hello world.", $content->getWikitextForTransclusion() );
+       }
+
+       # =================================================================================================================
+
+       public function testGetModel() {
+               $content = $this->newContent( "hello world." );
+
+               $this->assertEquals( CONTENT_MODEL_TEXT, $content->getModel() );
+       }
+
+       public function testGetContentHandler() {
+               $content = $this->newContent( "hello world." );
+
+               $this->assertEquals( CONTENT_MODEL_TEXT, $content->getContentHandler()->getModelID() );
+       }
+
+       public function dataIsEmpty( ) {
+               return array(
+                       array( '', true ),
+                       array( '  ', false ),
+                       array( '0', false ),
+                       array( 'hallo welt.', false ),
+               );
+       }
+
+       /**
+        * @dataProvider dataIsEmpty
+        */
+       public function testIsEmpty( $text, $empty ) {
+               $content = $this->newContent( $text );
+
+               $this->assertEquals( $empty, $content->isEmpty() );
+       }
+
+       public function dataEquals( ) {
+               return array(
+                       array( new TextContent( "hallo" ), null, false ),
+                       array( new TextContent( "hallo" ), new TextContent( "hallo" ), true ),
+                       array( new TextContent( "hallo" ), new JavascriptContent( "hallo" ), false ),
+                       array( new TextContent( "hallo" ), new WikitextContent( "hallo" ), false ),
+                       array( new TextContent( "hallo" ), new TextContent( "HALLO" ), false ),
+               );
+       }
+
+       /**
+        * @dataProvider dataEquals
+        */
+       public function testEquals( Content $a, Content $b = null, $equal = false ) {
+               $this->assertEquals( $equal, $a->equals( $b ) );
+       }
+
+       public function dataGetDeletionUpdates() {
+               return array(
+                       array("TextContentTest_testGetSecondaryDataUpdates_1",
+                               CONTENT_MODEL_TEXT, "hello ''world''\n",
+                               array( )
+                       ),
+                       array("TextContentTest_testGetSecondaryDataUpdates_2",
+                               CONTENT_MODEL_TEXT, "hello [[world test 21344]]\n",
+                               array( )
+                       ),
+                       // @todo: more...?
+               );
+       }
+
+       /**
+        * @dataProvider dataGetDeletionUpdates
+        */
+       public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) {
+               $title = Title::newFromText( $title );
+               $title->resetArticleID( 2342 ); //dummy id. fine as long as we don't try to execute the updates!
+
+               $content = ContentHandler::makeContent( $text, $title, $model );
+
+               $updates = $content->getDeletionUpdates( WikiPage::factory( $title ) );
+
+               // make updates accessible by class name
+               foreach ( $updates as $update ) {
+                       $class = get_class( $update );
+                       $updates[ $class ] = $update;
+               }
+
+               if ( !$expectedStuff ) {
+                       $this->assertTrue( true ); // make phpunit happy
+                       return;
+               }
+
+               foreach ( $expectedStuff as $class => $fieldValues ) {
+                       $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
+
+                       $update = $updates[ $class ];
+
+                       foreach ( $fieldValues as $field => $value ) {
+                               $v = $update->$field; #if the field doesn't exist, just crash and burn
+                               $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
+                       }
+               }
+       }
+
+}
index 5df8fe1..f7387e1 100644 (file)
@@ -236,30 +236,35 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ),
                        array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ) );
 
-               $this->setTitle( NS_MAIN );
-               $this->setUser( 'anon' );
-               $this->setUserPerm( "move" );
-               $this->runGroupPermissions( 'move', array(  ) );
-
-               $this->setUserPerm( "" );
-               $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ),
-                       array( array( 'movenologintext' ) ) );
-
-               $this->setUser( $this->userName );
-               $this->setUserPerm( "" );
-               $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) );
-
-               $this->setUserPerm( "move" );
-               $this->runGroupPermissions( 'move', array( ) );
-
-               $this->setUser( 'anon' );
-               $this->setUserPerm( 'move' );
-               $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( ), $res );
-
-               $this->setUserPerm( '' );
-               $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
-               $this->assertEquals( array( array( 'movenotallowed' ) ), $res );
+               if ( $this->isWikitextNS( NS_MAIN ) ) {
+                       //NOTE: some content models don't allow moving
+                       //@todo: find a Wikitext namespace for testing
+
+                       $this->setTitle( NS_MAIN );
+                       $this->setUser( 'anon' );
+                       $this->setUserPerm( "move" );
+                       $this->runGroupPermissions( 'move', array(  ) );
+
+                       $this->setUserPerm( "" );
+                       $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ),
+                               array( array( 'movenologintext' ) ) );
+
+                       $this->setUser( $this->userName );
+                       $this->setUserPerm( "" );
+                       $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) );
+
+                       $this->setUserPerm( "move" );
+                       $this->runGroupPermissions( 'move', array( ) );
+
+                       $this->setUser( 'anon' );
+                       $this->setUserPerm( 'move' );
+                       $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
+                       $this->assertEquals( array( ), $res );
+
+                       $this->setUserPerm( '' );
+                       $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
+                       $this->assertEquals( array( array( 'movenotallowed' ) ), $res );
+               }
 
                $this->setTitle( NS_USER );
                $this->setUser( $this->userName );
@@ -582,7 +587,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ),
                                                         $this->title->getUserPermissionsErrors( 'move', $this->user ) );
 
-               $this->setTitle( NS_MAIN, "test page" );
+               $this->setTitle( NS_HELP, "test page" );
                $this->assertEquals( array( ),
                                                         $this->title->getUserPermissionsErrors( 'move', $this->user ) );
                $this->assertEquals( true,
@@ -600,7 +605,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ),
                                                         $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
 
-               $this->setTitle( NS_MAIN, "test page" );
+               $this->setTitle( NS_HELP, "test page" );
                $this->assertEquals( array( ),
                                                         $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
                $this->assertEquals( true,
@@ -621,7 +626,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                $wgUser = $this->user;
 
                $this->setUserPerm( array( "createpage", "move" ) );
-               $this->setTitle( NS_MAIN, "test page" );
+               $this->setTitle( NS_HELP, "test page" );
 
                # $short
                $this->assertEquals( array( array( 'confirmedittext' ) ),
index cf9b96b..fa91452 100644 (file)
@@ -590,6 +590,21 @@ class WikiPageTest extends MediaWikiLangTestCase {
                return $po;
        }
 
+       /**
+        * @dataProvider provideGetParserOutput
+        */
+       public function testGetParserOutput_nonexisting( ) {
+               static $count = 0;
+               $count ++;
+
+               $page = new WikiPage( new Title( "testGetParserOutput_nonexisting_$count" ) );
+
+               $opt = new ParserOptions();
+               $po = $page->getParserOutput( $opt );
+
+               $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
+       }
+
        static $sections =
 
                "Intro
index dac8041..b2d3bdf 100644 (file)
@@ -6,25 +6,12 @@
  * @group Database
  *        ^--- needed, because we do need the database to test link updates
  */
-class WikitextContentTest extends MediaWikiTestCase {
-
-       public function setup() {
-               global $wgUser;
-
-               // anon user
-               $wgUser = new User();
-               $wgUser->setName( '127.0.0.1' );
-
-               $this->context = new RequestContext( new FauxRequest() );
-               $this->context->setTitle( Title::newFromText( "Test" ) );
-               $this->context->setUser( $wgUser );
-       }
+class WikitextContentTest extends TextContentTest {
 
        public function newContent( $text ) {
                return new WikitextContent( $text );
        }
 
-
        public function dataGetParserOutput() {
                return array(
                        array("WikitextContentTest_testGetParserOutput", CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i>\n</p>"),
@@ -32,19 +19,6 @@ class WikitextContentTest extends MediaWikiTestCase {
                );
        }
 
-       /**
-        * @dataProvider dataGetParserOutput
-        */
-       public function testGetParserOutput( $title, $model, $text, $expectedHtml ) {
-               $title = Title::newFromText( $title );
-               $content = ContentHandler::makeContent( $text, $title, $model );
-
-               $po = $content->getParserOutput( $title );
-
-               $this->assertEquals( $expectedHtml, $po->getText() );
-               // @todo: assert more properties
-       }
-
        public function dataGetSecondaryDataUpdates() {
                return array(
                        array("WikitextContentTest_testGetSecondaryDataUpdates_1",
@@ -131,8 +105,13 @@ just a test"
                $content = $this->newContent( $text );
 
                $sectionContent = $content->getSection( $sectionId );
+               if ( is_object( $sectionContent ) ) {
+                       $sectionText = $sectionContent->getNativeData();
+               } else {
+                       $sectionText = $sectionContent;
+               }
 
-               $this->assertEquals( $expectedText, is_null( $sectionContent ) ? null : $sectionContent->getNativeData() );
+               $this->assertEquals( $expectedText, $sectionText );
        }
 
        public function dataReplaceSection() {
@@ -198,20 +177,6 @@ just a test"
                );
        }
 
-       /**
-        * @dataProvider dataPreSaveTransform
-        */
-       public function testPreSaveTransform( $text, $expected ) {
-               global $wgContLang;
-
-               $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
-
-               $content = $this->newContent( $text );
-               $content = $content->preSaveTransform( $this->context->getTitle(), $this->context->getUser(), $options );
-
-               $this->assertEquals( $expected, $content->getNativeData() );
-       }
-
        public function dataPreloadTransform() {
                return array(
                        array( 'hello this is ~~~',
@@ -223,19 +188,6 @@ just a test"
                );
        }
 
-       /**
-        * @dataProvider dataPreloadTransform
-        */
-       public function testPreloadTransform( $text, $expected ) {
-               global $wgContLang;
-               $options = ParserOptions::newFromUserAndLang( $this->context->getUser(), $wgContLang );
-
-               $content = $this->newContent( $text );
-               $content = $content->preloadTransform( $this->context->getTitle(), $options );
-
-               $this->assertEquals( $expected, $content->getNativeData() );
-       }
-
        public function dataGetRedirectTarget() {
                return array(
                        array( '#REDIRECT [[Test]]',
@@ -250,30 +202,23 @@ just a test"
                );
        }
 
-       /**
-        * @dataProvider dataGetRedirectTarget
-        */
-       public function testGetRedirectTarget( $text, $expected ) {
-               $content = $this->newContent( $text );
-               $t = $content->getRedirectTarget( );
-
-               if ( is_null( $expected ) ) {
-                       $this->assertNull( $t, "text should not have generated a redirect target: $text" );
-               } else {
-                       $this->assertEquals( $expected, $t->getPrefixedText() );
-               }
-       }
-
-       /**
-        * @dataProvider dataGetRedirectTarget
-        */
-       public function isRedirect( $text, $expected ) {
-               $content = $this->newContent( $text );
-
-               $this->assertEquals( !is_null($expected), $content->isRedirect() );
+       public function dataGetTextForSummary() {
+               return array(
+                       array( "hello\nworld.",
+                               16,
+                               'hello world.',
+                       ),
+                       array( 'hello world.',
+                               8,
+                               'hello...',
+                       ),
+                       array( '[[hello world]].',
+                               8,
+                               'hel...',
+                       ),
+               );
        }
 
-
        /**
         * @todo: test needs database! Should be done by a test class in the Database group.
         */
@@ -355,85 +300,6 @@ just a test"
                );
        }
 
-
-       /**
-        * @dataProvider dataIsCountable
-        * @group Database
-        */
-       public function testIsCountable( $text, $hasLinks, $mode, $expected ) {
-               global $wgArticleCountMethod;
-
-               $old = $wgArticleCountMethod;
-               $wgArticleCountMethod = $mode;
-
-               $content = $this->newContent( $text );
-
-               $v = $content->isCountable( $hasLinks, $this->context->getTitle() );
-               $wgArticleCountMethod = $old;
-
-               $this->assertEquals( $expected, $v, "isCountable() returned unexpected value " . var_export( $v, true )
-                                                   . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
-       }
-
-       public function dataGetTextForSummary() {
-               return array(
-                       array( "hello\nworld.",
-                              16,
-                              'hello world.',
-                       ),
-                       array( 'hello world.',
-                              8,
-                              'hello...',
-                       ),
-                       array( '[[hello world]].',
-                              8,
-                              'hel...',
-                       ),
-               );
-       }
-
-       /**
-        * @dataProvider dataGetTextForSummary
-        */
-       public function testGetTextForSummary( $text, $maxlength, $expected ) {
-               $content = $this->newContent( $text );
-
-               $this->assertEquals( $expected, $content->getTextForSummary( $maxlength ) );
-       }
-
-
-       public function testGetTextForSearchIndex( ) {
-               $content = $this->newContent( "hello world." );
-
-               $this->assertEquals( "hello world.", $content->getTextForSearchIndex() );
-       }
-
-       public function testCopy() {
-               $content = $this->newContent( "hello world." );
-               $copy = $content->copy();
-
-               $this->assertTrue( $content->equals( $copy ), "copy must be equal to original" );
-               $this->assertEquals( "hello world.", $copy->getNativeData() );
-       }
-
-       public function testGetSize( ) {
-               $content = $this->newContent( "hello world." );
-
-               $this->assertEquals( 12, $content->getSize() );
-       }
-
-       public function testGetNativeData( ) {
-               $content = $this->newContent( "hello world." );
-
-               $this->assertEquals( "hello world.", $content->getNativeData() );
-       }
-
-       public function testGetWikitextForTransclusion( ) {
-               $content = $this->newContent( "hello world." );
-
-               $this->assertEquals( "hello world.", $content->getWikitextForTransclusion() );
-       }
-
        public function testMatchMagicWord( ) {
                $mw = MagicWord::get( "staticredirect" );
 
@@ -477,40 +343,16 @@ just a test"
                $this->assertEquals( CONTENT_MODEL_WIKITEXT, $content->getContentHandler()->getModelID() );
        }
 
-       public function dataIsEmpty( ) {
-               return array(
-                       array( '', true ),
-                       array( '  ', false ),
-                       array( '0', false ),
-                       array( 'hallo welt.', false ),
-               );
-       }
-
-       /**
-        * @dataProvider dataIsEmpty
-        */
-       public function testIsEmpty( $text, $empty ) {
-               $content = $this->newContent( $text );
-
-               $this->assertEquals( $empty, $content->isEmpty() );
-       }
-
        public function dataEquals( ) {
                return array(
                        array( new WikitextContent( "hallo" ), null, false ),
                        array( new WikitextContent( "hallo" ), new WikitextContent( "hallo" ), true ),
                        array( new WikitextContent( "hallo" ), new JavascriptContent( "hallo" ), false ),
+                       array( new WikitextContent( "hallo" ), new TextContent( "hallo" ), false ),
                        array( new WikitextContent( "hallo" ), new WikitextContent( "HALLO" ), false ),
                );
        }
 
-       /**
-        * @dataProvider dataEquals
-        */
-       public function testEquals( Content $a, Content $b = null, $equal = false ) {
-               $this->assertEquals( $equal, $a->equals( $b ) );
-       }
-
        public function dataGetDeletionUpdates() {
                return array(
                        array("WikitextContentTest_testGetSecondaryDataUpdates_1",
@@ -525,33 +367,4 @@ just a test"
                );
        }
 
-       /**
-        * @dataProvider dataGetDeletionUpdates
-        */
-       public function testDeletionUpdates( $title, $model, $text, $expectedStuff ) {
-               $title = Title::newFromText( $title );
-               $title->resetArticleID( 2342 ); //dummy id. fine as long as we don't try to execute the updates!
-
-               $content = ContentHandler::makeContent( $text, $title, $model );
-
-               $updates = $content->getDeletionUpdates( WikiPage::factory( $title ) );
-
-               // make updates accessible by class name
-               foreach ( $updates as $update ) {
-                       $class = get_class( $update );
-                       $updates[ $class ] = $update;
-               }
-
-               foreach ( $expectedStuff as $class => $fieldValues ) {
-                       $this->assertArrayHasKey( $class, $updates, "missing an update of type $class" );
-
-                       $update = $updates[ $class ];
-
-                       foreach ( $fieldValues as $field => $value ) {
-                               $v = $update->$field; #if the field doesn't exist, just crash and burn
-                               $this->assertEquals( $value, $v, "unexpected value for field $field in instance of $class" );
-                       }
-               }
-       }
-
 }
diff --git a/tests/phpunit/includes/api/ApiGeneratorTest.php b/tests/phpunit/includes/api/ApiGeneratorTest.php
new file mode 100644 (file)
index 0000000..60ae608
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+class ApiGeneratorTest extends MediaWikiTestCase {
+
+       /**
+        * Helper to easily get an ApiQuery object instance
+        */
+       function getApiQuery() {
+               // Initialize an ApiQuery object to play with
+               $main = new ApiMain( new FauxRequest() );
+               return new ApiQuery( $main, 'foo', 'bar' );
+       }
+
+       /**
+        * Test whether all registered query modules which are subclasses of
+        * ApiQueryGeneratorBase are listed as being a generator. Registration is
+        * done:
+        *  - for core: add it to ApiQuery::$mQueryGenerators
+        *  - for extension: by adding to $wgAPIGeneratorModules
+        *
+        * @dataProvider provideApiquerygeneratorbaseChilds
+        */
+       public function testApiquerygeneatorbaseModulesListedAsGenerators(
+               $moduleName, $moduleClass
+       ) {
+               $generators = $this->getApiQuery()->getGenerators();
+               $this->assertArrayHasKey( $moduleName, $generators,
+                       "API module '$moduleName' of class '$moduleClass' (an ApiQueryGeneratorBase subclass) must be listed in ApiQuery::\$mQueryGenerators or added to \$wgAPIGeneratorModules."
+               );
+       }
+
+       /**
+        * Returns API modules which are subclassing ApiQueryGeneratorBase.
+        * Case format is:
+        *      (moduleName, moduleClass)
+        */
+       public function provideApiquerygeneratorbaseChilds() {
+               $cases = array();
+               $modules = $this->getApiQuery()->getModules();
+               foreach( $modules as $moduleName => $moduleClass ) {
+                       if( !is_subclass_of( $moduleClass, 'ApiQueryGeneratorBase' ) ) {
+                               continue;
+                       }
+                       $cases[] = array( $moduleName, $moduleClass );
+               }
+               return $cases;
+       }
+
+       /**
+        * @dataProvider provideListedApiqueryGenerators
+        */
+       public function testGeneratorsAreApiquerygeneratorbaseSubclasses(
+               $generatorName, $generatorClass
+       ) {
+               $modules = $this->getApiQuery()->getModules();
+               $this->assertArrayHasKey( $generatorName, $modules,
+                       "Class '$generatorClass' of generator '$generatorName' must be a subclass of 'ApiQueryGeneratorBase'. Listed either in ApiQuery::\$mQueryGenerators or in \$wgAPIGeneratorModules."
+               );
+
+       }
+
+       /**
+        * Return ApiQuery generators, either listed in ApiQuery or registered
+        * via wgAPIGeneratorModules.
+        * Case format is:
+        *  (moduleName, $moduleClass).
+        */
+       public function provideListedApiqueryGenerators() {
+               $cases = array();
+               $generators = $this->getApiQuery()->getGenerators();
+               foreach( $generators as $generatorName => $generatorClass ) {
+                       $cases[] = array( $generatorName, $generatorClass );
+               }
+               return $cases;
+       }
+
+}
index 70fce11..398ad2d 100644 (file)
@@ -58,7 +58,7 @@ abstract class GenericArrayObjectTest extends MediaWikiTestCase {
                $instances = array();
 
                foreach ( $this->elementInstancesProvider() as $elementInstances ) {
-                       $instances[] = $this->getNew( $elementInstances );
+                       $instances[] = $this->getNew( $elementInstances[0] );
                }
 
                return $this->arrayWrap( $instances );
index 848991e..804726b 100644 (file)
@@ -303,7 +303,7 @@ class NewParserTest extends MediaWikiTestCase {
                        'wgNoFollowLinks' => true,
                        'wgNoFollowDomainExceptions' => array(),
                        'wgThumbnailScriptPath' => false,
-                       'wgUseImageResize' => false,
+                       'wgUseImageResize' => true,
                        'wgUseTeX' => isset( $opts['math'] ),
                        'wgMathDirectory' => $uploadDir . '/math',
                        'wgLocaltimezone' => 'UTC',
@@ -524,6 +524,14 @@ class NewParserTest extends MediaWikiTestCase {
                        return;
                }
 
+               if ( !$this->isWikitextNS( NS_MAIN ) ) {
+                       // parser tests frequently assume that the main namespace contains wikitext.
+                       // @todo: When setting up pages, force the content model. Only skip if
+                       //        $wgtContentModelUseDB is false.
+                       $this->markTestSkipped( "Main namespace does not support wikitext,"
+                                       . "skipping parser test: $desc" );
+               }
+
                wfDebug( "Running parser test: $desc\n" );
 
                $opts = $this->parseOptions( $opts );
index 879e41f..395e1a0 100644 (file)
@@ -40,6 +40,12 @@ class SearchEngineTest extends MediaWikiTestCase {
                if ( $this->pageExists( 'Not_Main_Page' ) ) {
                        return;
                }
+
+               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( 'Talk:Not_Main_Page',        'This is not a talk page to the main page, see [[smithee]]', 1 );
                $this->insertPage( 'Smithee',   'A smithee is one who smiths. See also [[Alan Smithee]]', 0 );
@@ -60,6 +66,11 @@ class SearchEngineTest extends MediaWikiTestCase {
        }
 
        function fetchIds( $results ) {
+               if ( !$this->isWikitextNS( NS_MAIN ) ) {
+                       $this->markTestIncomplete( __CLASS__ . " does no yet support non-wikitext content "
+                               . "in the main namespace");
+               }
+
                $this->assertTrue( is_object( $results ) );
 
                $matches = array();
@@ -84,7 +95,7 @@ class SearchEngineTest extends MediaWikiTestCase {
         * @param $n Integer: unused
         */
        function insertPage( $pageName, $text, $ns ) {
-               $title = Title::newFromText( $pageName );
+               $title = Title::newFromText( $pageName, $ns );
 
                $user = User::newFromName( 'WikiSysop' );
                $comment = 'Search Test';
diff --git a/tests/phpunit/includes/site/MediaWikiSiteTest.php b/tests/phpunit/includes/site/MediaWikiSiteTest.php
new file mode 100644 (file)
index 0000000..208ab1e
--- /dev/null
@@ -0,0 +1,108 @@
+<?php
+
+/**
+ * Tests for the MediaWikiSite class.
+ *
+ * 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
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ * @group Database
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class MediaWikiSiteTest extends SiteObjectTest {
+
+       public function setUp() {
+               parent::setUp();
+
+               static $hasSites = false;
+
+               if ( !$hasSites ) {
+                       TestSites::insertIntoDb();
+                       $hasSites = true;
+               }
+       }
+
+       public function testFactoryConstruction() {
+               $this->assertInstanceOf( 'MediaWikiSite', MediaWikiSite::newFromGlobalId( 'enwiki' ) );
+               $this->assertInstanceOf( 'Site', MediaWikiSite::newFromGlobalId( 'enwiki' ) );
+               $this->assertInstanceOf( 'MediaWikiSite', SitesTable::singleton()->newRow( array( 'type' => Site::TYPE_MEDIAWIKI ) ) );
+       }
+
+       public function testNormalizePageTitle() {
+               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
+
+               //NOTE: this does not actually call out to the enwiki site to perform the normalization,
+               //      but uses a local Title object to do so. This is hardcoded on SiteLink::normalizePageTitle
+               //      for the case that MW_PHPUNIT_TEST is set.
+               $this->assertEquals( 'Foo', $site->normalizePageName( ' foo ' ) );
+       }
+
+       public function fileUrlProvider() {
+               return array(
+                       // url, filepath, path arg, expected
+                       array( 'https://en.wikipedia.org', '/w/$1', 'api.php', 'https://en.wikipedia.org/w/api.php' ),
+                       array( 'https://en.wikipedia.org', '/w/', 'api.php', 'https://en.wikipedia.org/w/' ),
+                       array( 'https://en.wikipedia.org', '/foo/page.php?name=$1', 'api.php', 'https://en.wikipedia.org/foo/page.php?name=api.php' ),
+                       array( 'https://en.wikipedia.org', '/w/$1', '', 'https://en.wikipedia.org/w/' ),
+                       array( 'https://en.wikipedia.org', '/w/$1', 'foo/bar/api.php', 'https://en.wikipedia.org/w/foo/bar/api.php' ),
+               );
+       }
+
+       /**
+        * @dataProvider fileUrlProvider
+        */
+       public function testGetFileUrl( $url, $filePath, $pathArgument, $expected ) {
+               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
+
+               $site->setFilePath( $url . $filePath );
+
+               $this->assertEquals( $expected, $site->getFileUrl( $pathArgument ) );
+       }
+
+       public function provideGetPageUrl() {
+               return array(
+                       // path, page, expected substring
+                       array( 'http://acme.test/wiki/$1', 'Berlin', '/wiki/Berlin' ),
+                       array( 'http://acme.test/wiki/', 'Berlin', '/wiki/' ),
+                       array( 'http://acme.test/w/index.php?title=$1', 'Berlin', '/w/index.php?title=Berlin' ),
+                       array( 'http://acme.test/wiki/$1', '', '/wiki/' ),
+                       array( 'http://acme.test/wiki/$1', 'Berlin/sub page', '/wiki/Berlin/sub_page' ),
+                       array( 'http://acme.test/wiki/$1', 'Cork (city)   ', '/Cork_(city)' ),
+                       array( 'http://acme.test/wiki/$1', 'M&M', '/wiki/M%26M' ),
+               );
+       }
+
+       /**
+        * @dataProvider provideGetPageUrl
+        */
+       public function testGetPageUrl( $path, $page, $expected ) {
+               /* @var MediaWikiSite $site */
+               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
+
+               $site->setLinkPath( $path );
+               $this->assertContains( $path, $site->getPageUrl() );
+               $this->assertContains( $expected, $site->getPageUrl( $page ) );
+       }
+
+}
diff --git a/tests/phpunit/includes/site/SiteArrayTest.php b/tests/phpunit/includes/site/SiteArrayTest.php
new file mode 100644 (file)
index 0000000..021691a
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * Tests for the SiteArray class.
+ * The tests for methods defined in the SiteList interface are in SiteListTest.
+ *
+ * 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
+ *Both
+ * Bith
+ * @file
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteArrayTest extends GenericArrayObjectTest {
+
+       /**
+        * @see GenericArrayObjectTest::elementInstancesProvider
+        *
+        * @since 1.21
+        *
+        * @return array
+        */
+       public function elementInstancesProvider() {
+               $sites = TestSites::getSites();
+
+               $siteArrays = array();
+
+               $siteArrays[] = $sites;
+
+               $siteArrays[] = array( array_shift( $sites ) );
+
+               $siteArrays[] = array( array_shift( $sites ), array_shift( $sites ) );
+
+               return $this->arrayWrap( $siteArrays );
+       }
+
+       /**
+        * @see GenericArrayObjectTest::getInstanceClass
+        *
+        * @since 1.21
+        *
+        * @return array
+        */
+       public function getInstanceClass() {
+               return 'SiteArray';
+       }
+
+}
\ No newline at end of file
diff --git a/tests/phpunit/includes/site/SiteListTest.php b/tests/phpunit/includes/site/SiteListTest.php
new file mode 100644 (file)
index 0000000..bb8367f
--- /dev/null
@@ -0,0 +1,168 @@
+<?php
+
+/**
+ * Tests for the SiteList implementing classes.
+ *
+ * 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
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteListTest extends MediaWikiTestCase {
+
+       /**
+        * Returns instances of SiteList implementing objects.
+        * @return array
+        */
+       public function siteListProvider() {
+               $sitesArrays = $this->siteArrayProvider();
+
+               $listInstances = array();
+
+               foreach ( $sitesArrays as $sitesArray ) {
+                       $listInstances[] = new SiteArray( $sitesArray[0] );
+               }
+
+               return $this->arrayWrap( $listInstances );
+       }
+
+       /**
+        * Returns arrays with instances of Site implementing objects.
+        * @return array
+        */
+       public function siteArrayProvider() {
+               $sites = TestSites::getSites();
+
+               $siteArrays = array();
+
+               $siteArrays[] = $sites;
+
+               $siteArrays[] = array( array_shift( $sites ) );
+
+               $siteArrays[] = array( array_shift( $sites ), array_shift( $sites ) );
+
+               return $this->arrayWrap( $siteArrays );
+       }
+
+       /**
+        * @dataProvider siteListProvider
+        * @param SiteList $sites
+        */
+       public function testIsEmpty( SiteList $sites ) {
+               $this->assertEquals( count( $sites ) === 0, $sites->isEmpty() );
+       }
+
+       /**
+        * @dataProvider siteListProvider
+        * @param SiteList $sites
+        */
+       public function testGetSiteByGlobalId( SiteList $sites ) {
+               if ( $sites->isEmpty() ) {
+                       $this->assertTrue( true );
+               }
+               else {
+                       /**
+                        * @var Site $site
+                        */
+                       foreach ( $sites as $site ) {
+                               $this->assertEquals( $site, $sites->getSite( $site->getGlobalId() ) );
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider siteListProvider
+        * @param SiteList $sites
+        */
+       public function testGetSiteByInternalId( $sites ) {
+               /**
+                * @var Site $site
+                */
+               foreach ( $sites as $site ) {
+                       if ( is_integer( $site->getInternalId() ) ) {
+                               $this->assertEquals( $site, $sites->getSiteByInternalId( $site->getInternalId() ) );
+                       }
+               }
+
+               $this->assertTrue( true );
+       }
+
+       /**
+        * @dataProvider siteListProvider
+        * @param SiteList $sites
+        */
+       public function testHasGlobalId( $sites ) {
+               $this->assertFalse( $sites->hasSite( 'non-existing-global-id' ) );
+               $this->assertFalse( $sites->hasInternalId( 720101010 ) );
+
+               if ( !$sites->isEmpty() ) {
+                       /**
+                        * @var Site $site
+                        */
+                       foreach ( $sites as $site ) {
+                               $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) );
+                       }
+               }
+       }
+
+       /**
+        * @dataProvider siteListProvider
+        * @param SiteList $sites
+        */
+       public function testHasInternallId( $sites ) {
+               /**
+                * @var Site $site
+                */
+               foreach ( $sites as $site ) {
+                       if ( is_integer( $site->getInternalId() ) ) {
+                               $this->assertTrue( $site, $sites->hasInternalId( $site->getInternalId() ) );
+                       }
+               }
+
+               $this->assertFalse( $sites->hasInternalId( -1 ) );
+       }
+
+       /**
+        * @dataProvider siteListProvider
+        * @param SiteList $sites
+        */
+       public function testGetGlobalIdentifiers( SiteList $sites ) {
+               $identifiers = $sites->getGlobalIdentifiers();
+
+               $this->assertTrue( is_array( $identifiers ) );
+
+               $expected = array();
+
+               /**
+                * @var Site $site
+                */
+               foreach ( $sites as $site ) {
+                       $expected[] = $site->getGlobalId();
+               }
+
+               $this->assertArrayEquals( $expected, $identifiers );
+       }
+
+
+}
\ No newline at end of file
diff --git a/tests/phpunit/includes/site/SiteObjectTest.php b/tests/phpunit/includes/site/SiteObjectTest.php
new file mode 100644 (file)
index 0000000..e8358f3
--- /dev/null
@@ -0,0 +1,282 @@
+<?php
+
+/**
+ * Tests for the SiteObject class.
+ *
+ * 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
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteObjectTest extends ORMRowTest {
+
+       /**
+        * @see ORMRowTest::getRowClass
+        * @since 1.21
+        * @return string
+        */
+       protected function getRowClass() {
+               return 'SiteObject';
+       }
+
+       /**
+        * @see ORMRowTest::getTableInstance
+        * @since 1.21
+        * @return IORMTable
+        */
+       protected function getTableInstance() {
+               return SitesTable::singleton();
+       }
+
+       /**
+        * @see ORMRowTest::constructorTestProvider
+        * @since 1.21
+        * @return array
+        */
+       public function constructorTestProvider() {
+               $argLists = array();
+
+               $argLists[] = array( 'global_key' => '42' );
+
+               $argLists[] = array( 'global_key' => '42', 'type' => Site::TYPE_MEDIAWIKI );
+
+               $constructorArgs = array();
+
+               foreach ( $argLists as $argList ) {
+                       $constructorArgs[] = array( $argList, true );
+               }
+
+               return $constructorArgs;
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetInterwikiIds( Site $site ) {
+               $this->assertInternalType( 'array', $site->getInterwikiIds() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetNavigationIds( Site $site ) {
+               $this->assertInternalType( 'array', $site->getNavigationIds() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testAddNavigationId( Site $site ) {
+               $site->addNavigationId( 'foobar' );
+               $this->assertTrue( in_array( 'foobar', $site->getNavigationIds(), true ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testAddInterwikiId( Site $site ) {
+               $site->addInterwikiId( 'foobar' );
+               $this->assertTrue( in_array( 'foobar', $site->getInterwikiIds(), true ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetLanguageCode( Site $site ) {
+               $this->assertTypeOrFalse( 'string', $site->getLanguageCode() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetLanguageCode( Site $site ) {
+               $site->setLanguageCode( 'en' );
+               $this->assertEquals( 'en', $site->getLanguageCode() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testNormalizePageName( Site $site ) {
+               $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetGlobalId( Site $site ) {
+               $this->assertInternalType( 'string', $site->getGlobalId() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetGlobalId( Site $site ) {
+               $site->setGlobalId( 'foobar' );
+               $this->assertEquals( 'foobar', $site->getGlobalId() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetType( Site $site ) {
+               $this->assertInternalType( 'string', $site->getType() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetPath( Site $site ) {
+               $this->assertTypeOrFalse( 'string', $site->getPath( 'page_path' ) );
+               $this->assertTypeOrFalse( 'string', $site->getPath( 'file_path' ) );
+               $this->assertTypeOrFalse( 'string', $site->getPath( 'foobar' ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetAllPaths( Site $site ) {
+               $this->assertInternalType( 'array', $site->getAllPaths() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetAndRemovePath( Site $site ) {
+               $count = count( $site->getAllPaths() );
+
+               $site->setPath( 'spam', 'http://www.wikidata.org/$1' );
+               $site->setPath( 'spam', 'http://www.wikidata.org/foo/$1' );
+               $site->setPath( 'foobar', 'http://www.wikidata.org/bar/$1' );
+
+               $this->assertEquals( $count + 2, count( $site->getAllPaths() ) );
+
+               $this->assertInternalType( 'string', $site->getPath( 'foobar' ) );
+               $this->assertEquals( 'http://www.wikidata.org/foo/$1', $site->getPath( 'spam' ) );
+
+               $site->removePath( 'spam' );
+               $site->removePath( 'foobar' );
+
+               $this->assertEquals( $count, count( $site->getAllPaths() ) );
+
+               $this->assertFalse( $site->getPath( 'foobar' ) );
+               $this->assertFalse( $site->getPath( 'spam' ) );
+       }
+
+       public function testSetLinkPath() {
+               /* @var SiteObject $site */
+               $site = $this->getRowInstance( $this->getMockFields(), false );
+               $path = "TestPath/$1";
+
+               $site->setLinkPath( $path );
+               $this->assertEquals( $path, $site->getLinkPath() );
+       }
+
+       public function testGetLinkPathType() {
+               /* @var SiteObject $site */
+               $site = $this->getRowInstance( $this->getMockFields(), false );
+
+               $path = 'TestPath/$1';
+               $site->setLinkPath( $path );
+               $this->assertEquals( $path, $site->getPath( $site->getLinkPathType() ) );
+
+               $path = 'AnotherPath/$1';
+               $site->setPath( $site->getLinkPathType(), $path );
+               $this->assertEquals( $path, $site->getLinkPath() );
+       }
+
+       public function testSetPath() {
+               /* @var SiteObject $site */
+               $site = $this->getRowInstance( $this->getMockFields(), false );
+
+               $path = 'TestPath/$1';
+               $site->setPath( 'foo', $path );
+
+               $this->assertEquals( $path, $site->getPath( 'foo' ) );
+       }
+
+       public function provideGetPageUrl() {
+               //NOTE: the assumption that the URL is built by replacing $1
+               //      with the urlencoded version of $page
+               //      is true for SiteObject but not guaranteed for subclasses.
+               //      Subclasses need to override this provider appropriately.
+
+               return array(
+                       array( #0
+                               'http://acme.test/TestPath/$1',
+                               'Foo',
+                               '/TestPath/Foo',
+                       ),
+                       array( #1
+                               'http://acme.test/TestScript?x=$1&y=bla',
+                               'Foo',
+                               'TestScript?x=Foo&y=bla',
+                       ),
+                       array( #2
+                               'http://acme.test/TestPath/$1',
+                               'foo & bar/xyzzy (quux-shmoox?)',
+                               '/TestPath/foo%20%26%20bar%2Fxyzzy%20%28quux-shmoox%3F%29',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provideGetPageUrl
+        */
+       public function testGetPageUrl( $path, $page, $expected ) {
+               /* @var SiteObject $site */
+               $site = $this->getRowInstance( $this->getMockFields(), false );
+
+               //NOTE: the assumption that getPageUrl is based on getLinkPath
+               //      is true for SiteObject but not guaranteed for subclasses.
+               //      Subclasses need to override this test case appropriately.
+               $site->setLinkPath( $path );
+               $this->assertContains( $path, $site->getPageUrl() );
+
+               $this->assertContains( $expected, $site->getPageUrl( $page ) );
+       }
+
+       protected function assertTypeOrFalse( $type, $value ) {
+               if ( $value === false ) {
+                       $this->assertTrue( true );
+               }
+               else {
+                       $this->assertInternalType( $type, $value );
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/tests/phpunit/includes/site/SitesTest.php b/tests/phpunit/includes/site/SitesTest.php
new file mode 100644 (file)
index 0000000..7675d42
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * Tests for the Sites class.
+ *
+ * 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
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ * @group Database
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SitesTest extends MediaWikiTestCase {
+
+       public function setUp() {
+               parent::setUp();
+               TestSites::insertIntoDb();
+       }
+
+       public function testSingleton() {
+               $this->assertInstanceOf( 'Sites', Sites::singleton() );
+               $this->assertTrue( Sites::singleton() === Sites::singleton() );
+       }
+
+       public function testGetSites() {
+               $this->assertInstanceOf( 'SiteList', Sites::singleton()->getSites() );
+       }
+
+
+       public function testGetSite() {
+               $count = 0;
+               $sites = Sites::singleton()->getSites();
+
+               /**
+                * @var Site $site
+                */
+               foreach ( $sites as $site ) {
+                       $this->assertInstanceOf( 'Site', $site );
+
+                       $this->assertEquals(
+                               $site,
+                               Sites::singleton()->getSite( $site->getGlobalId() )
+                       );
+
+                       if ( ++$count > 100 ) {
+                               break;
+                       }
+               }
+       }
+
+       public function testNewSite() {
+               $this->assertInstanceOf( 'Site', Sites::newSite() );
+               $this->assertInstanceOf( 'Site', Sites::newSite( 'enwiki' ) );
+       }
+
+       public function testGetGroup() {
+               $wikipedias = Sites::singleton()->getSiteGroup( "wikipedia" );
+
+               $this->assertFalse( $wikipedias->isEmpty() );
+
+               /* @var Site $site */
+               foreach ( $wikipedias as $site ) {
+                       $this->assertEquals( 'wikipedia', $site->getGroup() );
+               }
+       }
+
+}
diff --git a/tests/phpunit/includes/site/TestSites.php b/tests/phpunit/includes/site/TestSites.php
new file mode 100644 (file)
index 0000000..6003a8d
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+
+/**
+ * Holds sites for testing purposes.
+ *
+ * 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
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class TestSites {
+
+       /**
+        * @since 1.21
+        *
+        * @return array
+        */
+       public static function getSites() {
+               $sites = array();
+
+               $site = Sites::newSite( 'foobar' );
+               $sites[] = $site;
+
+               $site = Sites::newSite( 'enwiktionary' );
+               $site->setGroup( 'wiktionary' );
+               $site->setType( Site::TYPE_MEDIAWIKI );
+               $site->setLanguageCode( 'en' );
+               $site->addNavigationId( 'enwiktionary' );
+               $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" );
+               $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" );
+               $sites[] = $site;
+
+               $site = Sites::newSite( 'dewiktionary' );
+               $site->setGroup( 'wiktionary' );
+               $site->setType( Site::TYPE_MEDIAWIKI );
+               $site->setLanguageCode( 'de' );
+               $site->addInterwikiId( 'dewiktionary' );
+               $site->addInterwikiId( 'wiktionaryde' );
+               $site->setPath( MediaWikiSite::PATH_PAGE, "https://de.wiktionary.org/wiki/$1" );
+               $site->setPath( MediaWikiSite::PATH_FILE, "https://de.wiktionary.org/w/$1" );
+               $sites[] = $site;
+
+               $site = Sites::newSite( 'spam' );
+               $site->setGroup( 'spam' );
+               $site->setType( Site::TYPE_UNKNOWN );
+               $site->setLanguageCode( 'en' );
+               $site->addNavigationId( 'spam' );
+               $site->addNavigationId( 'spamz' );
+               $site->addInterwikiId( 'spamzz' );
+               $site->setLinkPath( "http://spamzz.test/testing/" );
+               $sites[] = $site;
+
+               foreach ( array( 'en', 'de', 'nl', 'sv', 'sr', 'no', 'nn' ) as $langCode ) {
+                       $site = Sites::newSite( $langCode . 'wiki' );
+                       $site->setGroup( 'wikipedia' );
+                       $site->setType( Site::TYPE_MEDIAWIKI );
+                       $site->setLanguageCode( $langCode );
+                       $site->addInterwikiId( $langCode );
+                       $site->addNavigationId( $langCode );
+                       $site->setPath( MediaWikiSite::PATH_PAGE, "https://$langCode.wikipedia.org/wiki/$1" );
+                       $site->setPath( MediaWikiSite::PATH_FILE, "https://$langCode.wikipedia.org/w/$1" );
+                       $sites[] = $site;
+               }
+
+               return $sites;
+       }
+
+       /**
+        * Inserts sites into the database for the unit tests that need them.
+        *
+        * @since 0.1
+        */
+       public static function insertIntoDb() {
+               $dbw = wfGetDB( DB_MASTER );
+
+               $dbw->begin( __METHOD__ );
+
+               $dbw->delete( 'sites', '*', __METHOD__ );
+               $dbw->delete( 'site_identifiers', '*', __METHOD__ );
+
+               /**
+                * @var Site $site
+                */
+               foreach ( TestSites::getSites() as $site ) {
+                       $site->save();
+               }
+
+               $dbw->commit( __METHOD__ );
+
+               Sites::singleton()->getSites( false ); // re-cache
+       }
+
+}
\ No newline at end of file
index b2063eb..9d7dc71 100644 (file)
@@ -80,17 +80,15 @@ class SpecialSearchTest extends MediaWikiTestCase {
                                'Web request with specific NS should override user preference'
                        ),
                        array(
-                               $EMPTY_REQUEST, array( 'searchNs2' => 1, 'searchNs14' => 1 ),
-                               'advanced', array( 2, 14 ),
-                               'Bug 33583: search with no option should honor User search preferences'
-                       ),
-                       array(
-                               $EMPTY_REQUEST, array_fill_keys( array_map( function( $ns ) {
+                               $EMPTY_REQUEST, array(
+                                       'searchNs2' => 1,
+                                       'searchNs14' => 1,
+                               ) + array_fill_keys( array_map( function( $ns ) {
                                        return "searchNs$ns";
-                               }, $defaultNS ), 0 ) + array( 'searchNs2' => 1, 'searchNs14' => 1 ),
+                               }, $defaultNS ), 0 ),
                                'advanced', array( 2, 14 ),
                                'Bug 33583: search with no option should honor User search preferences'
-                               . 'and have all other namespace disabled'
+                               . ' and have all other namespace disabled'
                        ),
                );
        }
@@ -109,5 +107,35 @@ class SpecialSearchTest extends MediaWikiTestCase {
                }
                return $u;
        }
+
+       /**
+        * Verify we do not expand search term in <title> on search result page
+        * https://gerrit.wikimedia.org/r/4841
+        */
+       function testSearchTermIsNotExpanded() {
+
+               # Initialize [[Special::Search]]
+               $search = new SpecialSearch();
+               $search->getContext()->setTitle( Title::newFromText('Special:Search' ) );
+               $search->load();
+
+               # Simulate a user searching for a given term
+               $term = '{{SITENAME}}';
+               $search->showResults( $term );
+
+               # Lookup the HTML page title set for that page
+               $pageTitle = $search
+                       ->getContext()
+                       ->getOutput()
+                       ->getHTMLTitle();
+
+               # Compare :-]
+               $this->assertRegExp(
+                       '/' . preg_quote( $term ) . '/',
+                       $pageTitle,
+                       "Search term '{$term}' should not be expanded in Special:Search <title>"
+               );
+
+       }
 }
 
diff --git a/tests/phpunit/resources/ResourcesTest.php b/tests/phpunit/resources/ResourcesTest.php
new file mode 100644 (file)
index 0000000..18db399
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Sanity checks for making sure registered resources are sane.
+ *
+ * @file
+ * @author Niklas Laxström, 2012
+ * @author Antoine Musso, 2012
+ * @author Santhosh Thottingal, 2012
+ * @author Timo Tijhof, 2012
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
+ */
+class ResourcesTest extends MediaWikiTestCase {
+
+       /**
+        * @dataProvider provideResourceFiles
+        */
+       public function testFileExistence( $filename, $module, $resource ) {
+               $this->assertFileExists( $filename,
+                       "File '$resource' referenced by '$module' must exist."
+               );
+       }
+
+       /**
+        * This ask the ResouceLoader for all registered files from modules
+        * created by ResourceLoaderFileModule (or one of its descendants).
+        *
+        *
+        * Since the raw data is stored in protected properties, we have to
+        * overrride this through ReflectionObject methods.
+        */
+       public static function provideResourceFiles() {
+               global $wgEnableJavaScriptTest;
+
+               // Test existance of test suite files as well
+               // (can't use setUp or setMwGlobals because providers are static)
+               $live_wgEnableJavaScriptTest = $wgEnableJavaScriptTest;
+               $wgEnableJavaScriptTest = true;
+
+               // Array with arguments for the test function
+               $cases = array();
+
+               // Initialize ResourceLoader
+               $rl = new ResourceLoader();
+
+               // See also ResourceLoaderFileModule::__construct
+               $filePathProps = array(
+                       // Lists of file paths
+                       'lists' => array(
+                               'scripts',
+                               'debugScripts',
+                               'loaderScripts',
+                               'styles',
+                       ),
+
+                       // Collated lists of file paths
+                       'nested-lists' => array(
+                               'languageScripts',
+                               'skinScripts',
+                               'skinStyles',
+                       ),
+               );
+
+               foreach ( $rl->getModuleNames() as $moduleName ) {
+                       $module = $rl->getModule( $moduleName );
+                       if ( ! $module instanceof ResourceLoaderFileModule ) {
+                               continue;
+                       }
+
+                       $reflectedModule = new ReflectionObject( $module );
+
+                       $files = array();
+
+                       foreach ( $filePathProps['lists'] as $propName ) {
+                               $property = $reflectedModule->getProperty( $propName );
+                               $property->setAccessible( true );
+                               $list = $property->getValue( $module );
+                               foreach ( $list as $key => $value ) {
+                                       // 'scripts' are numeral arrays.
+                                       // 'styles' can be numeral or associative.
+                                       // In case of associative the key is the file path
+                                       // and the value is the 'media' attribute.
+                                       if ( is_int( $key ) ) {
+                                               $files[] = $value;
+                                       } else {
+                                               $files[] = $key;
+                                       }
+                               }
+                       }
+
+                       foreach ( $filePathProps['nested-lists'] as $propName ) {
+                               $property = $reflectedModule->getProperty( $propName );
+                               $property->setAccessible( true );
+                               $lists = $property->getValue( $module );
+                               foreach ( $lists as $group => $list ) {
+                                       foreach ( $list as $key => $value ) {
+                                               // We need the same filter as for 'lists',
+                                               // due to 'skinStyles'.
+                                               if ( is_int( $key ) ) {
+                                                       $files[] = $value;
+                                               } else {
+                                                       $files[] = $key;
+                                               }
+                                       }
+                               }
+                       }
+
+                       // Get method for resolving the paths to full paths
+                       $method = $reflectedModule->getMethod( 'getLocalPath' );
+                       $method->setAccessible( true );
+
+                       // Populate cases
+                       foreach ( $files as $file ) {
+                               $cases[] = array(
+                                       $method->invoke( $module, $file ),
+                                       $module->getName(),
+                                       $file,
+                               );
+                       }
+
+               }
+
+               // Restore settings
+               $wgEnableJavaScriptTest = $live_wgEnableJavaScriptTest;
+
+               return $cases;
+       }
+
+}
index be5f4ac..01072d8 100644 (file)
@@ -13,6 +13,7 @@ return array(
                        'tests/qunit/suites/resources/jquery/jquery.colorUtil.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.delayedBind.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.getAttrs.test.js',
+                       'tests/qunit/suites/resources/jquery/jquery.hidpi.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.highlightText.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.localize.test.js',
                        'tests/qunit/suites/resources/jquery/jquery.mwExtension.test.js',
@@ -41,6 +42,7 @@ return array(
                        'jquery.colorUtil',
                        'jquery.delayedBind',
                        'jquery.getAttrs',
+                       'jquery.hidpi',
                        'jquery.highlightText',
                        'jquery.localize',
                        'jquery.mwExtension',
diff --git a/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js b/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js
new file mode 100644 (file)
index 0000000..cf309df
--- /dev/null
@@ -0,0 +1,20 @@
+QUnit.module( 'jquery.hidpi', QUnit.newMwEnvironment() );
+
+QUnit.test( 'devicePixelRatio', function ( assert ) {
+       var devicePixelRatio = $.devicePixelRatio();
+       assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' );
+});
+
+QUnit.test( 'matchSrcSet', function ( assert ) {
+       var srcset = 'onefive.png 1.5x, two.png 2x';
+
+       // Nice exact matches
+       assert.equal( $.matchSrcSet( 1, srcset ), null, '1.0 gives no match' );
+       assert.equal( $.matchSrcSet( 1.5, srcset ), 'onefive.png', '1.5 gives match' );
+       assert.equal( $.matchSrcSet( 2, srcset ), 'two.png', '2 gives match' );
+
+       // Non-exact matches; should return the next-biggest specified
+       assert.equal( $.matchSrcSet( 1.25, srcset ), null, '1.25 gives no match' );
+       assert.equal( $.matchSrcSet( 1.75, srcset ), 'onefive.png', '1.75 gives match to 1.5' );
+       assert.equal( $.matchSrcSet( 2.25, srcset ), 'two.png', '2.25 gives match to 2' );
+});
index c80296f..bce7bd7 100644 (file)
@@ -6,7 +6,6 @@ QUnit.module( 'mediawiki.jqueryMsg', QUnit.newMwEnvironment( {
                mw.language = $.extend( true, {}, this.orgMwLangauge );
        },
        teardown: function () {
-               // Restore
                mw.language = this.orgMwLangauge;
        }
 }) );
@@ -25,7 +24,10 @@ function getMwLanguage( langCode, cb ) {
                        skin: mw.config.get( 'skin' ),
                        lang: langCode,
                        debug: mw.config.get( 'debug' ),
-                       modules: 'mediawiki.language',
+                       modules: [
+                               'mediawiki.language.data',
+                               'mediawiki.language'
+                       ].join( '|' ),
                        only: 'scripts'
                },
                dataType: 'script'
@@ -141,6 +143,7 @@ QUnit.test( 'Output matches PHP parser', mw.libs.phpParserData.tests.length, fun
                                assert.ok( false, 'Language "' + test.lang + '" failed to load' );
                                return;
                        }
+                       mw.config.set( 'wgUserLanguage', test.lang ) ;
                        var parser = new mw.jqueryMsg.parser( { language: langClass } );
                        assert.equal(
                                parser.parse( test.key, test.args ).html(),
index 806058d..be59f1a 100644 (file)
@@ -170,7 +170,7 @@ function assertStyleAsync( assert, $element, prop, val, fn ) {
                // If it is passing or if we timed out, run the real test and stop the loop
                if ( isCssImportApplied() || styleTestSince > styleTestTimeout ) {
                        assert.equal( $element.css( prop ), val,
-                               'style from url is applied (after ' + styleTestSince + 'ms)'
+                               'style "' + prop + ': ' + val + '" from url is applied (after ' + styleTestSince + 'ms)'
                        );
 
                        if ( fn ) {
@@ -253,35 +253,49 @@ QUnit.test( 'mw.loader.implement( styles={ "css": [text, ..] } )', 2, function (
        ]);
 } );
 
-QUnit.asyncTest( 'mw.loader.implement( styles={ "url": { <media>: [url, ..] } } )', 4, function ( assert ) {
-       var $element = $( '<div class="mw-test-implement-b"></div>' ).appendTo( '#qunit-fixture' ),
-               $element2 = $( '<div class="mw-test-implement-b2"></div>' ).appendTo( '#qunit-fixture' );
+QUnit.asyncTest( 'mw.loader.implement( styles={ "url": { <media>: [url, ..] } } )', 7, function ( assert ) {
+       var $element1 = $( '<div class="mw-test-implement-b1"></div>' ).appendTo( '#qunit-fixture' ),
+               $element2 = $( '<div class="mw-test-implement-b2"></div>' ).appendTo( '#qunit-fixture' ),
+               $element3 = $( '<div class="mw-test-implement-b3"></div>' ).appendTo( '#qunit-fixture' );
 
        assert.notEqual(
-               $element.css( 'float' ),
-               'right',
+               $element1.css( 'text-align' ),
+               'center',
                'style is clear'
        );
        assert.notEqual(
-               $element2.css( 'text-align' ),
-               'center',
+               $element2.css( 'float' ),
+               'left',
+               'style is clear'
+       );
+       assert.notEqual(
+               $element3.css( 'text-align' ),
+               'right',
                'style is clear'
        );
 
        mw.loader.implement(
                'test.implement.b',
                function () {
-                       assertStyleAsync( assert, $element, 'float', 'right', function () {
+                       assertStyleAsync( assert, $element2, 'float', 'left', function () {
+                               assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
 
-                               assert.notEqual( $element2.css( 'text-align' ), 'center', 'print style is not applied' );
+                               QUnit.start();
+                       } );
+                       assertStyleAsync( assert, $element3, 'float', 'right', function () {
+                               assert.notEqual( $element1.css( 'text-align' ), 'center', 'print style is not applied' );
 
                                QUnit.start();
                        } );
                },
                {
                        'url': {
-                               'screen': [urlStyleTest( '.mw-test-implement-b', 'float', 'right' )],
-                               'print': [urlStyleTest( '.mw-test-implement-b2', 'text-align', 'center' )]
+                               'print': [urlStyleTest( '.mw-test-implement-b1', 'text-align', 'center' )],
+                               'screen': [
+                                       // bug 40834: Make sure it actually works with more than 1 stylesheet reference
+                                       urlStyleTest( '.mw-test-implement-b2', 'float', 'left' ),
+                                       urlStyleTest( '.mw-test-implement-b3', 'float', 'right' )
+                               ]
                        }
                },
                {}
index 068ec01..362f304 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -153,6 +153,13 @@ function wfStreamThumb( array $params ) {
                $img = wfLocalFile( $fileName );
        }
 
+       // Check the source file title
+       if ( !$img ) {
+               wfThumbError( 404, wfMessage( 'badtitletext' )->text() );
+               wfProfileOut( __METHOD__ );
+               return;
+       }
+
        // Check permissions if there are read restrictions
        $varyHeader = array();
        if ( !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) ) {
@@ -167,11 +174,6 @@ function wfStreamThumb( array $params ) {
        }
 
        // Check the source file storage path
-       if ( !$img ) {
-               wfThumbError( 404, wfMessage( 'badtitletext' )->text() );
-               wfProfileOut( __METHOD__ );
-               return;
-       }
        if ( !$img->exists() ) {
                wfThumbError( 404, 'The source file for the specified thumbnail does not exist.' );
                wfProfileOut( __METHOD__ );
index 0c9b702..db388d2 100644 (file)
@@ -22,4 +22,4 @@
  * @ingroup Media
  */
 
-require './thumb.php'; 
+require './thumb.php';