Merge "Remove unused parameter"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 4 Dec 2018 06:27:27 +0000 (06:27 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 4 Dec 2018 06:27:27 +0000 (06:27 +0000)
331 files changed:
.eslintrc.json
RELEASE-NOTES-1.32
RELEASE-NOTES-1.33
composer.json
docs/extension.schema.v1.json
docs/extension.schema.v2.json
includes/DefaultSettings.php
includes/EditPage.php
includes/Linker.php
includes/MWNamespace.php
includes/MediaWikiServices.php
includes/Message.php
includes/MovePage.php
includes/Revision/FallbackSlotRoleHandler.php [new file with mode: 0644]
includes/Revision/MainSlotRoleHandler.php [new file with mode: 0644]
includes/Revision/RenderedRevision.php
includes/Revision/RevisionRenderer.php
includes/Revision/RevisionStore.php
includes/Revision/RevisionStoreFactory.php
includes/Revision/SlotRoleHandler.php [new file with mode: 0644]
includes/Revision/SlotRoleRegistry.php [new file with mode: 0644]
includes/ServiceWiring.php
includes/Storage/DerivedPageDataUpdater.php
includes/Storage/NameTableStore.php
includes/Storage/PageUpdater.php
includes/Title.php
includes/actions/InfoAction.php
includes/api/ApiBase.php
includes/api/ApiComparePages.php
includes/api/ApiErrorFormatter.php
includes/api/ApiFeedContributions.php
includes/api/ApiMain.php
includes/api/ApiMessageTrait.php
includes/api/ApiQueryAllDeletedRevisions.php
includes/api/ApiQueryAllRevisions.php
includes/api/ApiQueryBacklinks.php
includes/api/ApiQueryDeletedRevisions.php
includes/api/ApiQueryDeletedrevs.php
includes/api/ApiQueryLogEvents.php
includes/api/ApiQueryRecentChanges.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQueryRevisionsBase.php
includes/api/ApiQueryUserContribs.php
includes/api/i18n/es.json
includes/api/i18n/hu.json
includes/api/i18n/nb.json
includes/api/i18n/pl.json
includes/api/i18n/zh-hant.json
includes/block/BlockRestriction.php
includes/block/Restriction/Restriction.php
includes/changetags/ChangeTags.php
includes/content/Content.php
includes/content/ContentHandler.php
includes/content/WikitextContent.php
includes/db/CloneDatabase.php
includes/debug/logger/monolog/SyslogHandler.php
includes/diff/DifferenceEngine.php
includes/exception/MWException.php
includes/export/DumpFilter.php
includes/export/DumpOutput.php
includes/filerepo/file/ForeignAPIFile.php
includes/htmlform/fields/HTMLExpiryField.php
includes/htmlform/fields/HTMLMultiSelectField.php
includes/installer/MssqlUpdater.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
includes/installer/WebInstallerOptions.php
includes/installer/WebInstallerUpgrade.php
includes/installer/i18n/ar.json
includes/installer/i18n/cs.json
includes/installer/i18n/et.json
includes/installer/i18n/sr-ec.json
includes/installer/i18n/sr-el.json
includes/installer/i18n/sv.json
includes/jobqueue/JobQueueDB.php
includes/jobqueue/jobs/CategoryMembershipChangeJob.php
includes/libs/mime/XmlTypeCheck.php
includes/libs/objectcache/BagOStuff.php
includes/libs/objectcache/RedisBagOStuff.php
includes/libs/objectcache/WANObjectCache.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/ILoadBalancer.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/mail/EmailNotification.php
includes/media/Exif.php
includes/media/MediaTransformOutput.php
includes/page/Article.php
includes/page/WikiPage.php
includes/parser/Parser.php
includes/parser/ParserOptions.php
includes/parser/RemexStripTagHandler.php
includes/parser/Sanitizer.php
includes/password/PasswordPolicyChecks.php
includes/preferences/DefaultPreferencesFactory.php
includes/registration/ExtensionProcessor.php
includes/resourceloader/ResourceLoaderImage.php
includes/revisiondelete/RevisionDeleteUser.php
includes/search/SearchSuggestionSet.php
includes/specialpage/AuthManagerSpecialPage.php
includes/specials/SpecialExport.php
includes/specials/SpecialRevisiondelete.php
includes/specials/forms/PreferencesFormOOUI.php
includes/specials/pagers/ActiveUsersPager.php
includes/specials/pagers/BlockListPager.php
includes/specials/pagers/NewPagesPager.php
includes/specials/pagers/UsersPager.php
includes/upload/UploadFromChunks.php
includes/user/User.php
includes/utils/UIDGenerator.php
languages/ConverterRule.php
languages/Language.php
languages/LanguageConverter.php
languages/classes/LanguageKu.php
languages/classes/LanguageShi.php
languages/classes/LanguageUz.php
languages/data/CrhExceptions.php
languages/i18n/ace.json
languages/i18n/ady-cyrl.json
languages/i18n/aeb-arab.json
languages/i18n/ar.json
languages/i18n/arz.json
languages/i18n/ast.json
languages/i18n/azb.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bg.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/bs.json
languages/i18n/ca.json
languages/i18n/ce.json
languages/i18n/ckb.json
languages/i18n/cs.json
languages/i18n/da.json
languages/i18n/de.json
languages/i18n/dty.json
languages/i18n/el.json
languages/i18n/en.json
languages/i18n/eo.json
languages/i18n/es.json
languages/i18n/et.json
languages/i18n/eu.json
languages/i18n/fa.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/frr.json
languages/i18n/gl.json
languages/i18n/he.json
languages/i18n/hi.json
languages/i18n/hr.json
languages/i18n/hu.json
languages/i18n/hy.json
languages/i18n/ia.json
languages/i18n/id.json
languages/i18n/inh.json
languages/i18n/is.json
languages/i18n/it.json
languages/i18n/ja.json
languages/i18n/jv.json
languages/i18n/ka.json
languages/i18n/kjp.json
languages/i18n/km.json
languages/i18n/ko.json
languages/i18n/la.json
languages/i18n/lb.json
languages/i18n/lfn.json
languages/i18n/li.json
languages/i18n/lt.json
languages/i18n/lv.json
languages/i18n/lzh.json
languages/i18n/mai.json
languages/i18n/mdf.json
languages/i18n/mk.json
languages/i18n/ml.json
languages/i18n/my.json
languages/i18n/nan.json
languages/i18n/nap.json
languages/i18n/nb.json
languages/i18n/ne.json
languages/i18n/nl.json
languages/i18n/nn.json
languages/i18n/oc.json
languages/i18n/pl.json
languages/i18n/ps.json
languages/i18n/pt-br.json
languages/i18n/pt.json
languages/i18n/qqq.json
languages/i18n/ro.json
languages/i18n/roa-tara.json
languages/i18n/ru.json
languages/i18n/sah.json
languages/i18n/shn.json
languages/i18n/sk.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/su.json
languages/i18n/sv.json
languages/i18n/tcy.json
languages/i18n/te.json
languages/i18n/th.json
languages/i18n/tr.json
languages/i18n/tt-cyrl.json
languages/i18n/uk.json
languages/i18n/ur.json
languages/i18n/uz.json
languages/i18n/vi.json
languages/i18n/yue.json
languages/i18n/zh-hans.json
languages/i18n/zh-hant.json
languages/messages/MessagesCs.php
maintenance/archives/patch-drop-ct_tag.sql [new file with mode: 0644]
maintenance/mssql/archives/patch-drop-ct_tag.sql [new file with mode: 0644]
maintenance/mssql/tables.sql
maintenance/oracle/archives/patch-drop-ct_tag.sql [new file with mode: 0644]
maintenance/oracle/tables.sql
maintenance/populateChangeTagDef.php
maintenance/postgres/archives/patch-drop-ct_tag.sql [new file with mode: 0644]
maintenance/postgres/tables.sql
maintenance/sqlite/archives/patch-actor-table.sql
maintenance/sqlite/archives/patch-add-3d.sql
maintenance/sqlite/archives/patch-comment-table.sql
maintenance/sqlite/archives/patch-drop-ct_tag.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-filearchive-fa_actor.sql [new file with mode: 0644]
maintenance/sqlite/archives/patch-filearchive-fa_description_id.sql [new file with mode: 0644]
maintenance/tables.sql
mw-config/config.css
package.json
resources/Resources.php
resources/src/jquery.tipsy/jquery.tipsy.css
resources/src/jquery/jquery.makeCollapsible.css
resources/src/jquery/jquery.makeCollapsible.styles.less
resources/src/mediawiki.Title/Title.js
resources/src/mediawiki.action/mediawiki.action.view.categoryPage.less
resources/src/mediawiki.apihelp.css
resources/src/mediawiki.debug/debug.js
resources/src/mediawiki.feedback/feedback.css
resources/src/mediawiki.hlist/default.css
resources/src/mediawiki.htmlform.ooui.styles.less
resources/src/mediawiki.htmlform.styles/styles.css
resources/src/mediawiki.legacy/oldshared.css
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.less/mediawiki.mixins.less
resources/src/mediawiki.less/mediawiki.mixins.rotation.less
resources/src/mediawiki.notification/default.css
resources/src/mediawiki.page.gallery.styles/print.css
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.highlightCircles.seenunseen.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ChangesListWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterItemHighlightButton.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterTagMultiselectWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.FilterWrapperWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.HighlightColorPickerWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.ItemMenuOptionWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.LiveUpdateButtonWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SaveFiltersPopupButtonWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.SavedLinksListItemWidget.less
resources/src/mediawiki.rcfilters/styles/mw.rcfilters.ui.TagItemWidget.less
resources/src/mediawiki.skinning/content.css
resources/src/mediawiki.skinning/content.parsoid.less
resources/src/mediawiki.skinning/elements.css
resources/src/mediawiki.special.apisandbox/apisandbox.css
resources/src/mediawiki.special.apisandbox/apisandbox.js
resources/src/mediawiki.special.block.less
resources/src/mediawiki.special.changeslist.less
resources/src/mediawiki.special.preferences.styles.css
resources/src/mediawiki.special.preferences.styles.ooui.less
resources/src/mediawiki.special.search.interwikiwidget.styles.less
resources/src/mediawiki.special.search.styles.css
resources/src/mediawiki.special.search/search.css
resources/src/mediawiki.special.userlogin.login.styles/login.css
resources/src/mediawiki.special/special.css
resources/src/mediawiki.special/userrights.css
resources/src/mediawiki.ui/components/anchors.less
resources/src/mediawiki.ui/components/buttons.less
resources/src/mediawiki.ui/components/forms.less
resources/src/mediawiki.ui/components/icons.less
resources/src/mediawiki.ui/components/inputs.less
resources/src/mediawiki.ui/components/text.less
resources/src/mediawiki.util.js
resources/src/mediawiki.widgets.datetime/CalendarWidget.js
resources/src/mediawiki.widgets.datetime/CalendarWidget.less
resources/src/mediawiki.widgets.datetime/DateTimeInputWidget.js
resources/src/mediawiki.widgets.datetime/DiscordianDateTimeFormatter.js
resources/src/mediawiki.widgets.datetime/ProlepticGregorianDateTimeFormatter.js
resources/src/mediawiki.widgets/mw.widgets.CalendarWidget.less
resources/src/mediawiki.widgets/mw.widgets.StashedFileWidget.less
resources/src/mediawiki.widgets/mw.widgets.TitleWidget.less
tests/parser/parserTests.txt
tests/phpunit/includes/LinkerTest.php
tests/phpunit/includes/Revision/FallbackSlotRoleHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/Revision/MainSlotRoleHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/Revision/RenderedRevisionTest.php
tests/phpunit/includes/Revision/RevisionRendererTest.php
tests/phpunit/includes/Revision/RevisionStoreDbTestBase.php
tests/phpunit/includes/Revision/RevisionStoreFactoryTest.php
tests/phpunit/includes/Revision/RevisionStoreTest.php
tests/phpunit/includes/Revision/SlotRoleHandlerTest.php [new file with mode: 0644]
tests/phpunit/includes/Revision/SlotRoleRegistryTest.php [new file with mode: 0644]
tests/phpunit/includes/RevisionDbTestBase.php
tests/phpunit/includes/RevisionTest.php
tests/phpunit/includes/Storage/DerivedPageDataUpdaterTest.php
tests/phpunit/includes/Storage/PageUpdaterTest.php
tests/phpunit/includes/TitlePermissionTest.php
tests/phpunit/includes/api/ApiBlockTest.php
tests/phpunit/includes/api/ApiDeleteTest.php
tests/phpunit/includes/api/ApiEditPageTest.php
tests/phpunit/includes/api/ApiErrorFormatterTest.php
tests/phpunit/includes/api/ApiMainTest.php
tests/phpunit/includes/api/ApiMessageTest.php
tests/phpunit/includes/api/ApiUnblockTest.php
tests/phpunit/includes/api/ApiUserrightsTest.php
tests/phpunit/includes/changetags/ChangeTagsTest.php
tests/phpunit/includes/db/LBFactoryTest.php
tests/phpunit/includes/jobqueue/jobs/CategoryMembershipChangeJobTest.php
tests/phpunit/includes/jobqueue/jobs/RefreshLinksJobTest.php
tests/phpunit/includes/page/PageArchiveMcrTest.php
tests/phpunit/includes/page/PageArchivePreMcrTest.php
tests/phpunit/includes/page/PageArchiveTestBase.php
tests/phpunit/includes/page/WikiPageDbTestBase.php
tests/phpunit/includes/page/WikiPageMcrReadNewDbTest.php
tests/phpunit/includes/user/LocalIdLookupTest.php
tests/phpunit/includes/user/UserTest.php
tests/phpunit/maintenance/populateChangeTagDefTest.php [deleted file]
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js
tests/qunit/suites/resources/mediawiki/mediawiki.loader.test.js

index 99d7730..97f7c31 100644 (file)
@@ -10,7 +10,6 @@
                "OO": false
        },
        "rules": {
-               "dot-notation": 0,
                "max-len": 0
        }
 }
index 06b60e4..cc250ef 100644 (file)
@@ -154,6 +154,7 @@ production.
 ** ScopedCallback objects can no longer be serialized.
 * Updated wikimedia/timestamp from v1.0.0 to v2.2.0.
 * Updated wikimedia/wrappedstring from v2.3.0 to v3.0.1.
+* oyejorge/less.php replaced with our fork wikimedia/less.php
 
 * Updated composer/spdx-licenses from v1.3.0 to v1.4.0 (dev-only).
 * Updated mediawiki/mediawiki-codesniffer from v18.0.0 to v22.0.0 (dev-only).
index 1021cb3..628227e 100644 (file)
@@ -55,6 +55,12 @@ production.
 === Action API changes in 1.33 ===
 * (T198913) Added 'ApiOptions' hook.
 * The JSON formatversion=2 is no longer experimental.
+* Internal API errors (those with code beginning "internal_api_error") will
+  include the exception class name in a data field named "errorclass".
+  * Class names are not guaranteed to remain stable, and in particular database
+    exceptions will now include the "Wikimedia\Rdbms\" prefix in the class name.
+  * The code including an exception class name is deprecated. In the future,
+    all internal errors will use code "internal_api_error".
 * …
 
 === Action API internal changes in 1.33 ===
@@ -68,6 +74,10 @@ production.
   Additionally, the  'APIGetDescription' and 'APIGetParamDescription' hooks have
   been removed, as their only use was to let extensions override values returned
   by getDescription() and getParamDescription(), respectively.
+* API error codes may only contain ASCII letters, numbers, underscore, and
+  hyphen. Methods such as ApiBase::dieWithError() and
+  ApiMessageTrait::setApiCode() will throw an InvalidArgumentException if
+  passed a bad code.
 * …
 
 === Languages updated in 1.33 ===
@@ -142,6 +152,7 @@ because of Phabricator reports.
   * filterIntval()
   * filterTimezoneInput()
   * getTimeZoneList()
+* mw.util.jsMessage(), deprecated in 1.20, was removed. Use mw.notify instead.
 
 === Deprecations in 1.33 ===
 * The configuration option $wgUseESI has been deprecated, and is expected
index 09c6215..616c9d7 100644 (file)
@@ -27,7 +27,6 @@
                "ext-xml": "*",
                "liuggio/statsd-php-client": "1.0.18",
                "oojs/oojs-ui": "0.29.5",
-               "oyejorge/less.php": "1.7.0.14",
                "pear/mail": "1.4.1",
                "pear/mail_mime": "1.10.2",
                "pear/net_smtp": "1.8.0",
@@ -41,8 +40,9 @@
                "wikimedia/composer-merge-plugin": "1.4.1",
                "wikimedia/html-formatter": "1.0.2",
                "wikimedia/ip-set": "1.2.0",
+               "wikimedia/less.php": "1.8.0",
                "wikimedia/object-factory": "1.0.0",
-               "wikimedia/password-blacklist": "0.1.2",
+               "wikimedia/password-blacklist": "0.1.3",
                "wikimedia/php-session-serializer": "1.0.6",
                "wikimedia/purtle": "1.0.7",
                "wikimedia/relpath": "2.1.1",
index f6f3b21..7e42035 100644 (file)
                                "type": "string"
                        }
                },
+               "ReauthenticateTime": {
+                       "type": "object",
+                       "patternProperties": {
+                               ".*": {
+                                       "type": "integer"
+                               }
+                       }
+               },
                "callback": {
                        "type": [
                                "array",
index 8ade991..c5c3b5d 100644 (file)
                                "type": "string"
                        }
                },
+               "ReauthenticateTime": {
+                       "type": "object",
+                       "patternProperties": {
+                               ".*": {
+                                       "type": "integer"
+                               }
+                       }
+               },
                "callback": {
                        "type": [
                                "array",
index 5175543..c3a716f 100644 (file)
@@ -37,6 +37,7 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * @cond file_level_code
@@ -7565,7 +7566,10 @@ $wgJobClasses = [
        'refreshLinksPrioritized' => RefreshLinksJob::class,
        'refreshLinksDynamic' => RefreshLinksJob::class,
        'activityUpdateJob' => ActivityUpdateJob::class,
-       'categoryMembershipChange' => CategoryMembershipChangeJob::class,
+       'categoryMembershipChange' => function ( Title $title, $params = [] ) {
+               $pc = MediaWikiServices::getInstance()->getParserCache();
+               return new CategoryMembershipChangeJob( $pc, $title, $params );
+       },
        'clearUserWatchlist' => ClearUserWatchlistJob::class,
        'cdnPurge' => CdnPurgeJob::class,
        'userGroupExpiry' => UserGroupExpiryJob::class,
@@ -8614,6 +8618,9 @@ $wgUploadMaintenance = false;
  * defined for a given namespace, pages in that namespace will use the CONTENT_MODEL_WIKITEXT
  * (except for the special case of JS and CS pages).
  *
+ * @note To determine the default model for a new page's main slot, or any slot in general,
+ * use SlotRoleHandler::getDefaultModel() together with SlotRoleRegistry::getRoleHandler().
+ *
  * @since 1.21
  */
 $wgNamespaceContentModels = [];
@@ -8989,7 +8996,7 @@ $wgInterwikiPrefixDisplayTypes = [];
  * @since 1.30
  * @var int One of the MIGRATION_* constants
  */
-$wgCommentTableSchemaMigrationStage = MIGRATION_OLD;
+$wgCommentTableSchemaMigrationStage = MIGRATION_NEW;
 
 /**
  * RevisionStore table schema migration stage (content, slots, content_models & slot_roles tables).
@@ -9030,20 +9037,6 @@ $wgMultiContentRevisionSchemaMigrationStage = SCHEMA_COMPAT_WRITE_BOTH | SCHEMA_
  */
 $wgActorTableSchemaMigrationStage = SCHEMA_COMPAT_OLD;
 
-/**
- * change_tag table schema migration stage.
- *
- * - MIGRATION_OLD: Do not use change_tag_def table or ct_tag_id.
- * - MIGRATION_WRITE_BOTH: Write to the change_tag_def table and ct_tag_id, but read from
- *   the old schema. This is different from the formal definition of the constants
- * - MIGRATION_WRITE_NEW: Behaves the same as MIGRATION_WRITE_BOTH
- * - MIGRATION_NEW: Use the change_tag_def table and ct_tag_id, do not read/write ct_tag
- *
- * @since 1.32
- * @var int One of the MIGRATION_* constants
- */
-$wgChangeTagsSchemaMigrationStage = MIGRATION_NEW;
-
 /**
  * Flag to enable Partial Blocks. This allows an admin to prevent a user from editing specific pages
  * or namespaces.
@@ -9054,6 +9047,16 @@ $wgChangeTagsSchemaMigrationStage = MIGRATION_NEW;
  */
 $wgEnablePartialBlocks = false;
 
+/**
+ * Enable stats monitoring when Block Notices are displayed in different places around core
+ * and extensions.
+ *
+ * @since 1.34
+ * @deprecated 1.34
+ * @var bool
+ */
+$wgEnableBlockNoticeStats = false;
+
 /**
  * For really cool vim folding this needs to be at the end:
  * vim: foldmarker=@{,@} foldmethod=marker
index 5f4c3ae..9e278af 100644 (file)
@@ -627,14 +627,23 @@ class EditPage {
                if ( $permErrors ) {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
 
-                       // track block with a cookie if it doesn't exists already
-                       $this->context->getUser()->trackBlockWithCookie();
+                       if ( $this->context->getUser()->getBlock() ) {
+                               // track block with a cookie if it doesn't exists already
+                               $this->context->getUser()->trackBlockWithCookie();
+
+                               // Auto-block user's IP if the account was "hard" blocked
+                               if ( !wfReadOnly() ) {
+                                       DeferredUpdates::addCallableUpdate( function () {
+                                               $this->context->getUser()->spreadAnyEditBlock();
+                                       } );
+                               }
 
-                       // Auto-block user's IP if the account was "hard" blocked
-                       if ( !wfReadOnly() ) {
-                               DeferredUpdates::addCallableUpdate( function () {
-                                       $this->context->getUser()->spreadAnyEditBlock();
-                               } );
+                               $config = $this->context->getConfig();
+                               if ( $config->get( 'EnableBlockNoticeStats' ) ) {
+                                       $wiki = $config->get( 'DBname' );
+                                       $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                                       $statsd->increment( 'BlockNotices.' . $wiki . '.WikitextEditor.shown' );
+                               }
                        }
                        $this->displayPermissionsError( $permErrors );
 
index 7eda21b..2028197 100644 (file)
@@ -1151,7 +1151,6 @@ class Linker {
                                );
 
                                if ( $comment === null ) {
-                                       $link = '';
                                        if ( $title ) {
                                                $section = $auto;
                                                # Remove links that a user may have manually put in the autosummary
@@ -1160,6 +1159,10 @@ class Linker {
                                                $section = str_replace( '[[', '', $section );
                                                $section = str_replace( ']]', '', $section );
 
+                                               // We don't want any links in the auto text to be linked, but we still
+                                               // want to show any [[ ]]
+                                               $sectionText = str_replace( '[[', '&#91;[', $auto );
+
                                                $section = substr( Parser::guessSectionNameFromStrippedText( $section ), 1 );
                                                if ( $local ) {
                                                        $sectionTitle = Title::makeTitleSafe( NS_MAIN, '', $section );
@@ -1168,12 +1171,10 @@ class Linker {
                                                                $title->getDBkey(), $section );
                                                }
                                                if ( $sectionTitle ) {
-                                                       $link = Linker::makeCommentLink(
-                                                               $sectionTitle, $wgLang->getArrow() . $auto, $wikiId, 'noclasses'
+                                                       $auto = Linker::makeCommentLink(
+                                                               $sectionTitle, $wgLang->getArrow() . $wgLang->getDirMark() . $sectionText,
+                                                               $wikiId, 'noclasses'
                                                        );
-                                                       $auto = '';
-                                               } else {
-                                                       $link = '';
                                                }
                                        }
                                        if ( $pre ) {
@@ -1188,7 +1189,7 @@ class Linker {
                                                $auto = '<span dir="auto"><span class="autocomment">' . $auto . '</span>';
                                                $append .= '</span>';
                                        }
-                                       $comment = $pre . $link . $wgLang->getDirMark() . $auto;
+                                       $comment = $pre . $auto;
                                }
                                return $comment;
                        },
index e03a29b..98e70bf 100644 (file)
@@ -19,6 +19,7 @@
  *
  * @file
  */
+use MediaWiki\MediaWikiServices;
 
 /**
  * This is a utility class with only static functions
@@ -462,13 +463,17 @@ class MWNamespace {
         * Get the default content model for a namespace
         * This does not mean that all pages in that namespace have the model
         *
+        * @note To determine the default model for a new page's main slot, or any slot in general,
+        * use SlotRoleHandler::getDefaultModel() together with SlotRoleRegistry::getRoleHandler().
+        *
         * @since 1.21
         * @param int $index Index to check
         * @return null|string Default model name for the given namespace, if set
         */
        public static function getNamespaceContentModel( $index ) {
-               global $wgNamespaceContentModels;
-               return $wgNamespaceContentModels[$index] ?? null;
+               $config = MediaWikiServices::getInstance()->getMainConfig();
+               $models = $config->get( 'NamespaceContentModels' );
+               return $models[$index] ?? null;
        }
 
        /**
index f3ca7d4..0e36b22 100644 (file)
@@ -17,6 +17,7 @@ use MediaWiki\Http\HttpRequestFactory;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Shell\CommandFactory;
 use MediaWiki\Revision\RevisionRenderer;
+use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Special\SpecialPageFactory;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
@@ -840,6 +841,14 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'SkinFactory' );
        }
 
+       /**
+        * @since 1.33
+        * @return SlotRoleRegistry
+        */
+       public function getSlotRoleRegistry() {
+               return $this->getService( 'SlotRoleRegistry' );
+       }
+
        /**
         * @since 1.31
         * @return NameTableStore
index 3bd7755..15d9786 100644 (file)
@@ -290,6 +290,7 @@ class Message implements MessageSpecifier, Serializable {
                        'format' => $this->format,
                        'useDatabase' => $this->useDatabase,
                        'title' => $this->title,
+                       'titlestr' => $this->title ? $this->title->getFullText() : null,
                ] );
        }
 
@@ -300,6 +301,10 @@ class Message implements MessageSpecifier, Serializable {
         */
        public function unserialize( $serialized ) {
                $data = unserialize( $serialized );
+               if ( !is_array( $data ) ) {
+                       throw new InvalidArgumentException( __METHOD__ . ': Invalid serialized data' );
+               }
+
                $this->interface = $data['interface'];
                $this->key = $data['key'];
                $this->keysToTry = $data['keysToTry'];
@@ -307,7 +312,15 @@ class Message implements MessageSpecifier, Serializable {
                $this->format = $data['format'];
                $this->useDatabase = $data['useDatabase'];
                $this->language = $data['language'] ? Language::factory( $data['language'] ) : false;
-               $this->title = $data['title'];
+
+               if ( isset( $data['titlestr'] ) ) {
+                       $this->title = Title::newFromText( $data['titlestr'] );
+               } elseif ( isset( $data['title'] ) && $data['title'] instanceof Title ) {
+                       // Old serializations from before December 2018
+                       $this->title = $data['title'];
+               } else {
+                       $this->title = null; // Explicit for sanity
+               }
        }
 
        /**
index 0fd697b..bb76395 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\SlotRecord;
 
 /**
  * Handles the backend logic of moving a page from one title
@@ -137,7 +138,8 @@ class MovePage {
                        $status->fatal(
                                'content-not-allowed-here',
                                ContentHandler::getLocalizedName( $this->oldTitle->getContentModel() ),
-                               $this->newTitle->getPrefixedText()
+                               $this->newTitle->getPrefixedText(),
+                               SlotRecord::MAIN
                        );
                }
 
diff --git a/includes/Revision/FallbackSlotRoleHandler.php b/includes/Revision/FallbackSlotRoleHandler.php
new file mode 100644 (file)
index 0000000..78dfd39
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+/**
+ * This file is part of MediaWiki.
+ *
+ * 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
+ */
+
+namespace MediaWiki\Revision;
+
+use MediaWiki\Linker\LinkTarget;
+
+/**
+ * A SlotRoleHandler for providing basic functionality for undefined slot roles.
+ *
+ * This class is intended to be used when encountering slots with a role that used to be defined
+ * by an extension, but no longer is backed by hany specific handler, since the extension in
+ * question has been uninstalled. It may also be used for pages imported from another wiki.
+ *
+ * @since 1.33
+ */
+class FallbackSlotRoleHandler extends SlotRoleHandler {
+
+       public function __construct( $role ) {
+               // treat unknown content as plain text
+               parent::__construct( $role, CONTENT_MODEL_TEXT );
+       }
+
+       /**
+        * @param LinkTarget $page
+        *
+        * @return bool Always false, to prevent undefined slots from being used in new revisions.
+        */
+       public function isAllowedOn( LinkTarget $page ) {
+               return false;
+       }
+
+       /**
+        * @param string $model
+        * @param LinkTarget $page
+        *
+        * @return bool Always false, to prevent undefined slots from being used for
+        *         arbitrary content.
+        */
+       public function isAllowedModel( $model, LinkTarget $page ) {
+               return false;
+       }
+
+       public function getOutputLayoutHints() {
+               // TODO: should be return [ 'display' => 'none'] here, causing undefined slots
+               // to be hidden? We'd still need some place to surface the content of such
+               // slots, see T209923.
+
+               return parent::getOutputLayoutHints(); // TODO: Change the autogenerated stub
+       }
+
+}
diff --git a/includes/Revision/MainSlotRoleHandler.php b/includes/Revision/MainSlotRoleHandler.php
new file mode 100644 (file)
index 0000000..6c6fdd6
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+/**
+ * This file is part of MediaWiki.
+ *
+ * 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
+ */
+
+namespace MediaWiki\Revision;
+
+use ContentHandler;
+use Hooks;
+use MediaWiki\Linker\LinkTarget;
+use Title;
+
+/**
+ * A SlotRoleHandler for the main slot. While most slot roles serve a specific purpose and
+ * thus typically exhibit the same behaviour on all pages, the main slot is used for different
+ * things in different pages, typically depending on the namespace, a "file extension" in
+ * the page name, or the content model of the slot's content.
+ *
+ * MainSlotRoleHandler implements some of the per-namespace and per-model behavior that was
+ * supported prior to MediaWiki Version 1.33.
+ *
+ * @since 1.33
+ */
+class MainSlotRoleHandler extends SlotRoleHandler {
+
+       /**
+        * @var string[] A mapping of namespaces to content models.
+        * @see $wgNamespaceContentModels
+        */
+       private $namespaceContentModels;
+
+       /**
+        * @param string[] $namespaceContentModels A mapping of namespaces to content models,
+        *        typically from $wgNamespaceContentModels.
+        */
+       public function __construct( array $namespaceContentModels ) {
+               parent::__construct( 'main', CONTENT_MODEL_WIKITEXT );
+               $this->namespaceContentModels = $namespaceContentModels;
+       }
+
+       public function supportsArticleCount() {
+               return true;
+       }
+
+       /**
+        * @param string $model
+        * @param LinkTarget $page
+        *
+        * @return bool
+        */
+       public function isAllowedModel( $model, LinkTarget $page ) {
+               $title = Title::newFromLinkTarget( $page );
+               $handler = ContentHandler::getForModelID( $model );
+               return $handler->canBeUsedOn( $title );
+       }
+
+       /**
+        * @param LinkTarget $page
+        *
+        * @return string
+        */
+       public function getDefaultModel( LinkTarget $page ) {
+               // NOTE: this method must not rely on $title->getContentModel() directly or indirectly,
+               //       because it is used to initialize the mContentModel member.
+
+               $ext = '';
+               $ns = $page->getNamespace();
+               $model = $this->namespaceContentModels[$ns] ?? null;
+
+               // Hook can determine default model
+               $title = Title::newFromLinkTarget( $page );
+               if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) ) {
+                       if ( !is_null( $model ) ) {
+                               return $model;
+                       }
+               }
+
+               // Could this page contain code based on the title?
+               $isCodePage = $ns === NS_MEDIAWIKI && preg_match( '!\.(css|js|json)$!u', $title->getText(), $m );
+               if ( $isCodePage ) {
+                       $ext = $m[1];
+               }
+
+               // Is this a user subpage containing code?
+               $isCodeSubpage = $ns === NS_USER
+                       && !$isCodePage
+                       && preg_match( "/\\/.*\\.(js|css|json)$/", $title->getText(), $m );
+
+               if ( $isCodeSubpage ) {
+                       $ext = $m[1];
+               }
+
+               // Is this wikitext, according to $wgNamespaceContentModels or the DefaultModelFor hook?
+               $isWikitext = is_null( $model ) || $model == CONTENT_MODEL_WIKITEXT;
+               $isWikitext = $isWikitext && !$isCodePage && !$isCodeSubpage;
+
+               if ( !$isWikitext ) {
+                       switch ( $ext ) {
+                               case 'js':
+                                       return CONTENT_MODEL_JAVASCRIPT;
+                               case 'css':
+                                       return CONTENT_MODEL_CSS;
+                               case 'json':
+                                       return CONTENT_MODEL_JSON;
+                               default:
+                                       return is_null( $model ) ? CONTENT_MODEL_TEXT : $model;
+                       }
+               }
+
+               // We established that it must be wikitext
+
+               return CONTENT_MODEL_WIKITEXT;
+       }
+
+}
index 6eee3c4..094105a 100644 (file)
@@ -159,6 +159,28 @@ class RenderedRevision implements SlotRenderingProvider {
                return $this->options;
        }
 
+       /**
+        * Sets a ParserOutput to be returned by getRevisionParserOutput().
+        *
+        * @note For internal use by RevisionRenderer only! This method may be modified
+        * or removed without notice per the deprecation policy.
+        *
+        * @internal
+        *
+        * @param ParserOutput $output
+        */
+       public function setRevisionParserOutput( ParserOutput $output ) {
+               $this->revisionOutput = $output;
+
+               // If there is only one slot, we assume that the combined output is identical
+               // with the main slot's output. This is intended to prevent a redundant re-parse of
+               // the content in case getSlotParserOutput( SlotRecord::MAIN ) is called, for instance
+               // from ContentHandler::getSecondaryDataUpdates.
+               if ( $this->revision->getSlotRoles() === [ SlotRecord::MAIN ] ) {
+                       $this->slotsOutput[ SlotRecord::MAIN ] = $output;
+               }
+       }
+
        /**
         * @param array $hints Hints given as an associative array. Known keys:
         *      - 'generate-html' => bool: Whether the caller is interested in output HTML (as opposed
@@ -208,6 +230,7 @@ class RenderedRevision implements SlotRenderingProvider {
                                        'Access to the content has been suppressed for this audience'
                                );
                        } else {
+                               // XXX: allow SlotRoleHandler to control the ParserOutput?
                                $output = $this->getSlotParserOutputUncached( $content, $withHtml );
 
                                if ( $withHtml && !$output->hasText() ) {
index e2e84b6..f97390a 100644 (file)
@@ -50,15 +50,24 @@ class RevisionRenderer {
        /** @var ILoadBalancer */
        private $loadBalancer;
 
+       /** @var SlotRoleRegistry */
+       private $roleRegistery;
+
        /** @var string|bool */
        private $wikiId;
 
        /**
         * @param ILoadBalancer $loadBalancer
+        * @param SlotRoleRegistry $roleRegistry
         * @param bool|string $wikiId
         */
-       public function __construct( ILoadBalancer $loadBalancer, $wikiId = false ) {
+       public function __construct(
+               ILoadBalancer $loadBalancer,
+               SlotRoleRegistry $roleRegistry,
+               $wikiId = false
+       ) {
                $this->loadBalancer = $loadBalancer;
+               $this->roleRegistery = $roleRegistry;
                $this->wikiId = $wikiId;
 
                $this->saveParseLogger = new NullLogger();
@@ -82,6 +91,11 @@ class RevisionRenderer {
         *      - 'audience' the audience to use for content access. Default is
         *        RevisionRecord::FOR_PUBLIC if $forUser is not set, RevisionRecord::FOR_THIS_USER
         *        if $forUser is set. Can be set to RevisionRecord::RAW to disable audience checks.
+        *      - 'known-revision-output' a combined ParserOutput for the revision, perhaps from
+        *        some cache. the caller is responsible for ensuring that the ParserOutput indeed
+        *        matched the $rev and $options. This mechanism is intended as a temporary stop-gap,
+        *        for the time until caches have been changed to store RenderedRevision states instead
+        *        of ParserOutput objects.
         *
         * @return RenderedRevision|null The rendered revision, or null if the audience checks fails.
         */
@@ -133,6 +147,10 @@ class RevisionRenderer {
 
                $renderedRevision->setSaveParseLogger( $this->saveParseLogger );
 
+               if ( isset( $hints['known-revision-output'] ) ) {
+                       $renderedRevision->setRevisionParserOutput( $hints['known-revision-output'] );
+               }
+
                return $renderedRevision;
        }
 
@@ -175,8 +193,6 @@ class RevisionRenderer {
                        return $rrev->getSlotParserOutput( SlotRecord::MAIN );
                }
 
-               // TODO: put fancy layout logic here, see T200915.
-
                // move main slot to front
                if ( isset( $slots[SlotRecord::MAIN] ) ) {
                        $slots = [ SlotRecord::MAIN => $slots[SlotRecord::MAIN] ] + $slots;
@@ -192,6 +208,7 @@ class RevisionRenderer {
                        $out = $rrev->getSlotParserOutput( $role, $hints );
                        $slotOutput[$role] = $out;
 
+                       // XXX: should the SlotRoleHandler be able to intervene here?
                        $combinedOutput->mergeInternalMetaDataFrom( $out, $role );
                        $combinedOutput->mergeTrackingMetaDataFrom( $out );
                }
@@ -201,6 +218,16 @@ class RevisionRenderer {
                        $first = true;
                        /** @var ParserOutput $out */
                        foreach ( $slotOutput as $role => $out ) {
+                               $roleHandler = $this->roleRegistery->getRoleHandler( $role );
+
+                               // TODO: put more fancy layout logic here, see T200915.
+                               $layout = $roleHandler->getOutputLayoutHints();
+                               $display = $layout['display'] ?? 'section';
+
+                               if ( $display === 'none' ) {
+                                       continue;
+                               }
+
                                if ( $first ) {
                                        // skip header for the first slot
                                        $first = false;
@@ -210,6 +237,8 @@ class RevisionRenderer {
                                        $html .= Html::rawElement( 'h1', [ 'class' => 'mw-slot-header' ], $headText );
                                }
 
+                               // XXX: do we want to put a wrapper div around the output?
+                               // Do we want to let $roleHandler do that?
                                $html .= $out->getRawText();
                                $combinedOutput->mergeHtmlMetaDataFrom( $out );
                        }
index 6d3b72c..cf19ffb 100644 (file)
@@ -132,6 +132,9 @@ class RevisionStore
        /** @var int An appropriate combination of SCHEMA_COMPAT_XXX flags. */
        private $mcrMigrationStage;
 
+       /** @var SlotRoleRegistry */
+       private $slotRoleRegistry;
+
        /**
         * @todo $blobStore should be allowed to be any BlobStore!
         *
@@ -146,11 +149,11 @@ class RevisionStore
         * @param CommentStore $commentStore
         * @param NameTableStore $contentModelStore
         * @param NameTableStore $slotRoleStore
+        * @param SlotRoleRegistry $slotRoleRegistry
         * @param int $mcrMigrationStage An appropriate combination of SCHEMA_COMPAT_XXX flags
         * @param ActorMigration $actorMigration
         * @param bool|string $wikiId
         *
-        * @throws MWException if $mcrMigrationStage or $wikiId is invalid.
         */
        public function __construct(
                ILoadBalancer $loadBalancer,
@@ -159,6 +162,7 @@ class RevisionStore
                CommentStore $commentStore,
                NameTableStore $contentModelStore,
                NameTableStore $slotRoleStore,
+               SlotRoleRegistry $slotRoleRegistry,
                $mcrMigrationStage,
                ActorMigration $actorMigration,
                $wikiId = false
@@ -199,6 +203,7 @@ class RevisionStore
                $this->commentStore = $commentStore;
                $this->contentModelStore = $contentModelStore;
                $this->slotRoleStore = $slotRoleStore;
+               $this->slotRoleRegistry = $slotRoleRegistry;
                $this->mcrMigrationStage = $mcrMigrationStage;
                $this->actorMigration = $actorMigration;
                $this->wikiId = $wikiId;
@@ -923,7 +928,7 @@ class RevisionStore
                $format = $content->getDefaultFormat();
                $model = $content->getModel();
 
-               $this->checkContent( $content, $title );
+               $this->checkContent( $content, $title, $slot->getRole() );
 
                return $this->blobStore->storeBlob(
                        $content->serialize( $format ),
@@ -982,11 +987,12 @@ class RevisionStore
         *
         * @param Content $content
         * @param Title $title
+        * @param string $role
         *
         * @throws MWException
         * @throws MWUnknownContentModelException
         */
-       private function checkContent( Content $content, Title $title ) {
+       private function checkContent( Content $content, Title $title, $role ) {
                // Note: may return null for revisions that have not yet been inserted
 
                $model = $content->getModel();
@@ -1005,7 +1011,8 @@ class RevisionStore
 
                        $this->assertCrossWikiContentLoadingIsSafe();
 
-                       $defaultModel = ContentHandler::getDefaultModelFor( $title );
+                       $roleHandler = $this->slotRoleRegistry->getRoleHandler( $role );
+                       $defaultModel = $roleHandler->getDefaultModel( $title );
                        $defaultHandler = ContentHandler::getForModelID( $defaultModel );
                        $defaultFormat = $defaultHandler->getDefaultFormat();
 
@@ -1350,9 +1357,8 @@ class RevisionStore
                        $mainSlotRow->model_name = function ( SlotRecord $slot ) use ( $title ) {
                                $this->assertCrossWikiContentLoadingIsSafe();
 
-                               // TODO: MCR: consider slot role in getDefaultModelFor()! Use LinkTarget!
-                               // TODO: MCR: deprecate $title->getModel().
-                               return ContentHandler::getDefaultModelFor( $title );
+                               return $this->slotRoleRegistry->getRoleHandler( $slot->getRole() )
+                                       ->getDefaultModel( $title );
                        };
                }
 
@@ -1624,7 +1630,7 @@ class RevisionStore
                        $row->role_name = $this->slotRoleStore->getName( (int)$row->slot_role_id );
                        $row->model_name = $this->contentModelStore->getName( (int)$row->content_model );
 
-                       $contentCallback = function ( SlotRecord $slot ) use ( $queryFlags, $row ) {
+                       $contentCallback = function ( SlotRecord $slot ) use ( $queryFlags ) {
                                return $this->loadSlotContent( $slot, null, null, null, $queryFlags );
                        };
 
@@ -2517,45 +2523,78 @@ class RevisionStore
        }
 
        /**
-        * Get previous revision for this title
+        * Get the revision before $rev in the page's history, if any.
+        * Will return null for the first revision but also for deleted or unsaved revisions.
         *
         * MCR migration note: this replaces Revision::getPrevious
         *
+        * @see Title::getPreviousRevisionID
+        * @see PageArchive::getPreviousRevision
+        *
         * @param RevisionRecord $rev
         * @param Title|null $title if known (optional)
         *
         * @return RevisionRecord|null
         */
        public function getPreviousRevision( RevisionRecord $rev, Title $title = null ) {
+               if ( !$rev->getId() || !$rev->getPageId() ) {
+                       // revision is unsaved or otherwise incomplete
+                       return null;
+               }
+
+               if ( $rev instanceof RevisionArchiveRecord ) {
+                       // revision is deleted, so it's not part of the page history
+                       return null;
+               }
+
                if ( $title === null ) {
+                       // this would fail for deleted revisions
                        $title = $this->getTitle( $rev->getPageId(), $rev->getId() );
                }
+
                $prev = $title->getPreviousRevisionID( $rev->getId() );
-               if ( $prev ) {
-                       return $this->getRevisionByTitle( $title, $prev );
+               if ( !$prev ) {
+                       return null;
                }
-               return null;
+
+               return $this->getRevisionByTitle( $title, $prev );
        }
 
        /**
-        * Get next revision for this title
+        * Get the revision after $rev in the page's history, if any.
+        * Will return null for the latest revision but also for deleted or unsaved revisions.
         *
         * MCR migration note: this replaces Revision::getNext
         *
+        * @see Title::getNextRevisionID
+        *
         * @param RevisionRecord $rev
         * @param Title|null $title if known (optional)
         *
         * @return RevisionRecord|null
         */
        public function getNextRevision( RevisionRecord $rev, Title $title = null ) {
+               if ( !$rev->getId() || !$rev->getPageId() ) {
+                       // revision is unsaved or otherwise incomplete
+                       return null;
+               }
+
+               if ( $rev instanceof RevisionArchiveRecord ) {
+                       // revision is deleted, so it's not part of the page history
+                       return null;
+               }
+
                if ( $title === null ) {
+                       // this would fail for deleted revisions
                        $title = $this->getTitle( $rev->getPageId(), $rev->getId() );
                }
+
                $next = $title->getNextRevisionID( $rev->getId() );
-               if ( $next ) {
-                       return $this->getRevisionByTitle( $title, $next );
+               if ( !$next ) {
+                       return null;
                }
-               return null;
+
+               return $this->getRevisionByTitle( $title, $next );
        }
 
        /**
index 30ffc99..6b3117f 100644 (file)
@@ -72,10 +72,14 @@ class RevisionStoreFactory {
        /** @var NameTableStoreFactory */
        private $nameTables;
 
+       /** @var SlotRoleRegistry */
+       private $slotRoleRegistry;
+
        /**
         * @param ILBFactory $dbLoadBalancerFactory
         * @param BlobStoreFactory $blobStoreFactory
         * @param NameTableStoreFactory $nameTables
+        * @param SlotRoleRegistry $slotRoleRegistry
         * @param WANObjectCache $cache
         * @param CommentStore $commentStore
         * @param ActorMigration $actorMigration
@@ -88,6 +92,7 @@ class RevisionStoreFactory {
                ILBFactory $dbLoadBalancerFactory,
                BlobStoreFactory $blobStoreFactory,
                NameTableStoreFactory $nameTables,
+               SlotRoleRegistry $slotRoleRegistry,
                WANObjectCache $cache,
                CommentStore $commentStore,
                ActorMigration $actorMigration,
@@ -98,6 +103,7 @@ class RevisionStoreFactory {
                Assert::parameterType( 'integer', $migrationStage, '$migrationStage' );
                $this->dbLoadBalancerFactory = $dbLoadBalancerFactory;
                $this->blobStoreFactory = $blobStoreFactory;
+               $this->slotRoleRegistry = $slotRoleRegistry;
                $this->nameTables = $nameTables;
                $this->cache = $cache;
                $this->commentStore = $commentStore;
@@ -124,6 +130,7 @@ class RevisionStoreFactory {
                        $this->commentStore,
                        $this->nameTables->getContentModels( $wikiId ),
                        $this->nameTables->getSlotRoles( $wikiId ),
+                       $this->slotRoleRegistry,
                        $this->mcrMigrationStage,
                        $this->actorMigration,
                        $wikiId
diff --git a/includes/Revision/SlotRoleHandler.php b/includes/Revision/SlotRoleHandler.php
new file mode 100644 (file)
index 0000000..85b4c5a
--- /dev/null
@@ -0,0 +1,159 @@
+<?php
+/**
+ * This file is part of MediaWiki.
+ *
+ * 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
+ */
+
+namespace MediaWiki\Revision;
+
+use MediaWiki\Linker\LinkTarget;
+
+/**
+ * SlotRoleHandler instances are used to declare the existence and behavior of slot roles.
+ * Most importantly, they control which content model can be used for the slot, and how it is
+ * represented in the rendered verswion of page content.
+ *
+ * @since 1.33
+ */
+class SlotRoleHandler {
+
+       /**
+        * @var string
+        */
+       private $role;
+
+       /**
+        * @var array
+        * @see getOutputLayoutHints
+        */
+       private $layout = [
+               'display' => 'section', // use 'none' to suppress
+               'region' => 'center',
+               'placement' => 'append'
+       ];
+
+       /**
+        * @var string
+        */
+       private $contentModel;
+
+       /**
+        * @param string $role The name of the slot role defined by this SlotRoleHandler. See
+        *        SlotRoleRegistry::defineRole for more information.
+        * @param string $contentModel The default content model for this slot. As per the default
+        *        implementation of isAllowedModel(), also the only content model allowed for the
+        *        slot. Subclasses may however handle default and allowed models differently.
+        * @param array $layout Layout hints, for use by RevisionRenderer. See getOutputLayoutHints.
+        */
+       public function __construct( $role, $contentModel, $layout = [] ) {
+               $this->role = $role;
+               $this->contentModel = $contentModel;
+               $this->layout = array_merge( $this->layout, $layout );
+       }
+
+       /**
+        * @return string The role this SlotRoleHandler applies to
+        */
+       public function getRole() {
+               return $this->role;
+       }
+
+       /**
+        * Layout hints for use while laying out the combined output of all slots, typically by
+        * RevisionRenderer. The layout hints are given as an associative array. Well-known keys
+        * to use:
+        *
+        * * "display": how the output of this slot should be represented. Supported values:
+        *   - "section": show as a top level section of the region.
+        *   - "none": do not show at all
+        *   Further values that may be supported in the future include "box" and "banner".
+        * * "region": in which region of the page the output should be placed. Supported values:
+        *   - "center": the central content area.
+        *   Further values that may be supported in the future include "top" and "bottom", "left"
+        *   and "right", "header" and "footer".
+        * * "placement": placement relative to other content of the same area.
+        *   - "append": place at the end, after any output processed previously.
+        *   Further values that may be supported in the future include "prepend". A "weight" key
+        *   may be introduced for more fine grained control.
+        *
+        * @return array an associative array of hints
+        */
+       public function getOutputLayoutHints() {
+               return $this->layout;
+       }
+
+       /**
+        * The message key for the translation of the slot name.
+        *
+        * @return string
+        */
+       public function getNameMessageKey() {
+               return 'slot-name-' . $this->role;
+       }
+
+       /**
+        * Determines the content model to use per default for this slot on the given page.
+        *
+        * The default implementation always returns the content model provided to the constructor.
+        * Subclasses may base the choice on default model on the page title or namespace.
+        * The choice should not depend on external state, such as the page content.
+        *
+        * @param LinkTarget $page
+        *
+        * @return string
+        */
+       public function getDefaultModel( LinkTarget $page ) {
+               return $this->contentModel;
+       }
+
+       /**
+        * Determines whether the given model can be used on this slot on the given page.
+        *
+        * The default implementation checks whether $model is the content model provided to the
+        * constructor. Subclasses may allow other models and may base the decision on the page title
+        * or namespace. The choice should not depend on external state, such as the page content.
+        *
+        * @note This should be checked when creating new revisions. Existing revisions
+        *       are not guaranteed to comply with the return value.
+        *
+        * @param string $model
+        * @param LinkTarget $page
+        *
+        * @return bool
+        */
+       public function isAllowedModel( $model, LinkTarget $page ) {
+               return ( $model === $this->contentModel );
+       }
+
+       /**
+        * Whether this slot should be considered when determining whether a page should be counted
+        * as an "article" in the site statistics.
+        *
+        * For a page to be considered countable, one of the page's slots must return true from this
+        * method, and Content::isCountable() must return true for the content of that slot.
+        *
+        * The default implementation always returns false.
+        *
+        * @return string
+        */
+       public function supportsArticleCount() {
+               return false;
+       }
+
+}
diff --git a/includes/Revision/SlotRoleRegistry.php b/includes/Revision/SlotRoleRegistry.php
new file mode 100644 (file)
index 0000000..b108b98
--- /dev/null
@@ -0,0 +1,236 @@
+<?php
+/**
+ * This file is part of MediaWiki.
+ *
+ * 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
+ */
+
+namespace MediaWiki\Revision;
+
+use InvalidArgumentException;
+use LogicException;
+use MediaWiki\Linker\LinkTarget;
+use MediaWiki\Storage\NameTableStore;
+use Wikimedia\Assert\Assert;
+
+/**
+ * A registry service for SlotRoleHandlers, used to define which slot roles are available on
+ * which page.
+ *
+ * Extensions may use the SlotRoleRegistry to register the slots they define.
+ *
+ * In the context of the SlotRoleRegistry, it is useful to distinguish between "defined" and "known"
+ * slot roles: A slot role is "defined" if defineRole() or defineRoleWithModel() was called for
+ * that role. A slot role is "known" if the NameTableStore provided to the constructor as the
+ * $roleNamesStore parameter has an ID associated with that role, which essentially means that
+ * the role at some point has been used on the wiki. Roles that are not "defined" but are
+ * "known" typically belong to extensions that used to be installed on the wiki, but no longer are.
+ * Such slots should be considered ok for display and administrative operations, but only "defined"
+ * slots should be supported for editing.
+ *
+ * @since 1.33
+ */
+class SlotRoleRegistry {
+
+       /**
+        * @var NameTableStore
+        */
+       private $roleNamesStore;
+
+       /**
+        * @var callable[]
+        */
+       private $instantiators = [];
+
+       /**
+        * @var SlotRoleHandler[]
+        */
+       private $handlers;
+
+       /**
+        * SlotRoleRegistry constructor.
+        *
+        * @param NameTableStore $roleNamesStore
+        */
+       public function __construct( NameTableStore $roleNamesStore ) {
+               $this->roleNamesStore = $roleNamesStore;
+       }
+
+       /**
+        * Defines a slot role.
+        *
+        * For use by extensions that wish to define roles beyond the main slot role.
+        *
+        * @see defineRoleWithModel()
+        *
+        * @param string $role The role name of the slot to define. This should follow the
+        *        same convention as message keys:
+        * @param callable $instantiator called with $role as a parameter;
+        *        Signature: function ( string $role ): SlotRoleHandler
+        */
+       public function defineRole( $role, callable $instantiator ) {
+               if ( $this->isDefinedRole( $role ) ) {
+                       throw new LogicException( "Role $role is already defined" );
+               }
+
+               $this->instantiators[$role] = $instantiator;
+       }
+
+       /**
+        * Defines a slot role that allows only the given content model, and has no special
+        * behavior.
+        *
+        * For use by extensions that wish to define roles beyond the main slot role, but have
+        * no need to implement any special behavior for that slot.
+        *
+        * @see defineRole()
+        *
+        * @param string $role The role name of the slot to define, see defineRole()
+        *        for more information.
+        * @param string $model A content model name, see ContentHandler
+        * @param array $layout See SlotRoleHandler getOutputLayoutHints
+        */
+       public function defineRoleWithModel( $role, $model, $layout = [] ) {
+               $this->defineRole(
+                       $role,
+                       function ( $role ) use ( $model, $layout ) {
+                               return new SlotRoleHandler( $role, $model, $layout );
+                       }
+               );
+       }
+
+       /**
+        * Gets the SlotRoleHandler that should be used when processing content of the given role.
+        *
+        * @param string $role
+        *
+        * @throws InvalidArgumentException If $role is not a known slot role.
+        * @return SlotRoleHandler The handler to be used for $role. This may be a
+        *         FallbackSlotRoleHandler if the slot is "known" but not "defined".
+        */
+       public function getRoleHandler( $role ) {
+               if ( !isset( $this->handlers[$role] ) ) {
+                       if ( !$this->isDefinedRole( $role ) ) {
+                               if ( $this->isKnownRole( $role ) ) {
+                                       // The role has no handler defined, but is represented in the database.
+                                       // This may happen e.g. when the extension that defined the role was uninstalled.
+                                       wfWarn( __METHOD__ . ": known but undefined slot role $role" );
+                                       $this->handlers[$role] = new FallbackSlotRoleHandler( $role );
+                               } else {
+                                       // The role doesn't have a handler defined, and is not represented in
+                                       // the database. Something must be quite wrong.
+                                       throw new InvalidArgumentException( "Unknown role $role" );
+                               }
+                       } else {
+                               $handler = call_user_func( $this->instantiators[$role], $role );
+
+                               Assert::postcondition(
+                                       $handler instanceof SlotRoleHandler,
+                                       "Instantiator for $role role must return a SlotRoleHandler"
+                               );
+
+                               $this->handlers[$role] = $handler;
+                       }
+               }
+
+               return $this->handlers[$role];
+       }
+
+       /**
+        * Returns the list of roles allowed when creating a new revision on the given page.
+        * The choice should not depend on external state, such as the page content.
+        * Note that existing revisions of that page are not guaranteed to comply with this list.
+        *
+        * All implementations of this method are required to return at least all "required" roles.
+        *
+        * @param LinkTarget $title
+        *
+        * @return string[]
+        */
+       public function getAllowedRoles( LinkTarget $title ) {
+               // TODO: allow this to be overwritten per namespace (or page type)
+               // TODO: decide how to control which slots are offered for editing per default (T209927)
+               return $this->getDefinedRoles();
+       }
+
+       /**
+        * Returns the list of roles required when creating a new revision on the given page.
+        * The should not depend on external state, such as the page content.
+        * Note that existing revisions of that page are not guaranteed to comply with this list.
+        *
+        * All required roles are implicitly considered "allowed", so any roles
+        * returned by this method will also be returned by getAllowedRoles().
+        *
+        * @param LinkTarget $title
+        *
+        * @return string[]
+        */
+       public function getRequiredRoles( LinkTarget $title ) {
+               // TODO: allow this to be overwritten per namespace (or page type)
+               return [ 'main' ];
+       }
+
+       /**
+        * Returns the list of roles defined by calling defineRole().
+        *
+        * This list should be used when enumerating slot roles that can be used for editing.
+        *
+        * @return string[]
+        */
+       public function getDefinedRoles() {
+               return array_keys( $this->instantiators );
+       }
+
+       /**
+        * Returns the list of known roles, including the ones returned by getDefinedRoles(),
+        * and roles that exist according to the NameTableStore provided to the constructor.
+        *
+        * This list should be used when enumerating slot roles that can be used in queries or
+        * for display.
+        *
+        * @return string[]
+        */
+       public function getKnownRoles() {
+               return array_unique( array_merge(
+                       $this->getDefinedRoles(),
+                       $this->roleNamesStore->getMap()
+               ) );
+       }
+
+       /**
+        * Whether the given role is defined, that is, it was defined by calling defineRole().
+        *
+        * @param string $role
+        * @return bool
+        */
+       public function isDefinedRole( $role ) {
+               return in_array( $role, $this->getDefinedRoles(), true );
+       }
+
+       /**
+        * Whether the given role is known, that is, it's either defined or exist according to
+        * the NameTableStore provided to the constructor.
+        *
+        * @param string $role
+        * @return bool
+        */
+       public function isKnownRole( $role ) {
+               return in_array( $role, $this->getKnownRoles(), true );
+       }
+
+}
index 33517a0..9a94389 100644 (file)
@@ -48,8 +48,10 @@ use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Preferences\PreferencesFactory;
 use MediaWiki\Preferences\DefaultPreferencesFactory;
+use MediaWiki\Revision\MainSlotRoleHandler;
 use MediaWiki\Revision\RevisionFactory;
 use MediaWiki\Revision\RevisionLookup;
+use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Revision\RevisionRenderer;
 use MediaWiki\Revision\RevisionStore;
 use MediaWiki\Revision\RevisionStoreFactory;
@@ -420,9 +422,12 @@ return [
        },
 
        'RevisionRenderer' => function ( MediaWikiServices $services ) : RevisionRenderer {
-               $renderer = new RevisionRenderer( $services->getDBLoadBalancer() );
-               $renderer->setLogger( LoggerFactory::getInstance( 'SaveParse' ) );
+               $renderer = new RevisionRenderer(
+                       $services->getDBLoadBalancer(),
+                       $services->getSlotRoleRegistry()
+               );
 
+               $renderer->setLogger( LoggerFactory::getInstance( 'SaveParse' ) );
                return $renderer;
        },
 
@@ -436,6 +441,7 @@ return [
                        $services->getDBLoadBalancerFactory(),
                        $services->getBlobStoreFactory(),
                        $services->getNameTableStoreFactory(),
+                       $services->getSlotRoleRegistry(),
                        $services->getMainWANObjectCache(),
                        $services->getCommentStore(),
                        $services->getActorMigration(),
@@ -519,6 +525,22 @@ return [
                return $factory;
        },
 
+       'SlotRoleRegistry' => function ( MediaWikiServices $services ) : SlotRoleRegistry {
+               $config = $services->getMainConfig();
+
+               $registry = new SlotRoleRegistry(
+                       $services->getNameTableStoreFactory()->getSlotRoles()
+               );
+
+               $registry->defineRole( 'main', function () use ( $config ) {
+                       return new MainSlotRoleHandler(
+                               $config->get( 'NamespaceContentModels' )
+                       );
+               } );
+
+               return $registry;
+       },
+
        'SpecialPageFactory' => function ( MediaWikiServices $services ) : SpecialPageFactory {
                return new SpecialPageFactory(
                        $services->getMainConfig(),
index b45aeba..c401d44 100644 (file)
@@ -44,6 +44,7 @@ use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\Revision\RevisionRenderer;
 use MediaWiki\Revision\RevisionSlots;
 use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Revision\SlotRecord;
 use MediaWiki\User\UserIdentity;
 use MessageCache;
@@ -209,6 +210,9 @@ class DerivedPageDataUpdater implements IDBAccessObject {
         */
        private $revisionRenderer;
 
+       /** @var SlotRoleRegistry */
+       private $slotRoleRegistry;
+
        /**
         * A stage identifier for managing the life cycle of this instance.
         * Possible stages are 'new', 'knows-current', 'has-content', 'has-revision', and 'done'.
@@ -255,6 +259,7 @@ class DerivedPageDataUpdater implements IDBAccessObject {
         * @param WikiPage $wikiPage ,
         * @param RevisionStore $revisionStore
         * @param RevisionRenderer $revisionRenderer
+        * @param SlotRoleRegistry $slotRoleRegistry
         * @param ParserCache $parserCache
         * @param JobQueueGroup $jobQueueGroup
         * @param MessageCache $messageCache
@@ -265,6 +270,7 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                WikiPage $wikiPage,
                RevisionStore $revisionStore,
                RevisionRenderer $revisionRenderer,
+               SlotRoleRegistry $slotRoleRegistry,
                ParserCache $parserCache,
                JobQueueGroup $jobQueueGroup,
                MessageCache $messageCache,
@@ -276,6 +282,7 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                $this->parserCache = $parserCache;
                $this->revisionStore = $revisionStore;
                $this->revisionRenderer = $revisionRenderer;
+               $this->slotRoleRegistry = $slotRoleRegistry;
                $this->jobQueueGroup = $jobQueueGroup;
                $this->messageCache = $messageCache;
                $this->contLang = $contLang;
@@ -636,12 +643,26 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                $hasLinks = null;
 
                if ( $this->articleCountMethod === 'link' ) {
+                       // NOTE: it would be more appropriate to determine for each slot separately
+                       // whether it has links, and use that information with that slot's
+                       // isCountable() method. However, that would break parity with
+                       // WikiPage::isCountable, which uses the pagelinks table to determine
+                       // whether the current revision has links.
                        $hasLinks = (bool)count( $this->getCanonicalParserOutput()->getLinks() );
                }
 
-               // TODO: MCR: ask all slots if they have links [SlotHandler/PageTypeHandler]
-               $mainContent = $this->getRawContent( SlotRecord::MAIN );
-               return $mainContent->isCountable( $hasLinks );
+               foreach ( $this->getModifiedSlotRoles() as $role ) {
+                       $roleHandler = $this->slotRoleRegistry->getRoleHandler( $role );
+                       if ( $roleHandler->supportsArticleCount() ) {
+                               $content = $this->getRawContent( $role );
+
+                               if ( $content->isCountable( $hasLinks ) ) {
+                                       return true;
+                               }
+                       }
+               }
+
+               return false;
        }
 
        /**
@@ -649,6 +670,7 @@ class DerivedPageDataUpdater implements IDBAccessObject {
         */
        public function isRedirect() {
                // NOTE: main slot determines redirect status
+               // TODO: MCR: this should be controlled by a PageTypeHandler
                $mainContent = $this->getRawContent( SlotRecord::MAIN );
 
                return $mainContent->isRedirect();
@@ -738,17 +760,6 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                        $stashedEdit = ApiStashEdit::checkCache( $title, $mainContent, $legacyUser );
                }
 
-               if ( $stashedEdit ) {
-                       /** @var ParserOutput $output */
-                       $output = $stashedEdit->output;
-
-                       // TODO: this should happen when stashing the ParserOutput, not now!
-                       $output->setCacheTime( $stashedEdit->timestamp );
-
-                       // TODO: MCR: allow output for all slots to be stashed.
-                       $this->canonicalParserOutput = $output;
-               }
-
                $userPopts = ParserOptions::newFromUserAndLang( $user, $this->contLang );
                Hooks::run( 'ArticlePrepareTextForEdit', [ $wikiPage, $userPopts ] );
 
@@ -829,6 +840,27 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                } else {
                        $this->parentRevision = $parentRevision;
                }
+
+               $renderHints = [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ];
+
+               if ( $stashedEdit ) {
+                       /** @var ParserOutput $output */
+                       $output = $stashedEdit->output;
+
+                       // TODO: this should happen when stashing the ParserOutput, not now!
+                       $output->setCacheTime( $stashedEdit->timestamp );
+
+                       $renderHints['known-revision-output'] = $output;
+               }
+
+               // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+               // NOTE: the revision is either new or current, so we can bypass audience checks.
+               $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+                       $this->revision,
+                       null,
+                       null,
+                       $renderHints
+               );
        }
 
        /**
@@ -855,18 +887,7 @@ class DerivedPageDataUpdater implements IDBAccessObject {
         * @return RenderedRevision
         */
        public function getRenderedRevision() {
-               if ( !$this->renderedRevision ) {
-                       $this->assertPrepared( __METHOD__ );
-
-                       // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
-                       // NOTE: the revision is either new or current, so we can bypass audience checks.
-                       $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
-                               $this->revision,
-                               null,
-                               null,
-                               [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
-                       );
-               }
+               $this->assertPrepared( __METHOD__ );
 
                return $this->renderedRevision;
        }
@@ -1186,6 +1207,19 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                // Prune any output that depends on the revision ID.
                if ( $this->renderedRevision ) {
                        $this->renderedRevision->updateRevision( $revision );
+               } else {
+
+                       // NOTE: we want a canonical rendering, so don't pass $this->user or ParserOptions
+                       // NOTE: the revision is either new or current, so we can bypass audience checks.
+                       $this->renderedRevision = $this->revisionRenderer->getRenderedRevision(
+                               $this->revision,
+                               null,
+                               null,
+                               [ 'use-master' => $this->useMaster(), 'audience' => RevisionRecord::RAW ]
+                       );
+
+                       // XXX: Since we presumably are dealing with the current revision,
+                       // we could try to get the ParserOutput from the parser cache.
                }
 
                // TODO: optionally get ParserOutput from the ParserCache here.
@@ -1383,12 +1417,9 @@ class DerivedPageDataUpdater implements IDBAccessObject {
                        // the recent change entry (also done via deferred updates) and carry over any
                        // bot/deletion/IP flags, ect.
                        $this->jobQueueGroup->lazyPush(
-                               new CategoryMembershipChangeJob(
+                               CategoryMembershipChangeJob::newSpec(
                                        $this->getTitle(),
-                                       [
-                                               'pageId' => $this->getPageId(),
-                                               'revTimestamp' => $this->revision->getTimestamp(),
-                                       ]
+                                       $this->revision->getTimestamp()
                                )
                        );
                }
index c1dd09d..27194ab 100644 (file)
@@ -205,7 +205,7 @@ class NameTableStore {
         *
         * @param int $connFlags ILoadBalancer::CONN_XXX flags. Optional.
         *
-        * @return \string[] The freshly reloaded name map
+        * @return string[] The freshly reloaded name map
         */
        public function reloadMap( $connFlags = 0 ) {
                $this->tableCache = $this->loadTable(
index 043e00e..6cbdcc6 100644 (file)
@@ -31,7 +31,6 @@ use Content;
 use ContentHandler;
 use DeferredUpdates;
 use Hooks;
-use InvalidArgumentException;
 use LogicException;
 use ManualLogEntry;
 use MediaWiki\Linker\LinkTarget;
@@ -39,6 +38,7 @@ use MediaWiki\Revision\MutableRevisionRecord;
 use MediaWiki\Revision\RevisionAccessException;
 use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Revision\SlotRecord;
 use MWException;
 use RecentChange;
@@ -96,6 +96,11 @@ class PageUpdater {
         */
        private $revisionStore;
 
+       /**
+        * @var SlotRoleRegistry
+        */
+       private $slotRoleRegistry;
+
        /**
         * @var boolean see $wgUseAutomaticEditSummaries
         * @see $wgUseAutomaticEditSummaries
@@ -148,13 +153,15 @@ class PageUpdater {
         * @param DerivedPageDataUpdater $derivedDataUpdater
         * @param LoadBalancer $loadBalancer
         * @param RevisionStore $revisionStore
+        * @param SlotRoleRegistry $slotRoleRegistry
         */
        public function __construct(
                User $user,
                WikiPage $wikiPage,
                DerivedPageDataUpdater $derivedDataUpdater,
                LoadBalancer $loadBalancer,
-               RevisionStore $revisionStore
+               RevisionStore $revisionStore,
+               SlotRoleRegistry $slotRoleRegistry
        ) {
                $this->user = $user;
                $this->wikiPage = $wikiPage;
@@ -162,6 +169,7 @@ class PageUpdater {
 
                $this->loadBalancer = $loadBalancer;
                $this->revisionStore = $revisionStore;
+               $this->slotRoleRegistry = $slotRoleRegistry;
 
                $this->slotsUpdate = new RevisionSlotsUpdate();
        }
@@ -317,14 +325,6 @@ class PageUpdater {
                return $this->derivedDataUpdater->grabCurrentRevision();
        }
 
-       /**
-        * @return string
-        */
-       private function getTimestampNow() {
-               // TODO: allow an override to be injected for testing
-               return wfTimestampNow();
-       }
-
        /**
         * Check flags and add EDIT_NEW or EDIT_UPDATE to them as needed.
         *
@@ -346,8 +346,7 @@ class PageUpdater {
         * @param Content $content
         */
        public function setContent( $role, Content $content ) {
-               // TODO: MCR: check the role and the content's model against the list of supported
-               // roles, see T194046.
+               $this->ensureRoleAllowed( $role );
 
                $this->slotsUpdate->modifyContent( $role, $content );
        }
@@ -358,6 +357,8 @@ class PageUpdater {
         * @param SlotRecord $slot
         */
        public function setSlot( SlotRecord $slot ) {
+               $this->ensureRoleAllowed( $slot->getRole() );
+
                $this->slotsUpdate->modifySlot( $slot );
        }
 
@@ -376,6 +377,7 @@ class PageUpdater {
         *        by the new revision.
         */
        public function inheritSlot( SlotRecord $originalSlot ) {
+               // NOTE: slots can be inherited even if the role is not "allowed" on the title.
                // NOTE: this slot is inherited from some other revision, but it's
                // a "modified" slot for the RevisionSlotsUpdate and DerivedPageDataUpdater,
                // since it's not implicitly inherited from the parent revision.
@@ -393,9 +395,7 @@ class PageUpdater {
         * @param string $role A slot role name (but not "main")
         */
        public function removeSlot( $role ) {
-               if ( $role === SlotRecord::MAIN ) {
-                       throw new InvalidArgumentException( 'Cannot remove the main slot!' );
-               }
+               $this->ensureRoleNotRequired( $role );
 
                $this->slotsUpdate->removeSlot( $role );
        }
@@ -635,20 +635,38 @@ class PageUpdater {
                        throw new RuntimeException( 'Something is trying to edit an article with an empty title' );
                }
 
-               // TODO: MCR: check the role and the content's model against the list of supported
-               // and required roles, see T194046.
+               // NOTE: slots can be inherited even if the role is not "allowed" on the title.
+               $status = Status::newGood();
+               $this->checkAllRolesAllowed(
+                       $this->slotsUpdate->getModifiedRoles(),
+                       $status
+               );
+               $this->checkNoRolesRequired(
+                       $this->slotsUpdate->getRemovedRoles(),
+                       $status
+               );
 
-               // Make sure the given content type is allowed for this page
-               // TODO: decide: Extend check to other slots? Consider the role in check? [PageType]
-               $mainContentHandler = $this->getContentHandler( SlotRecord::MAIN );
-               if ( !$mainContentHandler->canBeUsedOn( $this->getTitle() ) ) {
-                       $this->status = Status::newFatal( 'content-not-allowed-here',
-                               ContentHandler::getLocalizedName( $mainContentHandler->getModelID() ),
-                               $this->getTitle()->getPrefixedText()
-                       );
+               if ( !$status->isOK() ) {
                        return null;
                }
 
+               // Make sure the given content is allowed in the respective slots of this page
+               foreach ( $this->slotsUpdate->getModifiedRoles() as $role ) {
+                       $slot = $this->slotsUpdate->getModifiedSlot( $role );
+                       $roleHandler = $this->slotRoleRegistry->getRoleHandler( $role );
+
+                       if ( !$roleHandler->isAllowedModel( $slot->getModel(), $this->getTitle() ) ) {
+                               $contentHandler = ContentHandler::getForModelID( $slot->getModel() );
+                               $this->status = Status::newFatal( 'content-not-allowed-here',
+                                       ContentHandler::getLocalizedName( $contentHandler->getModelID() ),
+                                       $this->getTitle()->getPrefixedText(),
+                                       wfMessage( $roleHandler->getNameMessageKey() )
+                                       // TODO: defer message lookup to caller
+                               );
+                               return null;
+                       }
+               }
+
                // Load the data from the master database if needed. Needed to check flags.
                // NOTE: This grabs the parent revision as the CAS token, if grabParentRevision
                // wasn't called yet. If the page is modified by another process before we are done with
@@ -882,13 +900,19 @@ class PageUpdater {
                        $content = $slot->getContent();
 
                        // XXX: We may push this up to the "edit controller" level, see T192777.
-                       // TODO: change the signature of PrepareSave to not take a WikiPage!
+                       // XXX: prepareSave() and isValid() could live in SlotRoleHandler
+                       // XXX: PrepareSave should not take a WikiPage!
                        $prepStatus = $content->prepareSave( $wikiPage, $flags, $oldid, $user );
 
                        // TODO: MCR: record which problem arose in which slot.
                        $status->merge( $prepStatus );
                }
 
+               $this->checkAllRequiredRoles(
+                       $rev->getSlotRoles(),
+                       $status
+               );
+
                return $rev;
        }
 
@@ -1216,4 +1240,71 @@ class PageUpdater {
                );
        }
 
+       /**
+        * @return string[] Slots required for this page update, as a list of role names.
+        */
+       private function getRequiredSlotRoles() {
+               return $this->slotRoleRegistry->getRequiredRoles( $this->getTitle() );
+       }
+
+       /**
+        * @return string[] Slots allowed for this page update, as a list of role names.
+        */
+       private function getAllowedSlotRoles() {
+               return $this->slotRoleRegistry->getAllowedRoles( $this->getTitle() );
+       }
+
+       private function ensureRoleAllowed( $role ) {
+               $allowedRoles = $this->getAllowedSlotRoles();
+               if ( !in_array( $role, $allowedRoles ) ) {
+                       throw new PageUpdateException( "Slot role `$role` is not allowed." );
+               }
+       }
+
+       private function ensureRoleNotRequired( $role ) {
+               $requiredRoles = $this->getRequiredSlotRoles();
+               if ( in_array( $role, $requiredRoles ) ) {
+                       throw new PageUpdateException( "Slot role `$role` is required." );
+               }
+       }
+
+       private function checkAllRolesAllowed( array $roles, Status $status ) {
+               $allowedRoles = $this->getAllowedSlotRoles();
+
+               $forbidden = array_diff( $roles, $allowedRoles );
+               if ( !empty( $forbidden ) ) {
+                       $status->error(
+                               'edit-slots-cannot-add',
+                               count( $forbidden ),
+                               implode( ', ', $forbidden )
+                       );
+               }
+       }
+
+       private function checkNoRolesRequired( array $roles, Status $status ) {
+               $requiredRoles = $this->getRequiredSlotRoles();
+
+               $needed = array_diff( $roles, $requiredRoles );
+               if ( !empty( $needed ) ) {
+                       $status->error(
+                               'edit-slots-cannot-remove',
+                               count( $needed ),
+                               implode( ', ', $needed )
+                       );
+               }
+       }
+
+       private function checkAllRequiredRoles( array $roles, Status $status ) {
+               $requiredRoles = $this->getRequiredSlotRoles();
+
+               $missing = array_diff( $requiredRoles, $roles );
+               if ( !empty( $missing ) ) {
+                       $status->error(
+                               'edit-slots-missing',
+                               count( $missing ),
+                               implode( ', ', $missing )
+                       );
+               }
+       }
+
 }
index c151f4a..8b4075b 100644 (file)
@@ -978,6 +978,8 @@ class Title implements LinkTarget {
        /**
         * Get the page's content model id, see the CONTENT_MODEL_XXX constants.
         *
+        * @todo Deprecate this in favor of SlotRecord::getModel()
+        *
         * @param int $flags A bit field; may be Title::GAID_FOR_UPDATE to select for update
         * @return string Content model id
         */
@@ -2688,30 +2690,14 @@ class Title implements LinkTarget {
                }
 
                $useReplica = ( $rigor !== 'secure' );
-               $block = $user->getBlock( $useReplica );
-
-               // The block may explicitly allow an action (like "read" or "upload").
-               if ( $block && $block->prevents( $action ) === false ) {
-                       return $errors;
-               }
-
-               // Determine if the user is blocked from this action on this page.
-               try {
+               if ( ( $action == 'edit' || $action == 'create' )
+                       && !$user->isBlockedFrom( $this, $useReplica )
+               ) {
+                       // Don't block the user from editing their own talk page unless they've been
+                       // explicitly blocked from that too.
+               } elseif ( $user->isBlocked() && $user->getBlock()->prevents( $action ) !== false ) {
                        // @todo FIXME: Pass the relevant context into this function.
-                       $action = Action::factory( $action, WikiPage::factory( $this ), RequestContext::getMain() );
-               } catch ( Exception $e ) {
-                       $action = null;
-               }
-
-               // If no action object is returned, assume that the action requires unblock
-               // which is the default.
-               if ( !$action || $action->requiresUnblock() ) {
-                       if ( $user->isBlockedFrom( $this, $useReplica ) ) {
-                               // @todo FIXME: Pass the relevant context into this function.
-                               $errors[] = $block
-                                       ? $block->getPermissionsError( RequestContext::getMain() )
-                                       : [ 'badaccess-group0' ];
-                       }
+                       $errors[] = $user->getBlock()->getPermissionsError( RequestContext::getMain() );
                }
 
                return $errors;
index d014503..25e4aae 100644 (file)
@@ -174,7 +174,7 @@ class InfoAction extends FormlessAction {
         * @param string $table The table that will be added to the content
         * @param string $name The name of the row
         * @param string $value The value of the row
-        * @param string $id The ID to use for the 'tr' element
+        * @param string|null $id The ID to use for the 'tr' element
         * @return string The table with the row added
         */
        protected function addRow( $table, $name, $value, $id ) {
index 1149d1e..32156d8 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 use Wikimedia\Rdbms\IDatabase;
+use MediaWiki\MediaWikiServices;
 
 /**
  * This abstract class implements many basic API functions, and is the base of
@@ -2069,11 +2070,41 @@ abstract class ApiBase extends ContextSource {
                foreach ( (array)$actions as $action ) {
                        $errors = array_merge( $errors, $title->getUserPermissionsErrors( $action, $user ) );
                }
+
                if ( $errors ) {
+                       // track block notices
+                       if ( $this->getConfig()->get( 'EnableBlockNoticeStats' ) ) {
+                               $this->trackBlockNotices( $errors );
+                       }
+
                        $this->dieStatus( $this->errorArrayToStatus( $errors, $user ) );
                }
        }
 
+       /**
+        * Keep track of errors messages resulting from a block
+        *
+        * @param array $errors
+        */
+       private function trackBlockNotices( array $errors ) {
+               $errorMessageKeys = [
+                       'blockedtext',
+                       'blockedtext-partial',
+                       'autoblockedtext',
+                       'systemblockedtext',
+               ];
+
+               $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
+
+               foreach ( $errors as $error ) {
+                       if ( in_array( $error[0], $errorMessageKeys ) ) {
+                               $wiki = $this->getConfig()->get( 'DBname' );
+                               $statsd->increment( 'BlockNotices.' . $wiki . '.MediaWikiApi.returned' );
+                               break;
+                       }
+               }
+       }
+
        /**
         * Will only set a warning instead of failing if the global $wgDebugAPI
         * is set to true. Otherwise behaves exactly as self::dieWithError().
index 76b7bce..393f435 100644 (file)
@@ -30,11 +30,15 @@ class ApiComparePages extends ApiBase {
        /** @var RevisionStore */
        private $revisionStore;
 
+       /** @var \MediaWiki\Revision\SlotRoleRegistry */
+       private $slotRoleRegistry;
+
        private $guessedTitle = false, $props;
 
        public function __construct( ApiMain $mainModule, $moduleName, $modulePrefix = '' ) {
                parent::__construct( $mainModule, $moduleName, $modulePrefix );
                $this->revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
+               $this->slotRoleRegistry = MediaWikiServices::getInstance()->getSlotRoleRegistry();
        }
 
        public function execute() {
@@ -272,9 +276,8 @@ class ApiComparePages extends ApiBase {
                }
 
                $guessedTitle = $this->guessTitle();
-               if ( $guessedTitle && $role === SlotRecord::MAIN ) {
-                       // @todo: Use SlotRoleRegistry and do this for all slots
-                       return $guessedTitle->getContentModel();
+               if ( $guessedTitle ) {
+                       return $this->slotRoleRegistry->getRoleHandler( $role )->getDefaultModel( $guessedTitle );
                }
 
                if ( isset( $params["fromcontentmodel-$role"] ) ) {
@@ -582,10 +585,7 @@ class ApiComparePages extends ApiBase {
        }
 
        public function getAllowedParams() {
-               $slotRoles = MediaWikiServices::getInstance()->getSlotRoleStore()->getMap();
-               if ( !in_array( SlotRecord::MAIN, $slotRoles, true ) ) {
-                       $slotRoles[] = SlotRecord::MAIN;
-               }
+               $slotRoles = $this->slotRoleRegistry->getKnownRoles();
                sort( $slotRoles, SORT_STRING );
 
                // Parameters for the 'from' and 'to' content
index 847afd8..a37ecc2 100644 (file)
@@ -58,6 +58,26 @@ class ApiErrorFormatter {
                $this->format = $format;
        }
 
+       /**
+        * Test whether a code is a valid API error code
+        *
+        * A valid code contains only ASCII letters, numbers, underscore, and
+        * hyphen and is not the empty string.
+        *
+        * For backwards compatibility, any code beginning 'internal_api_error_' is
+        * also allowed.
+        *
+        * @param string $code
+        * @return bool
+        */
+       public static function isValidApiCode( $code ) {
+               return is_string( $code ) && (
+                       preg_match( '/^[a-zA-Z0-9_-]+$/', $code ) ||
+                       // TODO: Deprecate this
+                       preg_match( '/^internal_api_error_[^\0\r\n]+$/', $code )
+               );
+       }
+
        /**
         * Return a formatter like this one but with a different format
         *
@@ -191,6 +211,7 @@ class ApiErrorFormatter {
                                if ( !isset( $options['code'] ) ) {
                                        $class = preg_replace( '#^Wikimedia\\\Rdbms\\\#', '', get_class( $exception ) );
                                        $options['code'] = 'internal_api_error_' . $class;
+                                       $options['data']['errorclass'] = get_class( $exception );
                                }
                        }
                        $params = [ wfEscapeWikiText( $exception->getMessage() ) ];
index 5bf8da9..9edf929 100644 (file)
@@ -172,33 +172,29 @@ class ApiFeedContributions extends ApiBase {
         * @return string
         */
        protected function feedItemDesc( RevisionRecord $revision ) {
-               if ( $revision ) {
-                       $msg = wfMessage( 'colon-separator' )->inContentLanguage()->text();
-                       try {
-                               $content = $revision->getContent( SlotRecord::MAIN );
-                       } catch ( RevisionAccessException $e ) {
-                               $content = null;
-                       }
-
-                       if ( $content instanceof TextContent ) {
-                               // only textual content has a "source view".
-                               $html = nl2br( htmlspecialchars( $content->getNativeData() ) );
-                       } else {
-                               // XXX: we could get an HTML representation of the content via getParserOutput, but that may
-                               //     contain JS magic and generally may not be suitable for inclusion in a feed.
-                               //     Perhaps Content should have a getDescriptiveHtml method and/or a getSourceText method.
-                               // Compare also FeedUtils::formatDiffRow.
-                               $html = '';
-                       }
-
-                       $comment = $revision->getComment();
+               $msg = wfMessage( 'colon-separator' )->inContentLanguage()->text();
+               try {
+                       $content = $revision->getContent( SlotRecord::MAIN );
+               } catch ( RevisionAccessException $e ) {
+                       $content = null;
+               }
 
-                       return '<p>' . htmlspecialchars( $this->feedItemAuthor( $revision ) ) . $msg .
-                               htmlspecialchars( FeedItem::stripComment( $comment ? $comment->text : '' ) ) .
-                               "</p>\n<hr />\n<div>" . $html . '</div>';
+               if ( $content instanceof TextContent ) {
+                       // only textual content has a "source view".
+                       $html = nl2br( htmlspecialchars( $content->getNativeData() ) );
+               } else {
+                       // XXX: we could get an HTML representation of the content via getParserOutput, but that may
+                       //     contain JS magic and generally may not be suitable for inclusion in a feed.
+                       //     Perhaps Content should have a getDescriptiveHtml method and/or a getSourceText method.
+                       // Compare also FeedUtils::formatDiffRow.
+                       $html = '';
                }
 
-               return '';
+               $comment = $revision->getComment();
+
+               return '<p>' . htmlspecialchars( $this->feedItemAuthor( $revision ) ) . $msg .
+                       htmlspecialchars( FeedItem::stripComment( $comment ? $comment->text : '' ) ) .
+                       "</p>\n<hr />\n<div>" . $html . '</div>';
        }
 
        public function getAllowedParams() {
index 22232dd..bc76f8f 100644 (file)
@@ -834,7 +834,11 @@ class ApiMain extends ApiBase {
                foreach ( $requestedHeaders as $rHeader ) {
                        $rHeader = strtolower( trim( $rHeader ) );
                        if ( !isset( $allowedAuthorHeaders[$rHeader] ) ) {
-                               wfDebugLog( 'api', 'CORS preflight failed on requested header: ' . $rHeader );
+                               LoggerFactory::getInstance( 'api-warning' )->warning(
+                                       'CORS preflight failed on requested header: {header}', [
+                                               'header' => $rHeader
+                                       ]
+                               );
                                return false;
                        }
                }
@@ -1025,8 +1029,10 @@ class ApiMain extends ApiBase {
                } else {
                        // Something is seriously wrong
                        $config = $this->getConfig();
+                       // TODO: Avoid embedding arbitrary class names in the error code.
                        $class = preg_replace( '#^Wikimedia\\\Rdbms\\\#', '', get_class( $e ) );
                        $code = 'internal_api_error_' . $class;
+                       $data = [ 'errorclass' => get_class( $e ) ];
                        if ( $config->get( 'ShowExceptionDetails' ) ) {
                                if ( $e instanceof ILocalizedException ) {
                                        $msg = $e->getMessageObject();
@@ -1040,7 +1046,7 @@ class ApiMain extends ApiBase {
                                $params = [ 'apierror-exceptioncaughttype', WebRequest::getRequestId(), get_class( $e ) ];
                        }
 
-                       $messages[] = ApiMessage::create( $params, $code );
+                       $messages[] = ApiMessage::create( $params, $code, $data );
                }
                return $messages;
        }
@@ -1077,7 +1083,15 @@ class ApiMain extends ApiBase {
                // Add errors from the exception
                $modulePath = $e instanceof ApiUsageException ? $e->getModulePath() : null;
                foreach ( $this->errorMessagesFromException( $e, 'error' ) as $msg ) {
-                       $errorCodes[$msg->getApiCode()] = true;
+                       if ( ApiErrorFormatter::isValidApiCode( $msg->getApiCode() ) ) {
+                               $errorCodes[$msg->getApiCode()] = true;
+                       } else {
+                               LoggerFactory::getInstance( 'api-warning' )->error( 'Invalid API error code "{code}"', [
+                                       'code' => $msg->getApiCode(),
+                                       'exception' => $e,
+                               ] );
+                               $errorCodes['<invalid-code>'] = true;
+                       }
                        $formatter->addError( $modulePath, $msg );
                }
                foreach ( $this->errorMessagesFromException( $e, 'warning' ) as $msg ) {
@@ -1464,9 +1478,14 @@ class ApiMain extends ApiBase {
                if ( $numLagged >= ceil( $replicaCount / 2 ) ) {
                        $laggedServers = implode( ', ', $laggedServers );
                        wfDebugLog(
-                               'api-readonly',
+                               'api-readonly', // Deprecate this channel in favor of api-warning?
                                "Api request failed as read only because the following DBs are lagged: $laggedServers"
                        );
+                       LoggerFactory::getInstance( 'api-warning' )->warning(
+                               "Api request failed as read only because the following DBs are lagged: {laggeddbs}", [
+                                       'laggeddbs' => $laggedServers,
+                               ]
+                       );
 
                        $this->dieWithError(
                                'readonly_lag',
index 18b6bc4..6894d28 100644 (file)
@@ -105,12 +105,15 @@ trait ApiMessageTrait {
                        } else {
                                $this->apiCode = $key;
                        }
+
+                       // Ensure the code is actually valid
+                       $this->apiCode = preg_replace( '/[^a-zA-Z0-9_-]/', '_', $this->apiCode );
                }
                return $this->apiCode;
        }
 
        public function setApiCode( $code, array $data = null ) {
-               if ( $code !== null && !( is_string( $code ) && $code !== '' ) ) {
+               if ( $code !== null && !ApiErrorFormatter::isValidApiCode( $code ) ) {
                        throw new InvalidArgumentException( "Invalid code \"$code\"" );
                }
 
index 7b4f15e..7a1c461 100644 (file)
@@ -43,8 +43,6 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
         * @return void
         */
        protected function run( ApiPageSet $resultPageSet = null ) {
-               global $wgChangeTagsSchemaMigrationStage;
-
                // Before doing anything at all, let's check permissions
                $this->checkUserRightsAny( 'deletedhistory' );
 
@@ -127,11 +125,7 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                }
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ 'ar_rev_id=ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'archive' ) ] );
                }
 
                if ( !is_null( $params['tag'] ) ) {
@@ -139,16 +133,12 @@ class ApiQueryAllDeletedRevisions extends ApiQueryRevisionsBase {
                        $this->addJoinConds(
                                [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
                        );
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               try {
-                                       $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
-                               } catch ( NameTableAccessException $exception ) {
-                                       // Return nothing.
-                                       $this->addWhere( '1=0' );
-                               }
-                       } else {
-                               $this->addWhereFld( 'ct_tag', $params['tag'] );
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       try {
+                               $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
+                       } catch ( NameTableAccessException $exception ) {
+                               // Return nothing.
+                               $this->addWhere( '1=0' );
                        }
                }
 
index 922d2c3..5343c33 100644 (file)
@@ -140,11 +140,7 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                $this->addTimestampWhereRange( $tsField, $dir, $params['start'], $params['end'] );
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ 'rev_id=ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'revision' ) ] );
                }
 
                if ( $params['user'] !== null ) {
index 35cb83a..f4e7463 100644 (file)
@@ -418,7 +418,7 @@ class ApiQueryBacklinks extends ApiQueryGeneratorBase {
                if ( is_null( $resultPageSet ) ) {
                        // Try to add the result data in one go and pray that it fits
                        $code = $this->bl_code;
-                       $data = array_map( function ( $arr ) use ( $result, $code ) {
+                       $data = array_map( function ( $arr ) use ( $code ) {
                                if ( isset( $arr['redirlinks'] ) ) {
                                        $arr['redirlinks'] = array_values( $arr['redirlinks'] );
                                        ApiResult::setIndexedTagName( $arr['redirlinks'], $code );
index 8f71c1c..9275a7c 100644 (file)
@@ -39,8 +39,6 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
        }
 
        protected function run( ApiPageSet $resultPageSet = null ) {
-               global $wgChangeTagsSchemaMigrationStage;
-
                $user = $this->getUser();
                // Before doing anything at all, let's check permissions
                $this->checkUserRightsAny( 'deletedhistory' );
@@ -79,11 +77,7 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
                }
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ 'ar_rev_id=ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'archive' ) ] );
                }
 
                if ( !is_null( $params['tag'] ) ) {
@@ -91,16 +85,12 @@ class ApiQueryDeletedRevisions extends ApiQueryRevisionsBase {
                        $this->addJoinConds(
                                [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
                        );
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               try {
-                                       $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
-                               } catch ( NameTableAccessException $exception ) {
-                                       // Return nothing.
-                                       $this->addWhere( '1=0' );
-                               }
-                       } else {
-                               $this->addWhereFld( 'ct_tag', $params['tag'] );
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       try {
+                               $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
+                       } catch ( NameTableAccessException $exception ) {
+                               // Return nothing.
+                               $this->addWhere( '1=0' );
                        }
                }
 
index e84b9b2..8540190 100644 (file)
@@ -36,8 +36,6 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
        }
 
        public function execute() {
-               global $wgChangeTagsSchemaMigrationStage;
-
                // Before doing anything at all, let's check permissions
                $this->checkUserRightsAny( 'deletedhistory' );
 
@@ -133,11 +131,7 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                }
 
                if ( $fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ 'ar_rev_id=ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'archive' ) ] );
                }
 
                if ( !is_null( $params['tag'] ) ) {
@@ -145,16 +139,12 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        $this->addJoinConds(
                                [ 'change_tag' => [ 'INNER JOIN', [ 'ar_rev_id=ct_rev_id' ] ] ]
                        );
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               try {
-                                       $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
-                               } catch ( NameTableAccessException $exception ) {
-                                       // Return nothing.
-                                       $this->addWhere( '1=0' );
-                               }
-                       } else {
-                               $this->addWhereFld( 'ct_tag', $params['tag'] );
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       try {
+                               $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
+                       } catch ( NameTableAccessException $exception ) {
+                               // Return nothing.
+                               $this->addWhere( '1=0' );
                        }
                }
 
index 3cb55e4..edf7002 100644 (file)
@@ -42,8 +42,6 @@ class ApiQueryLogEvents extends ApiQueryBase {
                $fld_details = false, $fld_tags = false;
 
        public function execute() {
-               global $wgChangeTagsSchemaMigrationStage;
-
                $params = $this->extractRequestParams();
                $db = $this->getDB();
                $this->commentStore = CommentStore::getStore();
@@ -109,25 +107,19 @@ class ApiQueryLogEvents extends ApiQueryBase {
                }
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds( [ 'tag_summary' => [ 'LEFT JOIN', 'log_id=ts_log_id' ] ] );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'logging' ) ] );
                }
 
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN',
                                [ 'log_id=ct_log_id' ] ] ] );
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               try {
-                                       $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
-                               } catch ( NameTableAccessException $exception ) {
-                                       // Return nothing.
-                                       $this->addWhere( '1=0' );
-                               }
-                       } else {
-                               $this->addWhereFld( 'ct_tag', $params['tag'] );
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       try {
+                               $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
+                       } catch ( NameTableAccessException $exception ) {
+                               // Return nothing.
+                               $this->addWhere( '1=0' );
                        }
                }
 
index b1dcf0d..7c6b463 100644 (file)
@@ -143,8 +143,6 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
         * @param ApiPageSet|null $resultPageSet
         */
        public function run( $resultPageSet = null ) {
-               global $wgChangeTagsSchemaMigrationStage;
-
                $user = $this->getUser();
                /* Get the parameters of the request. */
                $params = $this->extractRequestParams();
@@ -339,9 +337,7 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                        $resultPageSet && $params['generaterevisions'] );
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds( [ 'tag_summary' => [ 'LEFT JOIN', [ 'rc_id=ts_rc_id' ] ] ] );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'recentchanges' ) ] );
                }
 
                if ( $this->fld_sha1 ) {
@@ -365,16 +361,12 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
                if ( !is_null( $params['tag'] ) ) {
                        $this->addTables( 'change_tag' );
                        $this->addJoinConds( [ 'change_tag' => [ 'INNER JOIN', [ 'rc_id=ct_rc_id' ] ] ] );
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               try {
-                                       $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
-                               } catch ( NameTableAccessException $exception ) {
-                                       // Return nothing.
-                                       $this->addWhere( '1=0' );
-                               }
-                       } else {
-                               $this->addWhereFld( 'ct_tag', $params['tag'] );
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       try {
+                               $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
+                       } catch ( NameTableAccessException $exception ) {
+                               // Return nothing.
+                               $this->addWhere( '1=0' );
                        }
                }
 
index ac7ee0a..cb2f616 100644 (file)
@@ -84,7 +84,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
        }
 
        protected function run( ApiPageSet $resultPageSet = null ) {
-               global $wgActorTableSchemaMigrationStage, $wgChangeTagsSchemaMigrationStage;
+               global $wgActorTableSchemaMigrationStage;
 
                $params = $this->extractRequestParams( false );
                $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
@@ -185,11 +185,7 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                }
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ 'rev_id=ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'revision' ) ] );
                }
 
                if ( $params['tag'] !== null ) {
@@ -197,16 +193,12 @@ class ApiQueryRevisions extends ApiQueryRevisionsBase {
                        $this->addJoinConds(
                                [ 'change_tag' => [ 'INNER JOIN', [ 'rev_id=ct_rev_id' ] ] ]
                        );
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               try {
-                                       $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
-                               } catch ( NameTableAccessException $exception ) {
-                                       // Return nothing.
-                                       $this->addWhere( '1=0' );
-                               }
-                       } else {
-                               $this->addWhereFld( 'ct_tag', $params['tag'] );
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       try {
+                               $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $params['tag'] ) );
+                       } catch ( NameTableAccessException $exception ) {
+                               // Return nothing.
+                               $this->addWhere( '1=0' );
                        }
                }
 
index c00010a..3d0a0fb 100644 (file)
@@ -616,10 +616,7 @@ abstract class ApiQueryRevisionsBase extends ApiQueryGeneratorBase {
        }
 
        public function getAllowedParams() {
-               $slotRoles = MediaWikiServices::getInstance()->getSlotRoleStore()->getMap();
-               if ( !in_array( SlotRecord::MAIN, $slotRoles, true ) ) {
-                       $slotRoles[] = SlotRecord::MAIN;
-               }
+               $slotRoles = MediaWikiServices::getInstance()->getSlotRoleRegistry()->getKnownRoles();
                sort( $slotRoles, SORT_STRING );
 
                return [
index f16f958..ed83130 100644 (file)
@@ -321,7 +321,7 @@ class ApiQueryUserContribs extends ApiQueryBase {
         * @param int $limit
         */
        private function prepareQuery( array $users, $limit ) {
-               global $wgActorTableSchemaMigrationStage, $wgChangeTagsSchemaMigrationStage;
+               global $wgActorTableSchemaMigrationStage;
 
                $this->resetQueryParams();
                $db = $this->getDB();
@@ -478,11 +478,7 @@ class ApiQueryUserContribs extends ApiQueryBase {
                $this->addFieldsIf( 'rc_patrolled', $this->fld_patrolled );
 
                if ( $this->fld_tags ) {
-                       $this->addTables( 'tag_summary' );
-                       $this->addJoinConds(
-                               [ 'tag_summary' => [ 'LEFT JOIN', [ $idField . ' = ts_rev_id' ] ] ]
-                       );
-                       $this->addFields( 'ts_tags' );
+                       $this->addFields( [ 'ts_tags' => ChangeTags::makeTagSummarySubquery( 'revision' ) ] );
                }
 
                if ( isset( $this->params['tag'] ) ) {
@@ -490,16 +486,12 @@ class ApiQueryUserContribs extends ApiQueryBase {
                        $this->addJoinConds(
                                [ 'change_tag' => [ 'INNER JOIN', [ $idField . ' = ct_rev_id' ] ] ]
                        );
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               try {
-                                       $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $this->params['tag'] ) );
-                               } catch ( NameTableAccessException $exception ) {
-                                       // Return nothing.
-                                       $this->addWhere( '1=0' );
-                               }
-                       } else {
-                               $this->addWhereFld( 'ct_tag', $this->params['tag'] );
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       try {
+                               $this->addWhereFld( 'ct_tag_id', $changeTagDefStore->getId( $this->params['tag'] ) );
+                       } catch ( NameTableAccessException $exception ) {
+                               // Return nothing.
+                               $this->addWhere( '1=0' );
                        }
                }
        }
index f807411..31c9d8f 100644 (file)
                        "Luzcaru",
                        "Javiersanp",
                        "KATRINE1992",
-                       "Adjen"
+                       "Adjen",
+                       "Tiberius1701"
                ]
        },
-       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentation]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Mailing list]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API Announcements]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Bugs & requests]\n</div>\n<strong>Status:</strong> Todas las funciones mostradas en esta página deberían estar funcionando, pero la API aún está en desarrollo activo, y puede cambiar en cualquier momento. Suscribase a [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ the mediawiki-api-announce mailing list] para aviso de actualizaciones.\n\n<strong>Erroneous requests:</strong> Cuando se envían solicitudes erróneas a la API, se enviará un encabezado HTTP con la clave \"MediaWiki-API-Error\" y, luego, el valor del encabezado y el código de error devuelto se establecerán en el mismo valor. Para más información ver [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errors and warnings]].\n\n<strong>Testing:</strong> Para facilitar la comprobación de las solicitudes de API, consulte [[Special:ApiSandbox]].",
+       "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Documentación]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista de correo]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Anuncios API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Errores y peticiones]\n</div>\n<strong>Estado:</strong> La API de MediaWiki es una interfaz madura y estable que se mejora y prueba activamente. Aunque tratamos de evitarlo, es posible que ocasionalmente debamos hacer cambios importantes; Suscribase a la [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ lista de correo the mediawiki-api-announce] para recibir avisos de actualizaciones.\n\n<strong>Solicitudes erróneas:</strong> Cuando se envían solicitudes erróneas a la API, se enviará un encabezado HTTP con la clave \"MediaWiki-API-Error\" y, luego, el valor del encabezado y el código de error devuelto se establecerán en el mismo valor. Para obtener más información, consulte [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Errores y advertencias]].\n\n<p class=\"mw-apisandbox-link\"><strong>Pruebas:</strong> Para facilitar la comprobación de las solicitudes de API, consulte [[Special:ApiSandbox]].</p>",
        "apihelp-main-param-action": "Qué acción se realizará.",
        "apihelp-main-param-format": "El formato de la salida.",
-       "apihelp-main-param-maxlag": "El retardo máximo puede utilizarse cuando MediaWiki se instala en una agrupación replicada de bases de datos. Para guardar las acciones que causan más retardo de replicación de sitio, este parámetro puede hacer que el cliente espere hasta que el retardo de replicación sea menor que el valor especificado. En caso de un retardo excesivo, se devuelve el código de error <samp>maxlag</samp> con un mensaje como <samp>Esperando a $host: $lag segundos de retardo</samp>.<br />Consulta [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: parámetro Maxlag]] para más información.",
+       "apihelp-main-param-maxlag": "Se puede usar el retardo máximo cuando se instala MediaWiki en un clúster replicado de base de datos. Para evitar acciones que causen más retardo en la replicación del sitio, este parámetro puede hacer que el cliente espere hasta que el retardo en la replicación sea menor que el valor especificado. En caso de retardo excesivo, se devuelve el código de error <samp>maxlag</samp> con un mensaje como <samp>Esperando a $host: $lag segundos de retardo</samp>.<br />Consulta [[mw:Special:MyLanguage/Manual:Maxlag_parameter|Manual: parámetro Maxlag]] para más información.",
        "apihelp-main-param-smaxage": "Establece la cabecera HTTP <code>s-maxage</code> de control de antememoria a esta cantidad de segundos. Los errores nunca se almacenan en la antememoria.",
        "apihelp-main-param-maxage": "Establece la cabecera HTTP <code>max-age</code> de control de antememoria a esta cantidad de segundos. Los errores nunca se almacenan en la antememoria.",
        "apihelp-main-param-assert": "Comprobar que el usuario haya iniciado sesión si el valor es <kbd>user</kbd> o si tiene el permiso de bot si es <kbd>bot</kbd>.",
@@ -89,7 +90,7 @@
        "apihelp-compare-param-toid": "Segunda identificador de página para comparar.",
        "apihelp-compare-param-torev": "Segunda revisión para comparar.",
        "apihelp-compare-param-tosection": "Solamente usar la sección especificada del contenido 'to' especificado.",
-       "apihelp-compare-param-prop": "Cuáles fragmentos de información se obtendrán.",
+       "apihelp-compare-param-prop": "Qué fragmentos de información se obtendrán.",
        "apihelp-compare-paramvalue-prop-diff": "El HTML de las diferencias.",
        "apihelp-compare-paramvalue-prop-diffsize": "El tamaño del HTML de las diferencias, en bytes.",
        "apihelp-compare-example-1": "Crear una diferencia entre las revisiones 1 y 2.",
        "apihelp-delete-param-watchlist": "Añadir o quitar incondicionalmente la página de la lista de seguimiento del usuario actual, usar preferencias o no cambiar el estado de seguimiento.",
        "apihelp-delete-param-unwatch": "Quitar la página de la lista de seguimiento del usuario actual.",
        "apihelp-delete-param-oldimage": "El nombre de la imagen antigua es proporcionado conforme a lo dispuesto por [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]].",
-       "apihelp-delete-example-simple": "Borrar <kbd>Main Page</kbd>.",
-       "apihelp-delete-example-reason": "Eliminar <kbd>Main Page</kbd> con el motivo <kbd>Preparing for move</kbd>.",
+       "apihelp-delete-example-simple": "Borrar <kbd>Pagina principal</kbd>.",
+       "apihelp-delete-example-reason": "Eliminar <kbd>Main Page</kbd> con el motivo <kbd>Preparándose para traslado</kbd>.",
        "apihelp-disabled-summary": "Se desactivó este módulo.",
        "apihelp-edit-summary": "Crear y editar páginas.",
        "apihelp-edit-param-title": "Título de la página a editar. No se puede utilizar junto a <var>$1pageid</var>.",
        "apihelp-edit-param-tags": "Cambia las etiquetas para aplicarlas a la revisión.",
        "apihelp-edit-param-minor": "Edición menor.",
        "apihelp-edit-param-notminor": "Edición no menor.",
-       "apihelp-edit-param-bot": "Marcar esta como una edición de robot.",
+       "apihelp-edit-param-bot": "Marcar esta como una edición de bot.",
        "apihelp-edit-param-basetimestamp": "Marca de tiempo de la revisión base, usada para detectar conflictos de edición. Se puede obtener mediante [[Special:ApiHelp/query+revisions|action=query&prop=revisions&rvprop=timestamp]]",
        "apihelp-edit-param-starttimestamp": "Marca de tiempo de cuando empezó el proceso de edición, usada para detectar conflictos de edición. Se puede obtener un valor apropiado usando <var>[[Special:ApiHelp/main|curtimestamp]]</var> cuando comiences el proceso de edición (por ejemplo, al cargar el contenido de la página por editar).",
        "apihelp-edit-param-recreate": "Reemplazar los errores acerca de la página de haber sido eliminados en el ínterin.",
        "apihelp-edit-example-undo": "Deshacer intervalo de revisiones 13579-13585 con resumen automático",
        "apihelp-emailuser-summary": "Enviar un mensaje de correo electrónico a un usuario.",
        "apihelp-emailuser-param-target": "Cuenta de usuario destinatario.",
-       "apihelp-emailuser-param-subject": "Cabecera de asunto.",
+       "apihelp-emailuser-param-subject": "Cabecera del asunto.",
        "apihelp-emailuser-param-text": "Cuerpo del mensaje.",
        "apihelp-emailuser-param-ccme": "Enviarme una copia de este mensaje.",
        "apihelp-emailuser-example-email": "Enviar un correo al usuario <kbd>WikiSysop</kbd> con el texto <kbd>Content</kbd>.",
        "apihelp-expandtemplates-summary": "Expande todas las plantillas en wikitexto.",
        "apihelp-expandtemplates-param-title": "Título de la página.",
-       "apihelp-expandtemplates-param-text": "Sintaxis wiki que se convertirá.",
+       "apihelp-expandtemplates-param-text": "Wikitexto que se convertirá.",
        "apihelp-expandtemplates-param-revid": "Id. de revisión, para <code><nowiki>{{REVISIONID}}</nowiki></code> y variables similares.",
        "apihelp-expandtemplates-param-prop": "Qué elementos de información se utilizan para llegar.\n\nTenga en cuenta que si no se seleccionan los valores, el resultado contendrá el wikitexto, pero la salida será en un formato obsoleto.",
        "apihelp-expandtemplates-paramvalue-prop-wikitext": "El wikitexto expandido.",
        "apihelp-query+watchlist-paramvalue-prop-tags": "Enumera las etiquetas de la entrada.",
        "apihelp-query+watchlist-param-show": "Muestra solo los elementos que cumplan estos criterios. Por ejemplo, para ver solo ediciones menores realizadas por usuarios conectados, introduce $1show=minor|!anon.",
        "apihelp-query+watchlist-param-type": "Qué tipos de cambios mostrar:",
-       "apihelp-query+watchlist-paramvalue-type-edit": "Ediciones comunes a páginas",
+       "apihelp-query+watchlist-paramvalue-type-edit": "Ediciones comunes en páginas",
        "apihelp-query+watchlist-paramvalue-type-external": "Cambios externos.",
        "apihelp-query+watchlist-paramvalue-type-new": "Creaciones de páginas.",
        "apihelp-query+watchlist-paramvalue-type-log": "Entradas del registro.",
index 1211693..4258674 100644 (file)
@@ -38,6 +38,9 @@
        "apihelp-block-param-allowusertalk": "A felhasználó szerkeszthesse a saját vitalapját (a <var>[[mw:Special:MyLanguage/Manual:$wgBlockAllowsUTEdit|$wgBlockAllowsUTEdit]]</var> beállítástól függ).",
        "apihelp-block-param-reblock": "Jelenlegi blokk felülírása, ha a felhasználó már blokkolva van.",
        "apihelp-block-param-watchuser": "A szerkesztő vagy IP-cím szerkesztői- és vitalapjának figyelése.",
+       "apihelp-block-param-tags": "A blokknapló naplóbejegyzésére érvényesítendő változtatáscímkék.",
+       "apihelp-block-param-partial": "Teljes blokk helyett a felhasználó eltiltása bizonyos lapok vagy névterek szerkesztésétől.",
+       "apihelp-block-param-pagerestrictions": "A felhasználó számára blokkolandó címek listája. Csak akkor van hatása, ha a <var>partial</var> igaz.",
        "apihelp-block-example-ip-simple": "A <kbd>192.0.2.5</kbd> IP-cím blokkolása három napra <kbd>First strike</kbd> indoklással.",
        "apihelp-block-example-user-complex": "<kbd>Vandal</kbd> blokkolása határozatlan időre <kbd>Vandalism</kbd> indoklással, új fiók létrehozásának és e-mail küldésének megakadályozása.",
        "apihelp-checktoken-summary": "Egy <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> kéréssel szerzett token érvényességének vizsgálata.",
index 5e30c1a..3ba6228 100644 (file)
@@ -24,7 +24,7 @@
        "apihelp-main-param-origin": "Når man aksesserer API-en som bruker en domene-kryssende AJAX-forespørsel (CORS), sett denne til det opprinnelige domenet. Denne må tas med i alle pre-flight-forespørsler, og derfor være en del av spørre-URI-en (ikke POST-kroppen).\n\nFor autentiserte forespørsler må denne stemme helt med en av de opprinnelige i <code>Origin</code>-headeren, slik at den må settes til noe a la <kbd>https://en.wikipedia.org</kbd> eller <kbd>https://meta.wikimedia.org</kbd>. Hvis denne parameteren ikke stemmer med <code>Origin</code>-headeren, returneres et 403-svar. Hvis denne parameteren stemmer med <code>Origin</code>-headeren og originalen er hvitlistet, vil <code>Access-Control-Allow-Origin</code> og <code>Access-Control-Allow-Credentials</code>-headere bli satt.\n\nFor ikke-autentiserte forepørsler, spesifiser <kbd>*</kbd>. Denne vil gjøre at <code>Access-Control-Allow-Origin</code>-headeren blir satt, men <code>Access-Control-Allow-Credentials</code> blir <code>false</code> og alle bruerspesifikke data blir begrenset.",
        "apihelp-main-param-uselang": "Språk å bruke for meldingsoversettelser. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages</kbd> returnerer en liste over språkkoder, eller spesifiser <kbd>user</kbd> for å bruke den nåværende brukerens språkpreferanser, eller spesifiser <kbd>content</kbd> for å bruke denne wikiens innholdsspråk.",
        "apihelp-main-param-errorformat": "Formater som kan brukes for advarsels- og feiltekster.\n; plaintext: Wikitext der HTML-tagger er fjernet og elementer byttet ut.\n; wikitext: Ubehandlet wikitext.\n; html: HTML.\n; raw: Meldingsnøkler og -parametre.\n; none: Ingen tekst, bare feilkoder.\n; bc: Format brukt før MediaWiki 1.29. <var>errorlang</var> og <var>errorsuselocal</var> ses bort fra.",
-       "apihelp-main-param-errorlang": "Språk som skal brukes for advarsler og feil. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages/<kbd> returnerer ei liste over språkkoder, eller angi <kbd>content</kbd> for å bruke wikiens innholdsspråk, eller angi <kbd>uselang</kbd> for å bruke samme verdi som <var>uselang</var>-parameteren.",
+       "apihelp-main-param-errorlang": "Språk som skal brukes for advarsler og feil. <kbd>[[Special:ApiHelp/query+siteinfo|action=query&meta=siteinfo]]</kbd> med <kbd>siprop=languages</kbd> returnerer ei liste over språkkoder, eller angi <kbd>content</kbd> for å bruke wikiens innholdsspråk, eller angi <kbd>uselang</kbd> for å bruke samme verdi som <var>uselang</var>-parameteren.",
        "apihelp-main-param-errorsuselocal": "Hvis gitt, vil feiltekster bruke lokalt tilpassede meldinger fra {{ns:MediaWiki}}-navnerommet.",
        "apihelp-block-summary": "Blokker en bruker.",
        "apihelp-block-param-user": "Brukernavn, IP-adresse eller IP-intervall som skal blokkeres. Kan ikke brukes sammen med <var>$1userid</var>",
index 7b29b1f..53cc928 100644 (file)
@@ -14,7 +14,8 @@
                        "Matma Rex",
                        "Sethakill",
                        "Woytecr",
-                       "InternerowyGołąb"
+                       "InternerowyGołąb",
+                       "CiaPan"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|Dokumentacja]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api Lista dyskusyjna]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce Ogłoszenia dotyczące API]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R Błędy i propozycje]\n</div>\n<strong>Stan:</strong> Wszystkie funkcje opisane na tej stronie powinny działać, ale API nadal jest aktywnie rozwijane i mogą się zmienić w dowolnym czasie. Subskrybuj [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ listę dyskusyjną mediawiki-api-announce], aby móc na bieżąco dowiadywać się o aktualizacjach.\n\n<strong>Błędne żądania:</strong> Gdy zostanie wysłane błędne żądanie do API, zostanie wysłany w odpowiedzi nagłówek HTTP z kluczem \"MediaWiki-API-Error\" i zarówno jego wartość jak i wartość kodu błędu wysłanego w odpowiedzi będą miały taką samą wartość. Aby uzyskać więcej informacji, zobacz [[mw:Special:MyLanguage/API:Errors_and_warnings|API: Błędy i ostrzeżenia]].\n\n<strong>Testowanie:</strong> Aby łatwo testować żądania API, zobacz [[Special:ApiSandbox]].",
@@ -42,6 +43,8 @@
        "apihelp-block-param-reblock": "Jeżeli ten użytkownik jest już zablokowany, nadpisz blokadę.",
        "apihelp-block-param-watchuser": "Obserwuj stronę użytkownika lub IP oraz ich strony dyskusji.",
        "apihelp-block-param-tags": "Zmieniaj tagi by potwierdzić wejście do bloku logów.",
+       "apihelp-block-param-partial": "Zablokuj użytkownikowi dostęp do wybranych stron lub przestrzeni nazw zamiast do całej witryny.",
+       "apihelp-block-param-pagerestrictions": "Lista tytułów stron do zablokowania użytkownikowi możliwości edycji. Ma zastosowanie tylko gdy 'partial' (częściowa) jest ustawione na true (prawda).",
        "apihelp-block-example-ip-simple": "Zablokuj IP <kbd>192.0.2.5</kbd> na 3 dni z powodem <kbd>First strike</kbd>.",
        "apihelp-block-example-user-complex": "Zablokuj użytkownika <kbd>Vandal</kbd> na zawsze z powodem <kbd>Vandalism</kbd> i uniemożliw utworzenie nowego konta oraz wysyłanie emaili.",
        "apihelp-changeauthenticationdata-summary": "Zmień dane logowania bieżącego użytkownika.",
        "apihelp-opensearch-summary": "Przeszukaj wiki przy użyciu protokołu OpenSearch.",
        "apihelp-opensearch-param-search": "Wyszukaj tekst.",
        "apihelp-opensearch-param-limit": "Maksymalna liczba zwracanych wyników.",
-       "apihelp-opensearch-param-namespace": "Przestrzenie nazw do przeszukania.",
+       "apihelp-opensearch-param-namespace": "Przestrzenie nazw do przeszukania. Pomijane jeśli <var>$1search</var> zaczyna się od poprawnego przedrostka przestrzeni nazw.",
        "apihelp-opensearch-param-suggest": "Nic nie robi, jeżeli <var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var> ustawiono na false.",
        "apihelp-opensearch-param-redirects": "Jak obsługiwać przekierowania:\n;return:Zwróć samo przekierowanie.\n;resolve:Zwróć stronę docelową. Może zwrócić mniej niż wyników określonych w $1limit.\nZ powodów historycznych, domyślnie jest to \"return\" dla $1format=json, a \"resolve\" dla innych formatów.",
        "apihelp-opensearch-param-format": "Format danych wyjściowych.",
        "apihelp-query+blocks-paramvalue-prop-expiry": "Dodaje znacznik czasu wygaśnięcia blokady.",
        "apihelp-query+blocks-paramvalue-prop-reason": "Dodaje powód zablokowania.",
        "apihelp-query+blocks-paramvalue-prop-range": "Dodaje zakres adresów IP, na który zastosowano blokadę.",
+       "apihelp-query+blocks-paramvalue-prop-restrictions": "Dodaje częściowe ograniczenia jeśli blokada nie jest całościowa.",
        "apihelp-query+blocks-example-simple": "Listuj blokady.",
        "apihelp-query+categories-summary": "Lista kategorii, do których należą strony",
        "apihelp-query+categories-paramvalue-prop-timestamp": "Dodaje znacznik czasu dodania kategorii.",
        "apihelp-query+imageusage-example-simple": "Pokaż strony, które korzystają z [[:File:Albert Einstein Head.jpg]].",
        "apihelp-query+info-summary": "Pokaż podstawowe informacje o stronie.",
        "apihelp-query+info-paramvalue-prop-watchers": "Liczba obserwujących, jeśli jest to dozwolone.",
-       "apihelp-query+info-paramvalue-prop-readable": "Czy użytkownik może przeczytać tę stronę.",
+       "apihelp-query+info-paramvalue-prop-readable": "Czy użytkownik może przeczytać tę stronę. Zamiast tego użyj <kbd>intestactions=read</kbd>.",
        "apihelp-query+iwbacklinks-param-prefix": "Prefix interwiki.",
        "apihelp-query+iwbacklinks-param-limit": "Łączna liczba stron do zwrócenia.",
        "apihelp-query+iwbacklinks-paramvalue-prop-iwprefix": "Dodaje prefiks interwiki.",
        "apihelp-query+pageswithprop-example-simple": "Lista pierwszych 10 stron za pomocą <code>&#123;&#123;DISPLAYTITLE:&#125;&#125;</code>.",
        "apihelp-query+pageswithprop-example-generator": "Pobierz dodatkowe informacje o pierwszych 10 stronach wykorzystując <code>_&#95;NOTOC_&#95;</code>.",
        "apihelp-query+prefixsearch-param-search": "Wyszukaj tekst.",
-       "apihelp-query+prefixsearch-param-namespace": "Przestrzenie nazw do przeszukania.",
+       "apihelp-query+prefixsearch-param-namespace": "Przestrzenie nazw do przeszukania. Pomijane jeśli <var>$1search</var> zaczyna się od poprawnego przedrostka przestrzeni nazw.",
        "apihelp-query+prefixsearch-param-limit": "Maksymalna liczba zwracanych wyników.",
        "apihelp-query+prefixsearch-param-offset": "Liczba wyników do pominięcia.",
        "apihelp-query+protectedtitles-summary": "Lista wszystkich tytułów zabezpieczonych przed tworzeniem.",
index 71a2a08..0d12de7 100644 (file)
        "apihelp-delete-param-reason": "刪除的原因。 若未設定,將會使用自動產生的原因。",
        "apihelp-delete-param-tags": "在刪除日誌裡更改套用到項目的標籤。",
        "apihelp-delete-param-watch": "加入目前頁面至您的監視清單。",
-       "apihelp-delete-param-watchlist": "無條件使用設置將頁面加入或移除目前使用者的監視清單或者是不更改監視清單。",
+       "apihelp-delete-param-watchlist": "使用偏好設定無條件地將頁面加入至或移除自目前使用者的監視清單,或不更改監視。",
        "apihelp-delete-param-unwatch": "從您的監視清單中移除目前頁面。",
        "apihelp-delete-param-oldimage": "由 [[Special:ApiHelp/query+imageinfo|action=query&prop=imageinfo&iiprop=archivename]] 所提供要刪除的舊圖片名稱。",
        "apihelp-delete-example-simple": "刪除 <kbd>Main Page</kbd>。",
        "apihelp-edit-param-nocreate": "若頁面不存在,則產生錯誤。",
        "apihelp-edit-param-watch": "加入目前頁面至您的監視清單。",
        "apihelp-edit-param-unwatch": "從您的監視清單中移除目前頁面。",
-       "apihelp-edit-param-watchlist": "無條件使用設置將頁面加入或移除目前使用者的監視清單或者是不更改監視清單。",
+       "apihelp-edit-param-watchlist": "使用偏好設定無條件地將頁面加入至或移除自目前使用者的監視清單,或不更改監視。",
        "apihelp-edit-param-prependtext": "添加此文字至頁面開頭。覆蓋$1text。",
        "apihelp-edit-param-undo": "復原此修訂。覆寫 $1text、$1prependtext 與 $1appendtext。",
        "apihelp-edit-param-undoafter": "撤銷從 $1undo 至此為止的所有修訂。若不設定則僅會撤銷一次修訂。",
        "apihelp-expandtemplates-paramvalue-prop-encodedjsconfigvars": "指定頁面的 JavaScript 設置變量為 JSON 字串。",
        "apihelp-expandtemplates-paramvalue-prop-parsetree": "輸出的 XML 解析樹狀。",
        "apihelp-expandtemplates-param-includecomments": "輸出裡是否包含 HTML 註解。",
+       "apihelp-expandtemplates-param-generatexml": "產生 XML 解析樹狀(以 $1prop=parsetree 取代)。",
        "apihelp-expandtemplates-example-simple": "展開 wiki 文字<kbd><nowiki>{{Project:Sandbox}}</nowiki></kbd>。",
        "apihelp-feedcontributions-summary": "回傳使用者貢獻 Feed。",
        "apihelp-feedcontributions-param-feedformat": "Feed 的格式。",
        "apihelp-filerevert-param-archivename": "要復原的修訂存檔名稱。",
        "apihelp-filerevert-example-revert": "回退 <kbd>Wiki.png</kbd> 至 <kbd>2011-03-05T15:27:40Z</kbd> 的版本。",
        "apihelp-help-summary": "顯示指定模組的說明。",
+       "apihelp-help-param-wrap": "在標準 API 回應結構裡包裹輸出。",
        "apihelp-help-param-toc": "在 HTML 輸出裡包含目錄。",
        "apihelp-help-example-main": "主模組使用說明",
        "apihelp-help-example-submodules": "用於 <kbd>action=query</kbd> 與其所有子模組的幫助。",
        "apihelp-imagerotate-example-simple": "<kbd>90</kbd> 度旋轉 <kbd>File:Example.png</kbd>。",
        "apihelp-imagerotate-example-generator": "<kbd>180</kbd> 度旋轉所有在 <kbd>Category:Flip</kbd> 裡的圖片。",
        "apihelp-import-summary": "從其它 wiki 或 XML 檔案來匯入頁面。",
+       "apihelp-import-extended-description": "請注意當發送用於 <var>xml</var> 參數的檔案時,必須以 HTTP POST 作為檔案上傳(註:使用 multipart/form-data)。",
        "apihelp-import-param-summary": "匯入摘要。",
        "apihelp-import-param-xml": "上載的 XML 檔。",
        "apihelp-import-param-assignknownusers": "分配編輯至所命名使用者已存在本地的本地使用者。",
        "apihelp-move-param-noredirect": "不要建立重新導向。",
        "apihelp-move-param-watch": "將頁面和重定向加入目前使用者的監視清單。",
        "apihelp-move-param-unwatch": "從目前使用者的監視清單中移除頁面和重定向。",
-       "apihelp-move-param-watchlist": "在目前使用者的監視清單中無條件地加入或移除頁面,或使用設定,或不變更監視清單。",
+       "apihelp-move-param-watchlist": "使用偏好設定無條件地將頁面加入至或移除自目前使用者的監視清單,或不更改監視。",
        "apihelp-move-param-ignorewarnings": "忽略所有警告。",
        "apihelp-move-example-move": "將<kbd>Badtitle</kbd>移動至<kbd>Goodtitle</kbd>,不留下重定向。",
        "apihelp-opensearch-summary": "使用 OpenSearch 協定搜尋本 wiki。",
        "apihelp-opensearch-param-suggest": "若<var>[[mw:Special:MyLanguage/Manual:$wgEnableOpenSearchSuggest|$wgEnableOpenSearchSuggest]]</var>設定為false,則不做任何事。",
        "apihelp-opensearch-param-redirects": "如何處理重定向:\n;return:傳回重定向本身。\n;resolve:傳回目標頁面,傳回的結果數目可能少於$1limit。\n由於歷史原因,$1format=json的預設值為「return」,其他格式則為「resolve」。",
        "apihelp-opensearch-param-format": "輸出的格式。",
+       "apihelp-opensearch-param-warningsaserror": "若警告以 <kbd>format=json</kbd> 提升時,回傳 API 錯誤而非忽略掉。",
        "apihelp-opensearch-example-te": "找出以 <kbd>Te</kbd> 為開頭的頁面。",
        "apihelp-options-summary": "更改目前使用者的偏好設定。",
        "apihelp-options-param-reset": "重設偏好設定為網站預設值。",
        "apihelp-parse-paramvalue-prop-displaytitle": "添加已解析 wiki 文字的標題。",
        "apihelp-parse-paramvalue-prop-headitems": "提供放置頁面裡的 <code>&lt;head&gt;</code> 之項目。",
        "apihelp-parse-paramvalue-prop-headhtml": "取得頁面已解析的 <code>&lt;head&gt;</code>。",
+       "apihelp-parse-paramvalue-prop-jsconfigvars": "針對頁面提供指定的 JavaScript 設置變數。若要套用,請使用 <code>mw.config.set()</code>。",
        "apihelp-parse-paramvalue-prop-encodedjsconfigvars": "指定頁面的 JavaScript 設置變量為 JSON 字串。",
        "apihelp-parse-paramvalue-prop-iwlinks": "在已解析的 wiki 文字提供跨 wiki 連結。",
        "apihelp-parse-paramvalue-prop-wikitext": "指定被解析的原始 wiki 文字。",
        "apihelp-parse-paramvalue-prop-properties": "指定多項定義在已解析原始 wiki 文字的屬性。",
        "apihelp-parse-paramvalue-prop-limitreportdata": "取得結構化限制報告。當有設定 <var>$1disablelimitreport</var> 時,則不會給予資料。",
        "apihelp-parse-paramvalue-prop-limitreporthtml": "取得限制報告的 HTML 版本。當有設定 <var>$1disablelimitreport</var> 時,則不會給予資料。",
+       "apihelp-parse-paramvalue-prop-parsetree": "修訂內容的 XML 解析樹狀(需要內容模組 <code>$1</code>)",
        "apihelp-parse-paramvalue-prop-parsewarnings": "提供發生在解析內容時的警告。",
        "apihelp-parse-param-wrapoutputclass": "要包在解析器輸出內容的 CSS 類別。",
+       "apihelp-parse-param-effectivelanglinks": "包含由擴充提供的語言連結(與 <kbd>$1prop=langlinks</kbd> 一起使用)。",
+       "apihelp-parse-param-disablelimitreport": "從解析輸出內容裡省略限制報告(\"NewPP limit report\")。",
        "apihelp-parse-param-disablepp": "請改用<var>$1disablelimitreport</var>。",
        "apihelp-parse-param-disableeditsection": "從解析輸出內容省略編輯段落連結。",
        "apihelp-parse-param-disabletidy": "不要在解析輸出裡執行 HTML 內容清理(例如使用 tidy 軟體工具)",
        "apihelp-protect-param-tags": "修改標籤以套用於保護日誌裡的項目。",
        "apihelp-protect-param-cascade": "啟用連鎖保護(也就是保護包含於此頁面的頁面)。如果所有提供的保護等級不支援連鎖,就將其忽略。",
        "apihelp-protect-param-watch": "如果被設定,就將被(解除)保護的頁面加至目前使用者的監視列表。",
-       "apihelp-protect-param-watchlist": "無條件地將該頁面加入至或移除自目前使用者的監視列表、使用偏好設定或不更改監視。",
+       "apihelp-protect-param-watchlist": "使用偏好設定無條件地將頁面加入至或移除自目前使用者的監視清單,或不更改監視。",
        "apihelp-protect-example-protect": "保護一個頁面。",
        "apihelp-protect-example-unprotect": "透過設定為 <kbd>all</kbd>(註:代表任何人都可以執行操作),來解除對頁面的保護。",
        "apihelp-protect-example-unprotect2": "透過設定為沒有限制,來解除對頁面的保護。",
        "apihelp-query+allpages-param-prlevel": "篩選基於保護級別的保護(必須與 $1prtype= 參數一起使用)。",
        "apihelp-query+allpages-param-limit": "要回傳的頁面總數。",
        "apihelp-query+allpages-param-dir": "列出時所採用的方向。",
+       "apihelp-query+allpages-param-filterlanglinks": "篩選基於頁面是否有語言連結。請注意這可能不會考慮由擴充所添加的語言連結。",
        "apihelp-query+allpages-example-B": "顯示以字母 <kbd>B</kbd> 為開頭的所有頁面清單。",
        "apihelp-query+allpages-example-generator": "顯示 4 個以 <kbd>T</kbd> 為開頭的頁面之資訊。",
        "apihelp-query+allpages-example-generator-revisions": "顯示前 2 個以 <kbd>Re</kbd> 為開頭的非重新導向頁面內容。",
        "apihelp-query+blocks-paramvalue-prop-expiry": "添加當封鎖到期的時間戳記。",
        "apihelp-query+blocks-paramvalue-prop-reason": "添加封鎖的原因。",
        "apihelp-query+blocks-paramvalue-prop-range": "添加受封鎖影響的 IP 地址範圍。",
+       "apihelp-query+blocks-param-show": "僅顯示符合這些標準的項目。\n例如僅想查看在 IP 地址的無限期封鎖,請設定 <kbd>$1show=ip|!temp</kbd>。",
        "apihelp-query+blocks-example-simple": "列出封鎖。",
        "apihelp-query+blocks-example-users": "列出使用者 <kbd>Alice</kbd> 與 <kbd>Bob</kbd> 的封鎖。",
        "apihelp-query+categories-summary": "列出頁面隸屬的所有分類。",
        "apihelp-query+extlinks-summary": "回傳所有指定頁面的外部 URL (非 interwiki)。",
        "apihelp-query+extlinks-param-limit": "要回傳的連結數量。",
        "apihelp-query+extlinks-param-protocol": "URL 協定。若為空且有設定 <var>$1query</var>,會是 <kbd>http</kbd> 協定。將此與 <var>$1query</var> 一同留空會列出所有外部連結。",
+       "apihelp-query+extlinks-param-query": "不以協議來搜尋字串,對於檢查某頁面是否包含某個外部 URL 時很有用。",
        "apihelp-query+extlinks-example-simple": "取得 <kbd>Main Page</kbd> 的外部連結清單。",
        "apihelp-query+exturlusage-summary": "列舉包含指定 URL 的頁面。",
        "apihelp-query+exturlusage-param-prop": "要包含的資訊部份:",
        "apihelp-query+imageinfo-param-start": "列出的起始時間戳記。",
        "apihelp-query+imageinfo-param-end": "列出的終止時間戳記。",
        "apihelp-query+imageinfo-param-urlheight": "與 $1urlwidth 相似。",
+       "apihelp-query+imageinfo-param-metadataversion": "要使用的詮釋資料版本。若有指定 <kbd>latest</kbd>,會使用最新版本。預設為 <kbd>1</kbd>,以便向下兼容。",
        "apihelp-query+imageinfo-param-extmetadatamultilang": "若用於 extmetadata 屬性的翻譯可用,則全部索取。",
        "apihelp-query+imageinfo-param-extmetadatafilter": "若有指定且非空,僅會為 $1prop=extmetadata 回傳這些鍵。",
        "apihelp-query+imageinfo-param-badfilecontexttitle": "若有設定 <kbd>$2prop=badfile</kbd>,此頁面使用在當評估 [[MediaWiki:Bad image list]] 的時候",
        "apihelp-query+siteinfo-paramvalue-prop-namespacealiases": "已註冊命名空間別名清單。",
        "apihelp-query+siteinfo-paramvalue-prop-specialpagealiases": "特殊頁面別名清單。",
        "apihelp-query+siteinfo-paramvalue-prop-magicwords": "魔術字及其別名清單。",
+       "apihelp-query+siteinfo-paramvalue-prop-interwikimap": "回傳內部 wiki 對應(篩選可選用,也可透過 <var>$1inlanguagecode</var> 來選用本地化)。",
+       "apihelp-query+siteinfo-paramvalue-prop-dbrepllag": "回傳有最高複製延遲的資料庫伺服器。",
        "apihelp-query+siteinfo-paramvalue-prop-usergroups": "回傳使用者群組以及所分配權限。",
        "apihelp-query+siteinfo-paramvalue-prop-libraries": "回傳安裝在 wiki 上的函式庫。",
        "apihelp-query+siteinfo-paramvalue-prop-extensions": "回傳安裝在 wiki 上的擴充功能。",
        "apihelp-query+siteinfo-paramvalue-prop-fileextensions": "回傳允許上傳的副檔名(檔案類型)清單。",
        "apihelp-query+siteinfo-paramvalue-prop-rightsinfo": "若可用時,回傳 wiki 版權(授權條款)資訊。",
        "apihelp-query+siteinfo-paramvalue-prop-restrictions": "回傳在可用限制(保護)類型的資訊。",
+       "apihelp-query+siteinfo-paramvalue-prop-languages": "回傳 MediaWiki 支援的語言清單(可透過 <var>$1inlanguagecode</var> 來選用本地化)。",
+       "apihelp-query+siteinfo-paramvalue-prop-skins": "回傳所有已啟用的外觀清單(可透過 <var>$1inlanguagecode</var> 來選用本地化,不然會是內容語言)。",
        "apihelp-query+siteinfo-paramvalue-prop-extensiontags": "回傳解析擴充標籤清單。",
        "apihelp-query+siteinfo-paramvalue-prop-functionhooks": "回傳解析器函式掛勾清單。",
+       "apihelp-query+siteinfo-paramvalue-prop-showhooks": "回傳所有訂閱掛勾清單(<var>[[mw:Special:MyLanguage/Manual:$wgHooks|$wgHooks]]</var> 的內容)。",
        "apihelp-query+siteinfo-paramvalue-prop-variables": "回傳變數 ID 清單。",
+       "apihelp-query+siteinfo-paramvalue-prop-protocols": "回傳在外部連結裡所允許的協議清單。",
        "apihelp-query+siteinfo-paramvalue-prop-defaultoptions": "回傳用於使用者偏好設定的預設值。",
        "apihelp-query+siteinfo-paramvalue-prop-uploaddialog": "回傳上傳對話框的設置。",
        "apihelp-query+siteinfo-param-filteriw": "僅回傳跨 wiki 地圖的本地端或非本地端項目。",
        "apihelp-query+tags-paramvalue-prop-name": "添加標籤名稱。",
        "apihelp-query+tags-paramvalue-prop-displayname": "添加標籤的系統訊息。",
        "apihelp-query+tags-paramvalue-prop-description": "添加標籤的描述。",
+       "apihelp-query+tags-paramvalue-prop-hitcount": "添加含有此標籤之修訂與日誌項目的數量。",
        "apihelp-query+tags-paramvalue-prop-defined": "指示標籤是否已定義。",
        "apihelp-query+tags-paramvalue-prop-active": "標籤是否仍被套用。",
        "apihelp-query+tags-example-simple": "列出可用標籤。",
        "apihelp-query+templates-param-dir": "列出時所採用的方向。",
        "apihelp-query+templates-example-simple": "取得在頁面 <kbd>Main Page</kbd> 使用到的模坂。",
        "apihelp-query+templates-example-generator": "取得使用在 <kbd>Main Page</kbd> 的模版頁面相關資訊。",
+       "apihelp-query+templates-example-namespaces": "取得嵌入在頁面 <kbd>Main Page</kbd> 裡的 {{ns:user}} 與 {{ns:template}} 命名空間之頁面。",
        "apihelp-query+tokens-summary": "取得資料修改操作的權杖。",
        "apihelp-query+tokens-param-type": "要求的權杖類型。",
        "apihelp-query+tokens-example-simple": "接收 csrf 權杖(預設)。",
        "apihelp-query+transcludedin-example-generator": "取得有關嵌入 <kbd>Main Page</kbd> 的頁面之資訊。",
        "apihelp-query+usercontribs-summary": "按使用者來取得所有編輯。",
        "apihelp-query+usercontribs-param-limit": "回傳的貢獻數量上限。",
+       "apihelp-query+usercontribs-param-user": "要檢索貢獻的使用者。不能與 <var>$1userids</var> 或 <var>$1userprefix</var> 一起使用。",
        "apihelp-query+usercontribs-param-namespace": "僅列出這些命名空間的貢獻。",
        "apihelp-query+usercontribs-param-prop": "包含的額外資訊部份:",
        "apihelp-query+usercontribs-paramvalue-prop-ids": "添加頁面 ID 與修訂 ID。",
        "apihelp-query+usercontribs-example-ipprefix": "顯示所有來自於前綴為 <kbd>192.0.2.</kbd> 的 IP 地址貢獻。",
        "apihelp-query+userinfo-summary": "取得目前使用者的資訊。",
        "apihelp-query+userinfo-param-prop": "要包含的資訊部份:",
+       "apihelp-query+userinfo-paramvalue-prop-blockinfo": "若目前使用者被封鎖則標記出由誰做出,以及出於何種原因。",
        "apihelp-query+userinfo-paramvalue-prop-hasmsg": "若目前使用者有等待訊息,添加 <samp>messages</samp> 標籤。",
        "apihelp-query+userinfo-paramvalue-prop-groups": "列出目前使用者所隸屬的所有群組。",
+       "apihelp-query+userinfo-paramvalue-prop-implicitgroups": "列出目前使用者自動列入為成員的所有群組。",
        "apihelp-query+userinfo-paramvalue-prop-rights": "列出目前使用者所擁有的權限。",
+       "apihelp-query+userinfo-paramvalue-prop-changeablegroups": "列出目前使用者可以做出添加以及移除的群組。",
        "apihelp-query+userinfo-paramvalue-prop-options": "列出目前使用者已設定過的所有偏好設定。",
        "apihelp-query+userinfo-paramvalue-prop-preferencestoken": "取得權杖來變更目前使用者的偏好設定。",
        "apihelp-query+userinfo-paramvalue-prop-editcount": "添加目前使用者的編輯數。",
        "apihelp-query+watchlist-paramvalue-prop-patrol": "標記編輯為已巡查。",
        "apihelp-query+watchlist-paramvalue-prop-autopatrol": "標記編輯為自動巡查。",
        "apihelp-query+watchlist-paramvalue-prop-sizes": "添加頁面舊有與新的長度。",
+       "apihelp-query+watchlist-paramvalue-prop-notificationtimestamp": "添加使用者上一次被通知到有關編輯的時間戳記。",
        "apihelp-query+watchlist-paramvalue-prop-loginfo": "在適當處添加日誌資訊。",
        "apihelp-query+watchlist-paramvalue-prop-tags": "列出項目的標籤。",
        "apihelp-query+watchlist-param-type": "要顯示的更改類型:",
        "apihelp-query+watchlist-paramvalue-type-new": "頁面建立。",
        "apihelp-query+watchlist-paramvalue-type-log": "日誌項目。",
        "apihelp-query+watchlist-paramvalue-type-categorize": "分類成員更改。",
+       "apihelp-query+watchlist-param-owner": "與 $1token 一起使用以存取不同使用者的監視清單。",
        "apihelp-query+watchlist-param-token": "允許存取其他使用者監視清單的安全權杖(可在使用者的[[Special:Preferences#mw-prefsection-watchlist|偏好設定]]找到)。",
        "apihelp-query+watchlist-example-generator": "索取在目前使用者監視清單裡近期變更頁面的頁面資訊。",
        "apihelp-query+watchlistraw-summary": "列出在目前使用者的監視清單裡頭所有頁面。",
        "apihelp-rollback-param-user": "編輯被回退的使用者名稱。",
        "apihelp-rollback-param-summary": "自定義編輯摘要。若為空,則使用預設摘要。",
        "apihelp-rollback-param-markbot": "將回退的編輯以及回退操作標記為機器人所做編輯。",
-       "apihelp-rollback-param-watchlist": "無條件使用設置將頁面加入或移除目前使用者的監視清單或者是不更改監視清單。",
+       "apihelp-rollback-param-watchlist": "使用偏好設定無條件地將頁面加入至或移除自目前使用者的監視清單,或不更改監視。",
        "apihelp-rollback-example-simple": "回退由使用者 <kbd>Example</kbd> 對頁面 <kbd>Main Page</kbd> 所做的最新編輯。",
        "apihelp-rsd-summary": "匯出一個簡易探索(Really Simple Discovery、RSD)架構。",
        "apihelp-rsd-example-simple": "匯出 RSD 架構。",
        "apihelp-undelete-param-title": "要恢復的頁面標題。",
        "apihelp-undelete-param-reason": "還原的原因。",
        "apihelp-undelete-param-tags": "在刪除日誌裡更改套用到項目的標籤。",
+       "apihelp-undelete-param-watchlist": "使用偏好設定無條件地將頁面加入至或移除自目前使用者的監視清單,或不更改監視。",
        "apihelp-undelete-example-page": "取消刪除頁面 <kbd>Main Page</kbd>。",
        "apihelp-undelete-example-revisions": "取消刪除 <kbd>Main Page</kbd> 的兩筆修訂。",
        "apihelp-unlinkaccount-summary": "移除目前使用者所連結到的第三方帳號。",
        "apihelp-upload-summary": "上傳檔案,或取得等待上傳的狀態。",
        "apihelp-upload-param-filename": "目標檔案名稱。",
        "apihelp-upload-param-comment": "上傳註釋。如果 <var>$1text</var> 未指定的話,也會作為新檔案用的初始頁面文字。",
+       "apihelp-upload-param-tags": "更改標籤來套用到上傳日誌項目以及檔案頁面修訂。",
        "apihelp-upload-param-text": "用於新檔案的初始頁面文字。",
        "apihelp-upload-param-watch": "監視頁面。",
+       "apihelp-upload-param-watchlist": "使用偏好設定無條件地將頁面加入至或移除自目前使用者的監視清單,或不更改監視。",
        "apihelp-upload-param-ignorewarnings": "忽略所有警告。",
        "apihelp-upload-param-file": "檔案內容。",
        "apihelp-upload-param-url": "索取檔案的來源 URL。",
        "apihelp-upload-param-chunk": "大量內容。",
        "apihelp-upload-param-async": "在可能的情況下讓潛在的大型檔案非同步處理。",
        "apihelp-upload-example-url": "從 URL 上傳。",
+       "apihelp-upload-example-filekey": "完成出於警告而失敗的上傳。",
        "apihelp-userrights-summary": "變更一位使用者的群組成員。",
        "apihelp-userrights-param-user": "使用者名稱。",
        "apihelp-userrights-param-userid": "使用者ID。",
        "api-pageset-param-titles": "要使用的標題清單。",
        "api-pageset-param-pageids": "要使用的頁面 ID 清單。",
        "api-pageset-param-revids": "要使用的修訂 ID 清單。",
+       "api-pageset-param-redirects-generator": "自動解決在 <var>$1titles</var>、<var>$1pageids</var>、<var>$1revids</var>,以及由 <var>$1generator</var> 所回傳頁面裡的重新導向。",
+       "api-pageset-param-redirects-nogenerator": "自動解決在 <var>$1titles</var>、<var>$1pageids</var>,與 <var>$1revids</var> 的重新導向。",
        "api-help-title": "MediaWiki API 說明",
        "api-help-lead": "此頁為自動產生的 MediaWiki API 說明文件頁面。\n\n說明文件與範例:https://www.mediawiki.org/wiki/API",
        "api-help-main-header": "主要模組",
        "api-help-parameters": "{{PLURAL:$1|參數}}:",
        "api-help-param-deprecated": "已停用。",
        "api-help-param-required": "此參數為必填。",
+       "api-help-param-templated": "此為[[Special:ApiHelp/main#main/templatedparams|模板參數]]。當做出請求時,$2。",
+       "api-help-param-templated-var-first": "在參數名稱裡的 <var>&#x7B;$1&#x7D;</var> 應替換成 <var>$2</var> 的值",
+       "api-help-param-templated-var": "<var>&#x7B;$1&#x7D;</var> 與 <var>$2</var> 的值",
        "api-help-datatypes-header": "資料類型",
        "api-help-datatypes": "至MediaWiki的輸入值應為NFC標準化的UTF-8。MediaWiki可以嘗試轉換其他輸入值,但這可能導致一些操作失敗(例如附帶MD5檢查的[[Special:ApiHelp/edit|編輯]])。\n\n一些在API請求中的參數類型需要更進一步解釋:\n;boolean\n:布林參數產生作用就像HTML複選框一樣:如果參數被指定,無論何值都被視為真(true)。如果要假值(false),則必須省略參數。\n;timestamp\n:時間戳記可被指定為多種格式。推荐使用ISO 8601日期和時間標準。所有時間為UTC時間,包含的任何時區都會被忽略。\n:* ISO 8601日期和時間,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>Z</kbd>(標點和<kbd>Z</kbd>為選用)\n:* 帶小數秒(會被忽略)的ISO 8601日期和時間,<kbd><var>2001</var>-<var>01</var>-<var>15</var>T<var>14</var>:<var>56</var>:<var>00</var>.<var>00001</var>Z</kbd>(破折號、冒號和<kbd>Z</kbd>為選用)\n:* MediaWiki格式,<kbd><var>2001</var><var>01</var><var>15</var><var>14</var><var>56</var><var>00</var></kbd>\n:* 一般數字格式,<kbd><var>2001</var>-<var>01</var>-<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>(<kbd>GMT</kbd>、<kbd>+<var>##</var></kbd>或<kbd>-<var>##</var></kbd>的選用時區會被忽略)\n:* EXIF格式,<kbd><var>2001</var>:<var>01</var>:<var>15</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 2822格式(時區可省略),<kbd><var>Mon</var>, <var>15</var> <var>Jan</var> <var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* RFC 850格式(時區可省略),<kbd><var>Monday</var>, <var>15</var>-<var>Jan</var>-<var>2001</var> <var>14</var>:<var>56</var>:<var>00</var></kbd>\n:* C ctime格式,<kbd><var>Mon</var> <var>Jan</var> <var>15</var> <var>14</var>:<var>56</var>:<var>00</var> <var>2001</var></kbd>\n:* 從1970-01-01T00:00:00Z開始的秒數,作為1到13位數的整數(除了<kbd>0</kbd>)\n:* 字串<kbd>now</kbd>\n;替代多值分隔符號\n:使用多個值的參數通常會與垂直線符號(|)分隔的值一起提交,例如<kbd>param=value1|value2</kbd>或<kbd>param=value1%7Cvalue2</kbd>。如果值必須包含垂直線符號,使用U+001F(單位分隔符號)作為分隔符號,''並且''在值前加前綴U+001F,例如<kbd>param=%1Fvalue1%1Fvalue2</kbd>。",
        "api-help-templatedparams-header": "模板參數",
        "api-help-examples": "{{PLURAL:$1|範例}}:",
        "api-help-permissions": "{{PLURAL:$1|權限}}:",
        "api-help-permissions-granted-to": "{{PLURAL:$1|已授權給}}: $2",
+       "api-help-right-apihighlimits": "在 API 查詢使用較高的限制(慢查詢:$1;快查詢:$2)。慢查詢的限制也適用於多值參數。",
        "api-help-open-in-apisandbox": "<small>[在沙盒中開啟]</small>",
        "api-help-authmanager-general-usage": "使用此模組的一般程式是:\n# 通過 <kbd>amirequestsfor=$4</kbd> 取得來自 <kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd> 的可用欄位,和來自 <kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd> 的<kbd>$5</kbd>權杖。\n# 向用戶顯示欄位,並獲得其提交的內容。\n# 提交(POST)至此模組,提供 <var>$1returnurl</var> 及任何相關欄位。\n# 在回應中檢查 <samp>status</samp>。\n#* 如果您收到了 <samp>PASS</samp>(成功)或<samp>FAIL</samp>(失敗),則認為操作結束。成功與否如上句所示。\n#* 如果您收到了 <samp>UI</samp>,向用戶顯示新欄位,並再次獲取其提交的內容。然後再次使用 <var>$1continue</var>,向本模組提交相關欄位,並重復第四步。\n#* 如果您收到了 <samp>REDIRECT</samp>,將使用者指向<samp>redirecttarget</samp> 中的目標,等待其返回<var>$1returnurl</var>。然後再次使用 <var>$1continue</var>,向本模組提交返回 URL 中提供的一切欄位,並重復第四步。\n#* 如果您收到了 <samp>RESTART</samp>,這意味著身份驗證正常運作,但我們沒有連結的使用者帳戶。您可以將此視為 <samp>UI</samp>或<samp>FAIL</samp>。",
        "api-help-authmanagerhelper-requests": "只使用這些身份驗證請求,透過自<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>回傳的<samp>id</samp>與<kbd>amirequestsfor=$1</kbd>,或來自此模組之前的回應。",
        "api-help-authmanagerhelper-returnurl": "為第三方身份驗證流程傳回URL,必須為絕對值。需要此值或<var>$1continue</var>兩者之一。\n\n在接收<samp>REDIRECT</samp>回應時,一般狀況下您將打開瀏覽器或網站瀏覽功能到特定的<samp>redirecttarget</samp> URL以進行第三方身份驗證流程。當它完成時,第三方會將瀏覽器或網站瀏覽功能送至此URL。您應當提取任何來自URL的查詢或POST參數,並將之作為<var>$1continue</var>請求傳遞至此API模組。",
        "api-help-authmanagerhelper-continue": "此請求是在先前的<samp>UI</samp>或<samp>REDIRECT</samp>回應之後的後續動作。必須為此值或<var>$1returnurl</var>。",
        "api-help-authmanagerhelper-additional-params": "此模組允許額外參數,取決於可用的身份驗證請求。使用<kbd>[[Special:ApiHelp/query+authmanagerinfo|action=query&meta=authmanagerinfo]]</kbd>与<kbd>amirequestsfor=$1</kbd>(或之前來自此模組的回應,如果合適)以決定可用請求及其使用的欄位。",
+       "apierror-allimages-redirect": "當使用 <kbd>allimages</kbd> 作為產生器時,請改用 <kbd>gaifilterredir=nonredirects</kbd> 而不是 <var>redirects</var>。",
+       "apierror-allpages-generator-redirects": "當使用 <kbd>allpages</kbd> 作為產生器時,請改用 <kbd>gapfilterredir=nonredirects</kbd> 而不是 <var>redirects</var>。",
        "apierror-appendnotsupported": "無法附加到使用內容模組 $1 的頁面。",
        "apierror-articleexists": "您所嘗試建立的條目剛剛已被創建。",
        "apierror-assertbotfailed": "斷言使用者擁有的 <code>bot</code> 權限失效。",
        "apierror-autoblocked": "您的 IP 位址已經被自動封鎖,因為它曾經被一名已封鎖的使用者使用過。",
        "apierror-bad-badfilecontexttitle": "在 <var>$1badfilecontexttitle</var> 參數的無效標題。",
        "apierror-badconfig-resulttoosmall": "在此 wiki 上 <code>$wgAPIMaxResultSize</code> 的值太小,而無法含有基本結果資訊。",
+       "apierror-badcontinue": "無效的繼續參數。您應該傳遞由前一個查詢所回傳的原有值。",
+       "apierror-baddiff": "無法取得差異。不存在一個或兩個修訂,或是您沒有權限來檢視它們。",
        "apierror-baddiffto": "<var>$1diffto</var> 必須設定成非負值的數字、<kbd>prev</kbd>、<kbd>next</kbd>、或 <kbd>cur</kbd>。",
        "apierror-badformat-generic": "內容模組 $2 不支援使用請求格式 $1。",
+       "apierror-badformat": "由 $3 所使用的內容模組 $2 不支援使用請求格式 $1。",
        "apierror-badgenerator-notgenerator": "模組 <kbd>$1</kbd> 不能作為產生器。",
        "apierror-badgenerator-unknown": "未知的 <kbd>generator=$1</kbd>。",
        "apierror-badip": "IP 參數無效。",
        "apierror-badquery": "無效的查詢。",
        "apierror-badtimestamp": "用於時間戳記參數 <var>$1</var> 的值「$2」無效。",
        "apierror-badtoken": "無效 CSRF 權杖。",
+       "apierror-badupload": "檔案上傳參數 <var>$1</var> 不是一個檔案上傳,請確定在您的 POST 有使用 <code>multipart/form-data</code>,並且在 <code>Content-Disposition</code> 標頭有包含檔案名稱。",
+       "apierror-badurl": "用於 URL 參數 <var>$1</var> 的值「$2」無效。",
+       "apierror-baduser": "用於使用者參數 <var>$1</var> 的值「$2」無效。",
        "apierror-bad-watchlist-token": "提供無效的監視清單權杖。請在 [[Special:Preferences]] 設定正確權杖。",
        "apierror-blockedfrommail": "您已被封鎖,無法發送電子郵件。",
        "apierror-blocked": "您已被封鎖,無法編輯。",
        "apierror-cantundelete": "無法取消刪除:請求的修訂可能不存在,或是可能已被取消刪除。",
        "apierror-changeauth-norequest": "建立更改請求失敗。",
        "apierror-cidrtoobroad": "不能接受超出 /$2 的 $1 CIDR 範圍。",
+       "apierror-compare-no-title": "無法在不帶標題之下預先儲存轉換。請嘗試指定 <var>fromtitle</var> 或 <var>totitle</var>。",
+       "apierror-compare-nosuchfromsection": "在 'from' 內容裡沒有段落$1。",
+       "apierror-compare-nosuchtosection": "在 'to' 內容裡沒有段落$1。",
        "apierror-compare-notext": "參數 <var>$1</var> 不能在缺少 <var>$2</var> 的情況下使用。",
        "apierror-contentserializationexception": "內容序列化失敗:$1",
        "apierror-copyuploadbaddomain": "不允許從此網域來透過 URL 上傳。",
        "apierror-invalidoldimage": "<var>oldimage</var> 參數含有無效格式。",
        "apierror-invalidparammix-cannotusewith": "參數 <kbd>$1</kbd> 不能與 <kbd>$2</kbd> 一起使用。",
        "apierror-invalidparammix-mustusewith": "<kbd>$1</kbd> 參數僅能與 <kbd>$2</kbd> 一起使用。",
+       "apierror-invalidparammix-parse-new-section": "<kbd>section=new</kbd> 不能連同 <var>oldid</var>、<var>pageid</var>、或 <var>page</var> 參數。請使用 <var>title</var> 與 <var>text</var>。",
        "apierror-invalidparammix": "{{PLURAL:$2|參數}} $1 不能一起使用。",
+       "apierror-invalidsection": "<var>section</var> 參數必須是有效的段落 ID 或 <kbd>new</kbd>。",
        "apierror-invalidsha1base36hash": "所提供的 SHA1Base36 雜湊無效。",
        "apierror-invalidsha1hash": "所提供的 SHA1 雜湊無效。",
        "apierror-invalidtitle": "錯誤標題「$1」。",
        "apierror-systemblocked": "您已被 MediaWiki 給自動封鎖。",
        "apierror-templateexpansion-notwikitext": "模板擴展僅支援用於 wiki 文字內容。$1使用內容模組 $2。",
        "apierror-timeout": "伺服器未有在預計的時間內回應。",
+       "apierror-toofewexpiries": "提供了 $1 個逾期{{PLURAL:$1|時間戳記|時間戳記}},所需要的{{PLURAL:$2|是|是}} $2 個。",
        "apierror-toomanyvalues": "替參數 <var>$1</var> 提供太多的值。限制為 $2。",
        "apierror-unknownaction": "指定的操作 <kbd>$1</kbd> 無法識別出。",
        "apierror-unknownerror-editpage": "不明編輯頁面錯誤:$1。",
        "apierror-writeapidenied": "您不被允許透過 API 來編輯此 wiki。",
        "apiwarn-alldeletedrevisions-performance": "為了在產生標題時能有更好效能,請設定 <kbd>$1dir=newer</kbd>。",
        "apiwarn-badurlparam": "無法解析$2的 <var>$1urlparam</var>。這僅能用在寬度與高度。",
+       "apiwarn-checktoken-percentencoding": "在 URL 裡進行適當百分比編碼的權杖中,檢查像是「+」的符號。",
        "apiwarn-compare-nocontentmodel": "沒有可確定的內容模組,假定為 $1。",
        "apiwarn-deprecation-deletedrevs": "<kbd>list=deletedrevs</kbd> 已棄用。請改用 <kbd>prop=deletedrevisions</kbd> 或 <kbd>list=alldeletedrevisions</kbd>。",
        "apiwarn-deprecation-httpsexpected": "當應為 HTTPS 時,HTTP 要被使用。",
+       "apiwarn-deprecation-login-botpw": "透過 <kbd>action=login</kbd> 的主帳號登入已棄用,並可能會在無警告的情況下停止運作。要繼續以 <kbd>action=clientlogin</kbd> 登入,請參閱 [[Special:BotPasswords]];若要繼續安全使用主帳號登入,則請參閱 <kbd>action=clientlogin</kbd>。",
+       "apiwarn-deprecation-login-nobotpw": "透過 <kbd>action=login</kbd> 的主帳號登入已棄用,並可能會在無警告的情況下停止運作。若要安全登入,請參閱 <kbd>action=clientlogin</kbd>。",
        "apiwarn-deprecation-login-token": "透過 <kbd>action=login</kbd> 來取得權杖已棄用。請改用 <kbd>action=query&meta=tokens&type=login</kbd>。",
+       "apiwarn-deprecation-missingparam": "因為未指定 <var>$1</var>,輸出內容使用到過去舊有的格式。該格式已棄用,並且往後都只會使用新格式。",
        "apiwarn-deprecation-parameter": "參數 <var>$1</var> 已棄用。",
        "apiwarn-deprecation-parse-headitems": "<kbd>prop=headitems</kbd> 自 MediaWiki 的 1.28 版本後已被棄用。當建立新 HTML 文件時請使用 <kbd>prop=headhtml</kbd>,或是當更新文件客戶端時請使用 <kbd>prop=modules|jsconfigvars</kbd>。",
        "apiwarn-deprecation-purge-get": "透過 GET 方式使用的 <kbd>action=purge</kbd> 已棄用,請以 POST 替代。",
        "apiwarn-notfile": "「$1」不是一個檔案。",
        "apiwarn-nothumb-noimagehandler": "無法建立縮圖,因為$1沒有相關的圖片處理器。",
        "apiwarn-parse-nocontentmodel": "未提供 <var>title</var> 或 <var>contentmodel</var>,應是 $1。",
+       "apiwarn-parse-revidwithouttext": "<var>revid</var> 在不帶有 <var>text</var> 的情況下使用,且請求了已解析頁面屬性。請問您是指要使用 <var>oldid</var> 而不是 <var>revid</var> 嗎?",
+       "apiwarn-parse-titlewithouttext": "<var>title</var> 在不帶有 <var>text</var> 的情況下使用,且請求了已解析頁面屬性。請問您是指要使用 <var>page</var> 而不是 <var>title</var> 嗎?",
        "apiwarn-tokennotallowed": "「$1」操作不允許目前的使用者。",
        "apiwarn-tokens-origin": "當未套用相同來源方針,權杖可能無法取得。",
        "apiwarn-truncatedresult": "結果會被截短,否則將會大於 $1 位元組限制。",
index 43d70e6..5bf286d 100644 (file)
@@ -34,7 +34,6 @@ class BlockRestriction {
         *
         * @param int|array $blockId
         * @param IDatabase|null $db
-        * @param array $options Options to pass to the select query.
         * @return Restriction[]
         */
        public static function loadByBlockId( $blockId, IDatabase $db = null ) {
index f1cc1b0..5fefecc 100644 (file)
@@ -63,6 +63,7 @@ interface Restriction {
        /**
         * Creates a new Restriction from a database row.
         *
+        * @param \stdClass $row
         * @return self
         */
        public static function newFromRow( \stdClass $row );
index 0e36009..5e83f95 100644 (file)
@@ -262,8 +262,6 @@ class ChangeTags {
                &$rev_id = null, &$log_id = null, $params = null, RecentChange $rc = null,
                User $user = null
        ) {
-               global $wgChangeTagsSchemaMigrationStage;
-
                $tagsToAdd = array_filter( (array)$tagsToAdd ); // Make sure we're submitting all tags...
                $tagsToRemove = array_filter( (array)$tagsToRemove );
 
@@ -347,35 +345,27 @@ class ChangeTags {
                $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
                if ( count( $tagsToAdd ) ) {
                        $changeTagMapping = [];
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
-                               foreach ( $tagsToAdd as $tag ) {
-                                       $changeTagMapping[$tag] = $changeTagDefStore->acquireId( $tag );
-                               }
-                               // T207881: update the counts at the end of the transaction
-                               $dbw->onTransactionPreCommitOrIdle( function () use ( $dbw, $tagsToAdd ) {
-                                       $dbw->update(
-                                               'change_tag_def',
-                                               [ 'ctd_count = ctd_count + 1' ],
-                                               [ 'ctd_name' => $tagsToAdd ],
-                                               __METHOD__
-                                       );
-                               } );
+                       foreach ( $tagsToAdd as $tag ) {
+                               $changeTagMapping[$tag] = $changeTagDefStore->acquireId( $tag );
                        }
+                       // T207881: update the counts at the end of the transaction
+                       $dbw->onTransactionPreCommitOrIdle( function () use ( $dbw, $tagsToAdd ) {
+                               $dbw->update(
+                                       'change_tag_def',
+                                       [ 'ctd_count = ctd_count + 1' ],
+                                       [ 'ctd_name' => $tagsToAdd ],
+                                       __METHOD__
+                               );
+                       } );
 
                        $tagsRows = [];
                        foreach ( $tagsToAdd as $tag ) {
-                               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                                       $tagName = null;
-                               } else {
-                                       $tagName = $tag;
-                               }
                                // Filter so we don't insert NULLs as zero accidentally.
                                // Keep in mind that $rc_id === null means "I don't care/know about the
                                // rc_id, just delete $tag on this revision/log entry". It doesn't
                                // mean "only delete tags on this revision/log WHERE rc_id IS NULL".
                                $tagsRows[] = array_filter(
                                        [
-                                               'ct_tag' => $tagName,
                                                'ct_rc_id' => $rc_id,
                                                'ct_log_id' => $log_id,
                                                'ct_rev_id' => $rev_id,
@@ -392,24 +382,16 @@ class ChangeTags {
                // delete from change_tag
                if ( count( $tagsToRemove ) ) {
                        foreach ( $tagsToRemove as $tag ) {
-                               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                                       $tagName = null;
-                                       $tagId = $changeTagDefStore->getId( $tag );
-                               } else {
-                                       $tagName = $tag;
-                                       $tagId = null;
-                               }
                                $conds = array_filter(
                                        [
-                                               'ct_tag' => $tagName,
                                                'ct_rc_id' => $rc_id,
                                                'ct_log_id' => $log_id,
                                                'ct_rev_id' => $rev_id,
-                                               'ct_tag_id' => $tagId,
+                                               'ct_tag_id' => $changeTagDefStore->getId( $tag ),
                                        ]
                                );
                                $dbw->delete( 'change_tag', $conds, __METHOD__ );
-                               if ( $dbw->affectedRows() && $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
+                               if ( $dbw->affectedRows() ) {
                                        // T207881: update the counts at the end of the transaction
                                        $dbw->onTransactionPreCommitOrIdle( function () use ( $dbw, $tag ) {
                                                $dbw->update(
@@ -788,7 +770,7 @@ class ChangeTags {
        public static function modifyDisplayQuery( &$tables, &$fields, &$conds,
                &$join_conds, &$options, $filter_tag = ''
        ) {
-               global $wgUseTagFilter, $wgChangeTagsSchemaMigrationStage;
+               global $wgUseTagFilter;
 
                // Normalize to arrays
                $tables = (array)$tables;
@@ -796,6 +778,8 @@ class ChangeTags {
                $conds = (array)$conds;
                $options = (array)$options;
 
+               $fields['ts_tags'] = self::makeTagSummarySubquery( $tables );
+
                // Figure out which ID field to use
                if ( in_array( 'recentchanges', $tables ) ) {
                        $join_cond = 'ct_rc_id=rc_id';
@@ -809,44 +793,26 @@ class ChangeTags {
                        throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' );
                }
 
-               $tagTables[] = 'change_tag';
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                       $tagTables[] = 'change_tag_def';
-                       $join_cond_ts_tags = [ 'change_tag_def' => [ 'INNER JOIN', 'ct_tag_id=ctd_id' ] ];
-                       $field = 'ctd_name';
-               } else {
-                       $field = 'ct_tag';
-                       $join_cond_ts_tags = [];
-               }
-
-               $fields['ts_tags'] = wfGetDB( DB_REPLICA )->buildGroupConcatField(
-                       ',', $tagTables, $field, $join_cond, $join_cond_ts_tags
-               );
-
                if ( $wgUseTagFilter && $filter_tag ) {
                        // Somebody wants to filter on a tag.
                        // Add an INNER JOIN on change_tag
 
                        $tables[] = 'change_tag';
                        $join_conds['change_tag'] = [ 'INNER JOIN', $join_cond ];
-                       if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                               $filterTagIds = [];
-                               $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
-                               foreach ( (array)$filter_tag as $filterTagName ) {
-                                       try {
-                                               $filterTagIds[] = $changeTagDefStore->getId( $filterTagName );
-                                       } catch ( NameTableAccessException $exception ) {
-                                               // Return nothing.
-                                               $conds[] = '0';
-                                               break;
-                                       };
-                               }
+                       $filterTagIds = [];
+                       $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
+                       foreach ( (array)$filter_tag as $filterTagName ) {
+                               try {
+                                       $filterTagIds[] = $changeTagDefStore->getId( $filterTagName );
+                               } catch ( NameTableAccessException $exception ) {
+                                       // Return nothing.
+                                       $conds[] = '0';
+                                       break;
+                               };
+                       }
 
-                               if ( $filterTagIds !== [] ) {
-                                       $conds['ct_tag_id'] = $filterTagIds;
-                               }
-                       } else {
-                               $conds['ct_tag'] = $filter_tag;
+                       if ( $filterTagIds !== [] ) {
+                               $conds['ct_tag_id'] = $filterTagIds;
                        }
 
                        if (
@@ -858,6 +824,40 @@ class ChangeTags {
                }
        }
 
+       /**
+        * Make the tag summary subquery based on the given tables and return it.
+        *
+        * @param string|array $tables Table names, see Database::select
+        *
+        * @return string tag summary subqeury
+        * @throws MWException When unable to determine appropriate JOIN condition for tagging
+        */
+       public static function makeTagSummarySubquery( $tables ) {
+               // Normalize to arrays
+               $tables = (array)$tables;
+
+               // Figure out which ID field to use
+               if ( in_array( 'recentchanges', $tables ) ) {
+                       $join_cond = 'ct_rc_id=rc_id';
+               } elseif ( in_array( 'logging', $tables ) ) {
+                       $join_cond = 'ct_log_id=log_id';
+               } elseif ( in_array( 'revision', $tables ) ) {
+                       $join_cond = 'ct_rev_id=rev_id';
+               } elseif ( in_array( 'archive', $tables ) ) {
+                       $join_cond = 'ct_rev_id=ar_rev_id';
+               } else {
+                       throw new MWException( 'Unable to determine appropriate JOIN condition for tagging.' );
+               }
+
+               $tagTables = [ 'change_tag', 'change_tag_def' ];
+               $join_cond_ts_tags = [ 'change_tag_def' => [ 'INNER JOIN', 'ct_tag_id=ctd_id' ] ];
+               $field = 'ctd_name';
+
+               return wfGetDB( DB_REPLICA )->buildGroupConcatField(
+                       ',', $tagTables, $field, $join_cond, $join_cond_ts_tags
+               );
+       }
+
        /**
         * Build a text box to select a change tag
         *
@@ -918,32 +918,20 @@ class ChangeTags {
         * @since 1.25
         */
        public static function defineTag( $tag ) {
-               global $wgChangeTagsSchemaMigrationStage;
-
                $dbw = wfGetDB( DB_MASTER );
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
-                       $tagDef = [
-                               'ctd_name' => $tag,
-                               'ctd_user_defined' => 1,
-                               'ctd_count' => 0
-                       ];
-                       $dbw->upsert(
-                               'change_tag_def',
-                               $tagDef,
-                               [ 'ctd_name' ],
-                               [ 'ctd_user_defined' => 1 ],
-                               __METHOD__
-                       );
-               }
+               $tagDef = [
+                       'ctd_name' => $tag,
+                       'ctd_user_defined' => 1,
+                       'ctd_count' => 0
+               ];
+               $dbw->upsert(
+                       'change_tag_def',
+                       $tagDef,
+                       [ 'ctd_name' ],
+                       [ 'ctd_user_defined' => 1 ],
+                       __METHOD__
+               );
 
-               if ( $wgChangeTagsSchemaMigrationStage < MIGRATION_NEW ) {
-                       $dbw->replace(
-                               'valid_tag',
-                               [ 'vt_tag' ],
-                               [ 'vt_tag' => $tag ],
-                               __METHOD__
-                       );
-               }
                // clear the memcache of defined tags
                self::purgeTagCacheAll();
        }
@@ -957,28 +945,20 @@ class ChangeTags {
         * @since 1.25
         */
        public static function undefineTag( $tag ) {
-               global $wgChangeTagsSchemaMigrationStage;
-
                $dbw = wfGetDB( DB_MASTER );
 
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
-                       $dbw->update(
-                               'change_tag_def',
-                               [ 'ctd_user_defined' => 0 ],
-                               [ 'ctd_name' => $tag ],
-                               __METHOD__
-                       );
-
-                       $dbw->delete(
-                               'change_tag_def',
-                               [ 'ctd_name' => $tag, 'ctd_count' => 0 ],
-                               __METHOD__
-                       );
-               }
+               $dbw->update(
+                       'change_tag_def',
+                       [ 'ctd_user_defined' => 0 ],
+                       [ 'ctd_name' => $tag ],
+                       __METHOD__
+               );
 
-               if ( $wgChangeTagsSchemaMigrationStage < MIGRATION_NEW ) {
-                       $dbw->delete( 'valid_tag', [ 'vt_tag' => $tag ], __METHOD__ );
-               }
+               $dbw->delete(
+                       'change_tag_def',
+                       [ 'ctd_name' => $tag, 'ctd_count' => 0 ],
+                       __METHOD__
+               );
 
                // clear the memcache of defined tags
                self::purgeTagCacheAll();
@@ -1280,19 +1260,14 @@ class ChangeTags {
         * @since 1.25
         */
        public static function deleteTagEverywhere( $tag ) {
-               global $wgChangeTagsSchemaMigrationStage;
                $dbw = wfGetDB( DB_MASTER );
                $dbw->startAtomic( __METHOD__ );
 
                // delete from valid_tag and/or set ctd_user_defined = 0
                self::undefineTag( $tag );
 
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                       $tagId = MediaWikiServices::getInstance()->getChangeTagDefStore()->getId( $tag );
-                       $conditions = [ 'ct_tag_id' => $tagId ];
-               } else {
-                       $conditions = [ 'ct_tag' => $tag ];
-               }
+               $tagId = MediaWikiServices::getInstance()->getChangeTagDefStore()->getId( $tag );
+               $conditions = [ 'ct_tag_id' => $tagId ];
 
                // find out which revisions use this tag, so we can delete from tag_summary
                $result = $dbw->select( 'change_tag',
@@ -1308,17 +1283,9 @@ class ChangeTags {
                }
 
                // delete from change_tag
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                       $tagId = MediaWikiServices::getInstance()->getChangeTagDefStore()->getId( $tag );
-                       $dbw->delete( 'change_tag', [ 'ct_tag_id' => $tagId ], __METHOD__ );
-               } else {
-                       $dbw->delete( 'change_tag', [ 'ct_tag' => $tag ], __METHOD__ );
-               }
-
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_OLD ) {
-                       $dbw->delete( 'change_tag_def', [ 'ctd_name' => $tag ], __METHOD__ );
-               }
-
+               $tagId = MediaWikiServices::getInstance()->getChangeTagDefStore()->getId( $tag );
+               $dbw->delete( 'change_tag', [ 'ct_tag_id' => $tagId ], __METHOD__ );
+               $dbw->delete( 'change_tag_def', [ 'ctd_name' => $tag ], __METHOD__ );
                $dbw->endAtomic( __METHOD__ );
 
                // give extensions a chance
@@ -1484,16 +1451,16 @@ class ChangeTags {
                        $cache->makeKey( 'valid-tags-db' ),
                        WANObjectCache::TTL_MINUTE * 5,
                        function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
-                               global $wgChangeTagsSchemaMigrationStage;
                                $dbr = wfGetDB( DB_REPLICA );
 
                                $setOpts += Database::getCacheSetOptions( $dbr );
 
-                               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                                       $tags = self::listExplicitlyDefinedTagsNewBackend();
-                               } else {
-                                       $tags = $dbr->selectFieldValues( 'valid_tag', 'vt_tag', [], $fname );
-                               }
+                               $tags = $dbr->selectFieldValues(
+                                       'change_tag_def',
+                                       'ctd_name',
+                                       [ 'ctd_user_defined' => 1 ],
+                                       __METHOD__
+                               );
 
                                return array_filter( array_unique( $tags ) );
                        },
@@ -1505,22 +1472,6 @@ class ChangeTags {
                );
        }
 
-       /**
-        * Lists tags explicitly user defined tags. When ctd_user_defined is true.
-        *
-        * @return string[] Array of strings: tags
-        * @since 1.25
-        */
-       private static function listExplicitlyDefinedTagsNewBackend() {
-               $dbr = wfGetDB( DB_REPLICA );
-               return $dbr->selectFieldValues(
-                       'change_tag_def',
-                       'ctd_name',
-                       [ 'ctd_user_defined' => 1 ],
-                       __METHOD__
-               );
-       }
-
        /**
         * Lists tags defined by core or extensions using the ListDefinedTags hook.
         * Extensions need only define those tags they deem to be in active use.
@@ -1583,57 +1534,9 @@ class ChangeTags {
         * Returns a map of any tags used on the wiki to number of edits
         * tagged with them, ordered descending by the hitcount.
         * This does not include tags defined somewhere that have never been applied.
-        *
-        * Keeps a short-term cache in memory, so calling this multiple times in the
-        * same request should be fine.
-        *
         * @return array Array of string => int
         */
        public static function tagUsageStatistics() {
-               global $wgChangeTagsSchemaMigrationStage;
-               if ( $wgChangeTagsSchemaMigrationStage > MIGRATION_WRITE_BOTH ) {
-                       return self::newTagUsageStatistics();
-               }
-
-               $fname = __METHOD__;
-               $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
-               return $cache->getWithSetCallback(
-                       $cache->makeKey( 'change-tag-statistics' ),
-                       WANObjectCache::TTL_MINUTE * 5,
-                       function ( $oldValue, &$ttl, array &$setOpts ) use ( $fname ) {
-                               $dbr = wfGetDB( DB_REPLICA, 'vslow' );
-
-                               $setOpts += Database::getCacheSetOptions( $dbr );
-
-                               $res = $dbr->select(
-                                       'change_tag',
-                                       [ 'ct_tag', 'hitcount' => 'count(*)' ],
-                                       [],
-                                       $fname,
-                                       [ 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' ]
-                               );
-
-                               $out = [];
-                               foreach ( $res as $row ) {
-                                       $out[$row->ct_tag] = $row->hitcount;
-                               }
-
-                               return $out;
-                       },
-                       [
-                               'checkKeys' => [ $cache->makeKey( 'change-tag-statistics' ) ],
-                               'lockTSE' => WANObjectCache::TTL_MINUTE * 5,
-                               'pcTTL' => WANObjectCache::TTL_PROC_LONG
-                       ]
-               );
-       }
-
-       /**
-        * Same self::tagUsageStatistics() but uses change_tag_def.
-        *
-        * @return array Array of string => int
-        */
-       private static function newTagUsageStatistics() {
                $dbr = wfGetDB( DB_REPLICA );
                $res = $dbr->select(
                        'change_tag_def',
index bb3fb10..1bb43f8 100644 (file)
@@ -241,6 +241,8 @@ interface Content {
         * that it's also in a countable location (e.g. a current revision in the
         * main namespace).
         *
+        * @see SlotRoleHandler::supportsArticleCount
+        *
         * @since 1.21
         *
         * @param bool|null $hasLinks If it is known whether this content contains
@@ -352,6 +354,8 @@ interface Content {
         * Returns whether this Content represents a redirect.
         * Shorthand for getRedirectTarget() !== null.
         *
+        * @see SlotRoleHandler::supportsRedirects
+        *
         * @since 1.21
         *
         * @return bool
index fab043a..5c18a33 100644 (file)
@@ -174,62 +174,17 @@ abstract class ContentHandler {
         * Note: this is used by, and may thus not use, Title::getContentModel()
         *
         * @since 1.21
+        * @deprecated since 1.33, use SlotRoleHandler::getDefaultModel() together with
+        * SlotRoleRegistry::getRoleHandler().
         *
         * @param Title $title
         *
         * @return string Default model name for the page given by $title
         */
        public static function getDefaultModelFor( Title $title ) {
-               // NOTE: this method must not rely on $title->getContentModel() directly or indirectly,
-               //       because it is used to initialize the mContentModel member.
-
-               $ns = $title->getNamespace();
-
-               $ext = false;
-               $m = null;
-               $model = MWNamespace::getNamespaceContentModel( $ns );
-
-               // Hook can determine default model
-               if ( !Hooks::run( 'ContentHandlerDefaultModelFor', [ $title, &$model ] ) ) {
-                       if ( !is_null( $model ) ) {
-                               return $model;
-                       }
-               }
-
-               // Could this page contain code based on the title?
-               $isCodePage = NS_MEDIAWIKI == $ns && preg_match( '!\.(css|js|json)$!u', $title->getText(), $m );
-               if ( $isCodePage ) {
-                       $ext = $m[1];
-               }
-
-               // Is this a user subpage containing code?
-               $isCodeSubpage = NS_USER == $ns
-                       && !$isCodePage
-                       && preg_match( "/\\/.*\\.(js|css|json)$/", $title->getText(), $m );
-               if ( $isCodeSubpage ) {
-                       $ext = $m[1];
-               }
-
-               // Is this wikitext, according to $wgNamespaceContentModels or the DefaultModelFor hook?
-               $isWikitext = is_null( $model ) || $model == CONTENT_MODEL_WIKITEXT;
-               $isWikitext = $isWikitext && !$isCodePage && !$isCodeSubpage;
-
-               if ( !$isWikitext ) {
-                       switch ( $ext ) {
-                               case 'js':
-                                       return CONTENT_MODEL_JAVASCRIPT;
-                               case 'css':
-                                       return CONTENT_MODEL_CSS;
-                               case 'json':
-                                       return CONTENT_MODEL_JSON;
-                               default:
-                                       return is_null( $model ) ? CONTENT_MODEL_TEXT : $model;
-                       }
-               }
-
-               // We established that it must be wikitext
-
-               return CONTENT_MODEL_WIKITEXT;
+               $slotRoleregistry = MediaWikiServices::getInstance()->getSlotRoleRegistry();
+               $mainSlotHandler = $slotRoleregistry->getRoleHandler( 'main' );
+               return $mainSlotHandler->getDefaultModel( $title );
        }
 
        /**
@@ -777,7 +732,7 @@ abstract class ContentHandler {
 
        /**
         * Determines whether the content type handled by this ContentHandler
-        * can be used on the given page.
+        * can be used for the main slot of the given page.
         *
         * This default implementation always returns true.
         * Subclasses may override this to restrict the use of this content model to specific locations,
@@ -787,6 +742,8 @@ abstract class ContentHandler {
         * @note this calls the ContentHandlerCanBeUsedOn hook which may be used to override which
         * content model can be used where.
         *
+        * @see SlotRoleHandler::isAllowedModel
+        *
         * @param Title $title The page's title.
         *
         * @return bool True if content of this kind can be used on the given page, false otherwise.
index a7021b1..517d807 100644 (file)
@@ -25,6 +25,7 @@
  * @author Daniel Kinzler
  */
 
+use MediaWiki\Logger\LoggerFactory;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -41,6 +42,11 @@ class WikitextContent extends TextContent {
         */
        private $hadSignature = false;
 
+       /**
+        * @var array|null Stack trace of the previous parse
+        */
+       private $previousParseStackTrace = null;
+
        public function __construct( $text ) {
                parent::__construct( $text, CONTENT_MODEL_WIKITEXT );
        }
@@ -337,6 +343,28 @@ class WikitextContent extends TextContent {
        ) {
                global $wgParser;
 
+               $stackTrace = ( new RuntimeException() )->getTraceAsString();
+               if ( $this->previousParseStackTrace ) {
+                       // NOTE: there may be legitimate changes to re-parse the same WikiText content,
+                       // e.g. if predicted revision ID for the REVISIONID magic word mismatched.
+                       // But that should be rare.
+                       $logger = LoggerFactory::getInstance( 'DuplicateParse' );
+                       $logger->debug(
+                               __METHOD__ . ': Possibly redundant parse!',
+                               [
+                                       'title' => $title->getPrefixedDBkey(),
+                                       'rev' => $revId,
+                                       'options-hash' => $options->optionsHash(
+                                               ParserOptions::allCacheVaryingOptions(),
+                                               $title
+                                       ),
+                                       'trace' => $stackTrace,
+                                       'previous-trace' => $this->previousParseStackTrace,
+                               ]
+                       );
+               }
+               $this->previousParseStackTrace = $stackTrace;
+
                list( $redir, $text ) = $this->getRedirectTargetAndText();
                $output = $wgParser->parse( $text, $title, $options, true, true, $revId );
 
index 5f09555..d427724 100644 (file)
@@ -137,7 +137,7 @@ class CloneDatabase {
                global $wgDBprefix;
 
                $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
-               $lbFactory->setDomainPrefix( $prefix );
+               $lbFactory->setLocalDomainPrefix( $prefix );
                $wgDBprefix = $prefix;
        }
 }
index 780ea94..ee3e9a1 100644 (file)
@@ -62,7 +62,7 @@ class SyslogHandler extends SyslogUdpHandler {
         * @param string $host Syslog host
         * @param int $port Syslog port
         * @param int $facility Syslog message facility
-        * @param string $level The minimum logging level at which this handler
+        * @param int $level The minimum logging level at which this handler
         *   will be triggered
         * @param bool $bubble Whether the messages that are handled can bubble up
         *   the stack or not
index 8d0971e..63cc2a8 100644 (file)
@@ -1055,7 +1055,7 @@ class DifferenceEngine extends ContextSource {
                        $slotDiff = $slotDiffRenderer->getDiff( $slotContents[$role]['old'],
                                $slotContents[$role]['new'] );
                        if ( $slotDiff && $role !== SlotRecord::MAIN ) {
-                               // TODO use human-readable role name at least
+                               // FIXME: ask SlotRoleHandler::getSlotNameMessage
                                $slotTitle = $role;
                                $difftext .= $this->getSlotHeader( $slotTitle );
                        }
index af835e4..7f70c4f 100644 (file)
@@ -121,7 +121,7 @@ class MWException extends Exception {
                                        "Fatal exception of type $1",
                                        $type,
                                        $logId,
-                                       MWExceptionHandler::getURL( $this )
+                                       MWExceptionHandler::getURL()
                                )
                        ) ) .
                        "<!-- Set \$wgShowExceptionDetails = true; " .
index 1349c54..088c7b1 100644 (file)
@@ -67,7 +67,7 @@ class DumpFilter {
         * @param string $string
         */
        function writeOpenPage( $page, $string ) {
-               $this->sendingThisPage = $this->pass( $page, $string );
+               $this->sendingThisPage = $this->pass( $page );
                if ( $this->sendingThisPage ) {
                        $this->sink->writeOpenPage( $page, $string );
                }
index edd73fc..ab925b7 100644 (file)
@@ -76,7 +76,6 @@ class DumpOutput {
        /**
         * Override to write to a different stream type.
         * @param string $string
-        * @return bool
         */
        function write( $string ) {
                print $string;
index fd3dc8b..aff0e3f 100644 (file)
@@ -77,9 +77,7 @@ class ForeignAPIFile extends File {
                        if ( $lastRedirect >= 0 ) {
                                $newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
                                $img = new self( $newtitle, $repo, $info, true );
-                               if ( $img ) {
-                                       $img->redirectedFrom( $title->getDBkey() );
-                               }
+                               $img->redirectedFrom( $title->getDBkey() );
                        } else {
                                $img = new self( $title, $repo, $info, true );
                        }
@@ -321,7 +319,7 @@ class ForeignAPIFile extends File {
         */
        function getThumbPath( $suffix = '' ) {
                if ( $this->repo->canCacheThumbs() ) {
-                       $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath( $this->getName() );
+                       $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
                        if ( $suffix ) {
                                $path = $path . $suffix . '/';
                        }
index e7bdb44..fb0ca77 100644 (file)
@@ -15,6 +15,7 @@ class HTMLExpiryField extends HTMLFormField {
 
        /**
         * Relative Date Time Field.
+        * @param array $params
         */
        public function __construct( array $params = [] ) {
                parent::__construct( $params );
index 477cc4c..1c4a785 100644 (file)
@@ -121,7 +121,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
 
        /**
         * Get options and make them into arrays suitable for OOUI.
-        * @return array Options for inclusion in a select or whatever.
+        * @throws MWException
         */
        public function getOptionsOOUI() {
                // Sections make this difficult. See getInputOOUI().
index 4a12d4c..db4cbdf 100644 (file)
@@ -152,6 +152,9 @@ class MssqlUpdater extends DatabaseUpdater {
                        [ 'addField', 'ipblocks', 'ipb_sitewide', 'patch-ipb_sitewide.sql' ],
                        [ 'addTable', 'ipblocks_restrictions', 'patch-ipblocks_restrictions-table.sql' ],
                        [ 'migrateImageCommentTemp' ],
+
+                       // 1.33
+                       [ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
                ];
        }
 
index 82cf7f4..532ccb0 100644 (file)
@@ -372,6 +372,9 @@ class MysqlUpdater extends DatabaseUpdater {
                        [ 'addField', 'ipblocks', 'ipb_sitewide', 'patch-ipb_sitewide.sql' ],
                        [ 'addTable', 'ipblocks_restrictions', 'patch-ipblocks_restrictions-table.sql' ],
                        [ 'migrateImageCommentTemp' ],
+
+                       // 1,33
+                       [ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
                ];
        }
 
index 78b53aa..19c4cfe 100644 (file)
@@ -164,6 +164,9 @@ class OracleUpdater extends DatabaseUpdater {
                        [ 'addTable', 'ipblocks_restrictions', 'patch-ipblocks_restrictions-table.sql' ],
                        [ 'migrateImageCommentTemp' ],
 
+                       // 1.33
+                       [ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
+
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
 
index 71c1a52..5730743 100644 (file)
@@ -598,6 +598,9 @@ class PostgresUpdater extends DatabaseUpdater {
                        [ 'addPgField', 'ipblocks', 'ipb_sitewide', 'SMALLINT NOT NULL DEFAULT 1' ],
                        [ 'addTable', 'ipblocks_restrictions', 'patch-ipblocks_restrictions-table.sql' ],
                        [ 'migrateImageCommentTemp' ],
+
+                       // 1.33
+                       [ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
                ];
        }
 
index cba6a8a..2f39912 100644 (file)
@@ -191,6 +191,7 @@ class SqliteUpdater extends DatabaseUpdater {
 
                        // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
                        [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
+                       [ 'addField', 'filearchive', 'fa_description_id', 'patch-filearchive-fa_description_id.sql' ],
 
                        [ 'migrateComments' ],
                        [ 'renameIndex', 'l10n_cache', 'lc_lang_key', 'PRIMARY', false,
@@ -204,6 +205,7 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
+                       [ 'addField', 'filearchive', 'fa_actor', 'patch-filearchive-fa_actor.sql' ],
                        [ 'migrateActors' ],
                        [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
                        [ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
@@ -237,6 +239,9 @@ class SqliteUpdater extends DatabaseUpdater {
                        [ 'addField', 'ipblocks', 'ipb_sitewide', 'patch-ipb_sitewide.sql' ],
                        [ 'addTable', 'ipblocks_restrictions', 'patch-ipblocks_restrictions-table.sql' ],
                        [ 'migrateImageCommentTemp' ],
+
+                       // 1.33
+                       [ 'dropField', 'change_tag', 'ct_tag', 'patch-drop-ct_tag.sql' ],
                ];
        }
 
index 953295a..4794712 100644 (file)
@@ -397,7 +397,7 @@ class WebInstallerOptions extends WebInstallerPage {
                $wrapperStyle = ( $this->getVar( '_LicenseCode' ) == 'cc-choose' ) ? '' : 'display: none';
 
                return "<div class=\"config-cc-wrapper\" id=\"config-cc-wrapper\" style=\"$wrapperStyle\">\n" .
-                       Html::element( 'iframe', $iframeAttribs, '', false /* not short */ ) .
+                       Html::element( 'iframe', $iframeAttribs ) .
                        "</div>\n";
        }
 
index a6157b5..46efc40 100644 (file)
@@ -39,14 +39,13 @@ class WebInstallerUpgrade extends WebInstallerPage {
                        if ( $this->parent->request->wasPosted() && !$this->getVar( '_ExistingDBSettings' ) ) {
                                // Done message acknowledged
                                return 'continue';
-                       } else {
-                               // Back button click
-                               // Show the done message again
-                               // Make them click back again if they want to do the upgrade again
-                               $this->showDoneMessage();
-
-                               return 'output';
                        }
+                       // Back button click
+                       // Show the done message again
+                       // Make them click back again if they want to do the upgrade again
+                       $this->showDoneMessage();
+
+                       return 'output';
                }
 
                // wgDBtype is generally valid here because otherwise the previous page
@@ -73,15 +72,13 @@ class WebInstallerUpgrade extends WebInstallerPage {
                                }
                                $this->setVar( '_UpgradeDone', true );
                                $this->showDoneMessage();
-
-                               return 'output';
                        } else {
                                $this->startForm();
                                $this->parent->showError( 'config-upgrade-error' );
                                $this->endForm();
-
-                               return 'output';
                        }
+
+                       return 'output';
                }
 
                $this->startForm();
index 5c262e5..5b3b94b 100644 (file)
        "config-regenerate": "إعادة تكوين LocalSettings.php ←",
        "config-show-table-status": "<code> إظهار جدول الحالة </code> فشل الاستعلام!",
        "config-unknown-collation": "<strong>تحذير:</strong> قاعدة بيانات يستخدم ترتيبا غير معروف.",
-       "config-db-web-account": "حساب قاعدة البيانات للوصول عبر الوب",
+       "config-db-web-account": "حساب قاعدة البيانات للوصول عبر الويب",
        "config-db-web-help": "حدد اسم المستخدم وكلمة المرور التي سيستخدمهما خادم الويب للاتصال بخادم قاعدة البيانات، أثناء عملية الويكي العادية.",
        "config-db-web-account-same": "استعمل نفس الحساب للتنصيب",
        "config-db-web-create": "إنشئ حساب إذا لم يكن موجودا بالفعل",
index af27650..74503b7 100644 (file)
@@ -25,8 +25,8 @@
        "config-localsettings-incomplete": "Existující soubor <code>LocalSettings.php</code> vypadá neúplný.\nNení nastavena proměnná $1.\nUpravte soubor <code>LocalSettings.php</code> tak, aby tuto proměnnou obsahoval, a klikněte na „{{int:Config-continue}}“.",
        "config-localsettings-connection-error": "Při připojování k databázi s využitím nastavení uvedených v <code>LocalSettings.php</code> došlo k chybě. Opravte tato nastavení a zkuste to znovu.\n\n$1",
        "config-session-error": "Nepodařilo se inicializovat relaci: $1",
-       "config-session-expired": "Platnost dat vašeho sezení patrně vypršela.\nSezení má nastavenu životnost $1.\nProdloužit ji můžete nastavením <code>session.gc_maxlifetime</code> v php.ini.\nSpusťte instalační proces od začátku.",
-       "config-no-session": "Data vašeho sezení se ztratila!\nZkontrolujte svůj soubor php.ini a ujistěte se, že <code>session.save_path</code> je nastaveno na odpovídající adresář.",
+       "config-session-expired": "Platnost dat vaší relace patrně vypršela.\nRelace má nastavenu životnost $1.\nProdloužit ji můžete nastavením <code>session.gc_maxlifetime</code> v php.ini.\nSpusťte instalační proces znovu.",
+       "config-no-session": "Data vaší relace se ztratila!\nZkontrolujte svůj soubor php.ini a ujistěte se, že <code>session.save_path</code> je nastaveno na odpovídající adresář.",
        "config-your-language": "Váš jazyk:",
        "config-your-language-help": "Zvolte jazyk, který se má použít v průběhu instalace.",
        "config-wiki-language": "Jazyk wiki:",
index c9d2886..f5aee2d 100644 (file)
@@ -38,7 +38,7 @@
        "config-env-hhvm": "HHVM $1 on installitud.",
        "config-diff3-bad": "GNU diff3 ei leitud.",
        "config-db-type": "Andmebaasi tüüp:",
-       "config-db-name": "Andmebaasi nimi:",
+       "config-db-name": "Andmebaasi nimi (sidekriipsudeta):",
        "config-db-name-oracle": "Andmebaasi skeem:",
        "config-db-username": "Andmebaasi kasutajanimi:",
        "config-db-password": "Andmebaasi parool:",
index 18c4103..2fb5ba4 100644 (file)
                ]
        },
        "config-desc": "Инсталациони програм за MediaWiki",
-       "config-title": "MediaWiki $1 инсталација",
+       "config-title": "Инсталација MediaWiki-ја $1",
        "config-information": "Информације",
        "config-localsettings-upgrade": "Откривена је датотека <code>LocalSettings.php</code>.\nДа бисте надоградили ову инсталацију, унесите вредност <code>$wgUpgradeKey</code> у оквиру испод.\nНаћи ћете је у <code>LocalSettings.php</code>-у.",
        "config-localsettings-cli-upgrade": "Откривена је датотека <code>LocalSettings.php</code>.\nДа бисте надоградили ову инсталацију, покрените <code>update.php</code>",
        "config-localsettings-key": "Кључ за надоградњу:",
        "config-localsettings-badkey": "Кључ за надоградњу који сте навели је погрешан.",
-       "config-upgrade-key-missing": "Откривена је постојећа MediaWiki инсталација.\nДа бисте надоградили ову инсталацију, поставите следећи ред кода на дно датотеке <code>LocalSettings.php</code>.\n\n$1",
+       "config-upgrade-key-missing": "Откривена је постојећа инсталација MediaWiki-ја.\nДа бисте надоградили ову инсталацију, поставите следећи ред кода на дно датотеке <code>LocalSettings.php</code>.\n\n$1",
        "config-localsettings-incomplete": "Постојећа датотека <code>LocalSettings.php</code> изгледа непотпуно.\nПроменљива $1 није постављена.\nПромените је тако што ћете поставити променљиву, па кликнути на „{{int:Config-continue}}”.",
        "config-localsettings-connection-error": "Дошло је до грешке при повезивању са базом података коришћењем подешавања наведених у датотеци <code>LocalSettings.php</code>. Поправите ова подешавања, па покушајте поново.\n\n$1",
        "config-session-error": "Грешка при започињању сесије: $1",
@@ -78,7 +78,7 @@
        "config-using-uri": "Коришћење URL адресе сервера „<nowiki>$1$2</nowiki>”.",
        "config-uploads-not-safe": "<strong>Упозорење:</strong> Ваш подразумевани директоријум за отпремања <code>$1</code> је подложан извршењу произвољних скрипти.\nИако MediaWiki проверава све отпремљене датотеке за безбедоносне претње, препоручује се [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security да затворите ову безбедоносну рањивост] пре омогућавања отпремања.",
        "config-no-cli-uploads-check": "<strong>Упозорење:</strong> Ваш подразумевани директоријум за отпремање (<code>$1</code>) није проверен на рањивост\nна произвољно извршавање скрипте током CLI инсталације.",
-       "config-using-32bit": "<strong>Упозорење:</strong> изгледа да ваш систем ради са 32-битним целим бројевима. Ово се не [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit препоручује].",
+       "config-using-32bit": "<strong>Упозорење:</strong> изгледа да ваш систем ради са 32-битним целим бројевима. Ово се [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit не препоручује].",
        "config-db-type": "Тип базе података:",
        "config-db-host": "Хост базе података",
        "config-db-host-oracle": "TNS базе података:",
        "config-skins-must-enable-some": "Морате одабрати барем једну тему за омогућавање.",
        "config-skins-must-enable-default": "Тема коју сте одабрали за подразумевану мора да се омогући.",
        "config-install-alreadydone": "<strong>Упозорење:</strong> Изгледа да већ имате инсталиран MediaWiki и покушавате да га поново инсталирате.\nПродужите ка следећој страници.",
-       "config-install-begin": "Притиском на „{{int:config-continue}}”, започећете инсталацију Медијавикија.\nАко желите да извршите промене, притисните „{{int:config-back}}”.",
+       "config-install-begin": "Притиском на „{{int:config-continue}}”, започећете инсталацију MediaWiki-ја.\nАко желите да извршите промене, притисните „{{int:config-back}}”.",
        "config-install-step-done": "готово",
        "config-install-step-failed": "није успело",
        "config-install-extensions": "Укључивање додатака",
        "config-screenshot": "снимак екрана",
        "config-extension-not-found": "Није могуће пронаћи датотеку регистрације за додатак „$1”",
        "config-extension-dependency": "Дошло је до грешке зависности при инсталирању додатка „$1”: $2",
-       "mainpagetext": "<strong>Медијавики је инсталиран.</strong>",
+       "mainpagetext": "<strong>MediaWiki је инсталиран.</strong>",
        "mainpagedocfooter": "Погледајте [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Водич за кориснике] за информације о томе како користити wiki софтвер.\n\n== Увод ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Листа поставки конфигурације]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki ЧПП]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Дописна листа о MediaWiki издањима]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Научите како да се борите против непожељног садржаја на свом wiki-ју]"
 }
index 56b469f..e897a81 100644 (file)
@@ -7,26 +7,27 @@
                        "Zoranzoki21"
                ]
        },
-       "config-desc": "Instalacioni program za Medijaviki",
-       "config-title": "Instalacija Medijavikija $1",
+       "config-desc": "Instalacioni program za MediaWiki",
+       "config-title": "Instalacija MediaWiki-ja $1",
        "config-information": "Informacije",
-       "config-localsettings-upgrade": "Otkrivena je datoteka <code>LocalSettings.php</code>.\nKako biste nadogradili ovu instalaciju, unesite vrednost <code>$wgUpgradeKey</code> u okviru ispod.\nNaći ćete je u <code>LocalSettings.php</code>-u.",
-       "config-localsettings-cli-upgrade": "Otkrivena je datoteka <code>LocalSettings.php</code>.\nKako biste nadogradili ovu instalaciju, pokrenite <code>update.php</code>",
+       "config-localsettings-upgrade": "Otkrivena je datoteka <code>LocalSettings.php</code>.\nDa biste nadogradili ovu instalaciju, unesite vrednost <code>$wgUpgradeKey</code> u okviru ispod.\nNaći ćete je u <code>LocalSettings.php</code>-u.",
+       "config-localsettings-cli-upgrade": "Otkrivena je datoteka <code>LocalSettings.php</code>.\nDa biste nadogradili ovu instalaciju, pokrenite <code>update.php</code>",
        "config-localsettings-key": "Ključ za nadogradnju:",
        "config-localsettings-badkey": "Ključ za nadogradnju koji ste naveli je pogrešan.",
-       "config-upgrade-key-missing": "Otkrivena je postojeća instalacija Medijavikija.\nKako biste nadogradili ovu instalaciju, stavite sledeći red koda na dno vaše datoteke <code>LocalSettings.php</code>.\n\n$1",
-       "config-localsettings-incomplete": "Postojeći <code>LocalSettings.php</code> izgleda nekompletno.\nPromenljiva $1 nije postavljena.\nPromenite <code>LocalSettings.php</code> tako što ćete postaviti promenljivu, pa kliknite na „{{int:Config-continue}}”.",
+       "config-upgrade-key-missing": "Otkrivena je postojeća instalacija MediaWiki-ja.\nDa biste nadogradili ovu instalaciju, postavite sledeći red koda na dno datoteke <code>LocalSettings.php</code>.\n\n$1",
+       "config-localsettings-incomplete": "Postojeća datoteka <code>LocalSettings.php</code> izgleda nepotpuno.\nPromenljiva $1 nije postavljena.\nPromenite je tako što ćete postaviti promenljivu, pa kliknuti na „{{int:Config-continue}}”.",
+       "config-localsettings-connection-error": "Došlo je do greške pri povezivanju sa bazom podataka korišćenjem podešavanja navedenih u datoteci <code>LocalSettings.php</code>. Popravite ova podešavanja, pa pokušajte ponovo.\n\n$1",
        "config-session-error": "Greška pri započinjanju sesije: $1",
-       "config-session-expired": "Vaši podaci o sesiji su istekli.\nSesije su podešene da traju $1.\nNjihov rok možete povećati postavljanjem <code>session.gc_maxlifetime</code> u php.ini.\nPonovo pokrenite instalaciju.",
-       "config-no-session": "Vaši podaci o sesiji su izgubljeni!\nProverite Vaš php.ini i obezbedite da je <code>session.save_path</code> postavljen na odgovarajući direktorijum.",
+       "config-session-expired": "Izgleda da su vaši podaci o sesiji istekli.\nSesije su konfigurisane u trajanju od $1.\nMožete da povećate njihovo trajanje postavljanjem parametra <code>session.gc_maxlifetime</code> u datoteci php.ini.\nPonovo pokrenite proces instalacije.",
+       "config-no-session": "Vaši podaci o sesiji su izgubljeni!\nProverite datoteku php.ini i uverite se da je parametar <code>session.save_path</code> postavljen na odgovarajući direktorijum.",
        "config-your-language": "Vaš jezik:",
-       "config-your-language-help": "Izaberite jezik koji želite da koristite tokom instalacije.",
-       "config-wiki-language": "Jezik vikija:",
-       "config-wiki-language-help": "Izaberite jezik na kom će biti sadržaj vikija.",
+       "config-your-language-help": "Izaberite jezik koji želite da koristite tokom procesa instalacije.",
+       "config-wiki-language": "Wiki jezik:",
+       "config-wiki-language-help": "Izaberite jezik na kom će wiki biti pretežno napisan.",
        "config-back": "← Nazad",
        "config-continue": "Nastavi →",
        "config-page-language": "Jezik",
-       "config-page-welcome": "Dobro došli na Medijaviki!",
+       "config-page-welcome": "Dobro došli na MediaWiki!",
        "config-page-dbconnect": "Povezivanje sa bazom podataka",
        "config-page-upgrade": "Nadogradnja postojeće instalacije",
        "config-page-dbsettings": "Podešavanja baze podataka",
        "config-page-releasenotes": "Napomene o izdanju",
        "config-page-copying": "Kopiranje",
        "config-page-upgradedoc": "Nadogradnja",
-       "config-page-existingwiki": "Postojeći viki",
-       "config-help-restart": "Želite li da obrišete sve sačuvane podatke koje ste uneli i ponovo pokrenete instalaciju?",
+       "config-page-existingwiki": "Postojeći wiki",
+       "config-help-restart": "Želite li da obrišete sve sačuvane podatke koje ste uneli i ponovo pokrenete proces instalacije?",
        "config-restart": "Da, pokreni ponovo",
-       "config-welcome": "=== Provera okruženja ===\nSada će se izvršiti osnovna provera kako bi se utvrdilo da li je ovo okruženje pogodno za instalaciju Medijavikija.\nNe zaboravite da uključite ove informacije ako tražite podršku kako završiti instalaciju.",
-       "config-sidebar": "* [https://www.mediawiki.org Početna strana Medijavikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodič za korisnike]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Vodič za administratore]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ČPP]\n----\n* <doclink href=Readme>Pročitaj me</doclink>\n* <doclink href=ReleaseNotes>Napomene o izdanju</doclink>\n* <doclink href=Copying>Kopiranje</doclink>\n* <doclink href=UpgradeDoc>Nadogradnja</doclink>",
-       "config-env-good": "Okruženje je provereno.\nMožete instalirati Medijaviki.",
-       "config-env-bad": "Okruženje je provereno.\nNe možete instalirati Medijaviki.",
+       "config-welcome": "=== Provera okruženja ===\nSada će se izvršiti osnovna provera kako bi se utvrdilo da li je ovo okruženje pogodno za MediaWiki instalaciju.\nNe zaboravite da uključite ove informacije ako tražite podršku kako završiti instalaciju.",
+       "config-sidebar": "* [https://www.mediawiki.org MediaWiki početna]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodič za korisnike]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Contents Vodič za administratore]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ ČPP]\n----\n* <doclink href=Readme>Pročitaj me</doclink>\n* <doclink href=ReleaseNotes>Napomene o izdanju</doclink>\n* <doclink href=Copying>Kopiranje</doclink>\n* <doclink href=UpgradeDoc>Nadogradnja</doclink>",
+       "config-env-good": "Okruženje je provereno.\nMožete da instalirate MediaWiki.",
+       "config-env-bad": "Okruženje je provereno.\nNe možete da instalirate MediaWiki.",
        "config-env-php": "PHP $1 je instaliran.",
        "config-env-hhvm": "HHVM $1 je instaliran.",
+       "config-unicode-using-intl": "Koristi se [https://pecl.php.net/intl dodatak intl PECL] za normalizaciju Unikoda.",
+       "config-outdated-sqlite": "<strong>Upozorenje:</strong> imate SQLite $1, koji je niži od najmanje tražene verzije ($2). SQLite će biti nedostupan.",
+       "config-no-fts3": "<strong>Upozorenje:</strong> SQLite je kompajliran bez [//sqlite.org/fts3.html FTS3 modula], funkcije pretrage biće nedostupne na ovoj bazi podataka.",
+       "config-pcre-old": "<strong>Neotklonjiva greška:</strong> Neophodan je PCRE $1 ili noviji.\nVaš binarni PHP je povezan sa PCRE $2.\n[https://www.mediawiki.org/wiki/Manual:Errors_and_symptoms/PCRE Više informacija].",
+       "config-pcre-no-utf8": "<strong>Neotklonjiva greška:</strong> Izgleda da je PCRE modul PHP-a  kompajliran bez PCRE_UTF8 podrške.\nMediaWiki zahteva UTF-8 podršku za ispravno funkcionisanje.",
+       "config-memory-raised": "Vrednost parametra <code>memory_limit</code> PHP-a iznosi $1, podignuta na $2.",
+       "config-memory-bad": "<strong>Upozorenje:</strong> Vrednost parametra <code>memory_limit</code> PHP-a iznosi $1.\nOvo je verovatno prenisko.\nInstalacija možda neće uspeti!",
        "config-apc": "[https://secure.php.net/apc APC] je instaliran",
+       "config-apcu": "[https://secure.php.net/apcu APCu] je instaliran",
        "config-wincache": "[https://www.iis.net/downloads/microsoft/wincache-extension WinCache] je instaliran",
        "config-no-cache-apcu": "<strong>Upozorenje:</strong> Nije moguće pronaći [https://secure.php.net/apcu APCu] ili [https://www.iis.net/downloads/microsoft/wincache-extension WinCache].\nKeširanje objekata nije omogućeno.",
        "config-diff3-bad": "GNU diff3 nije pronađen.",
        "config-git": "Pronađen je Git softver za kontrolu verzija: <code>$1</code>",
        "config-git-bad": "Nije pronađen Git softver za kontrolu verzija.",
-       "config-imagemagick": "Pronađen ImageMagick: <code>$1</code>.\nUmanjivanje slika će biti omogućeno ako omogućite otpremanje.",
-       "config-gd": "Pronađena je GD ugrađena grafička biblioteka.\nUmanjivanje slika će biti omogućeno ako omogućite otpremanje.",
-       "config-no-scaling": "Nije moguće pronaći GD biblioteku ili ImageMagick.\nUmanjivanje slika će biti onemogućeno.",
-       "config-using-server": "Koristi se ime servera \"<nowiki>$1</nowiki>\".",
-       "config-using-uri": "Koristi se URL servera \"<nowiki>$1$2</nowiki>\".",
-       "config-uploads-not-safe": "<strong>Upozorenje:</strong> Vaš podrazumevan folder za otpremanja <code>$1</code> je podložan izvršenju proizvoljnih skripti.\nIako Medijaviki proverava sve otpremljene datoteke za bezbedonosne pretnje, preporučuje se [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security da zatvorite ovu bezbedonosnu ranjivost] pre omogućavanja otpremanja.",
-       "config-no-cli-uploads-check": "<strong>Upozorenje:</strong> Vaš podrazumevan folder za otpremanje (<code>$1</code>) nije proveren na ranjivost na proizvoljno izvršavanje skripte tokom CLI instalacije.",
+       "config-imagemagick": "Pronađen ImageMagick: <code>$1</code>.\nUmanjivanje slika će se omogućiti ako omogućite otpremanje.",
+       "config-gd": "Pronađena je GD ugrađena grafička biblioteka.\nUmanjivanje slika će se omogućiti ako omogućite otpremanje.",
+       "config-no-scaling": "Nije moguće pronaći GD biblioteku ili ImageMagick.\nUmanjivanje slika će se onemogućiti.",
+       "config-no-uri": "<strong>Greška:</strong> Nije moguće utvrditi trenutni URI.\nInstalacija je obustavljena.",
+       "config-no-cli-uri": "<strong>Upozorenje:</strong> Parametar <code>--scriptpath</code> nije naveden, korišćenje podrazumevanog: <code>$1</code>.",
+       "config-using-server": "Korišćenje imena servera „<nowiki>$1</nowiki>”.",
+       "config-using-uri": "Korišćenje URL adrese servera „<nowiki>$1$2</nowiki>”.",
+       "config-uploads-not-safe": "<strong>Upozorenje:</strong> Vaš podrazumevani direktorijum za otpremanja <code>$1</code> je podložan izvršenju proizvoljnih skripti.\nIako MediaWiki proverava sve otpremljene datoteke za bezbedonosne pretnje, preporučuje se [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Security#Upload_security da zatvorite ovu bezbedonosnu ranjivost] pre omogućavanja otpremanja.",
+       "config-no-cli-uploads-check": "<strong>Upozorenje:</strong> Vaš podrazumevani direktorijum za otpremanje (<code>$1</code>) nije proveren na ranjivost\nna proizvoljno izvršavanje skripte tokom CLI instalacije.",
+       "config-using-32bit": "<strong>Upozorenje:</strong> izgleda da vaš sistem radi sa 32-bitnim celim brojevima. Ovo se [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:32-bit ne preporučuje].",
        "config-db-type": "Tip baze podataka:",
        "config-db-host": "Host baze podataka",
-       "config-db-wiki-settings": "Identifikuj ovaj viki",
-       "config-db-name": "Ime baze podataka:",
+       "config-db-host-oracle": "TNS baze podataka:",
+       "config-db-wiki-settings": "Identifikuj ovaj wiki",
+       "config-db-name": "Ime baze podataka (bez crtica):",
+       "config-db-name-help": "Odaberite ime koje identifikuje vaš wiki.\nOno ne treba da sadrži razmake.\n\nAko koristite deljeni veb-hosting, vaš dobavljač usluge hostinga će vam dati određeno ime baze podataka za korišćenje ili će vas pustiti da pravite baze podataka putem kontrolne table.",
        "config-db-name-oracle": "Šema baze podataka:",
        "config-db-install-account": "Korisnički nalog za instalaciju",
        "config-db-username": "Korisničko ime baze podataka:",
        "config-db-password": "Lozinka baze podataka:",
-       "config-db-prefix": "Prefiks tabele u bazi podataka:",
+       "config-db-install-username": "Unesite korisničko ime koje će se koristiti za povezivanje sa bazom podataka tokom procesa instalacije.\nOvo nije korisničko ime MediaWiki naloga; ovo je korisničko ime za bazu podataka.",
+       "config-db-install-help": "Unesite korisničko ime i lozinku koja će se koristiti za povezivanje sa bazom podataka tokom procesa instalacije.",
+       "config-db-account-lock": "Koristi isto korisničko ime i lozinku tokom normalnog rada",
+       "config-db-wiki-account": "Korisnički nalog za normalan rad",
+       "config-db-prefix": "Prefiks tabele baze podataka (bez crtica):",
+       "config-mysql-old": "Neophodan je MySQL $1 ili noviji. Vi imate $2.",
        "config-db-port": "Port baze podataka:",
-       "config-db-schema": "Šema za Medijaviki:",
+       "config-db-schema": "Šema za MediaWiki (bez crtica)",
+       "config-db-schema-help": "Ova šema obično će raditi dobro.\nPromenite je samo ako znate da je to potrebno.",
+       "config-pg-test-error": "Nije moguće povezati se sa bazom podataka <strong>$1</strong>: $2",
+       "config-sqlite-dir": "Direktorijum SQLite podataka:",
+       "config-oracle-def-ts": "Podrazumevani tabelarni prostor:",
+       "config-oracle-temp-ts": "Privremeni tabelarni prostor:",
        "config-type-mysql": "MariaDB, MySQL ili kompatibilan",
        "config-type-postgres": "PostgreSQL",
        "config-type-sqlite": "SQLite",
        "config-type-oracle": "Oracle",
        "config-type-mssql": "Microsoft SQL Server",
-       "config-support-info": "Medijaviki podržava sledeće sisteme baza podataka:\n\n$1\n\nAko ne vidite sistem podataka koji pokušavate da koristite na spisku ispod, onda pratite gornja uputstva da biste omogućili podršku.",
-       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] je primarna meta za Medijaviki i najbolje je podržana. Medijaviki takođe radi sa [{{int:version-db-mysql-url}} MySQL-om] i [{{int:version-db-percona-url}} Percona Server-om], koji su kompatibilni sa MariaDB-om. ([https://secure.php.net/manual/en/mysqli.installation.php Kako kompajlirati PHP sa podrškom MySQL-a])",
+       "config-support-info": "MediaWiki podržava sledeće sisteme baza podataka:\n\n$1\n\nAko ne vidite sistem koji pokušavate da koristite na listi ispod, onda pratite povezana uputstva iznad kako biste omogućili podršku.",
+       "config-dbsupport-mysql": "* [{{int:version-db-mariadb-url}} MariaDB] je primarna meta za MediaWiki i najbolje je podržana. MediaWiki takođe radi sa [{{int:version-db-mysql-url}} MySQL-om] i [{{int:version-db-percona-url}} Percona Server-om], koji su kompatibilni sa MariaDB-om. ([https://secure.php.net/manual/en/mysqli.installation.php Kako kompajlirati PHP sa podrškom MySQL-a])",
        "config-dbsupport-postgres": "* [{{int:version-db-postgres-url}} PostgreSQL] je popularan sistem baza podataka otvorenog koda kao alternativa MySQL-u. ([https://secure.php.net/manual/en/pgsql.installation.php Kako kompajlirati PHP sa podrškom PostgreSQL-a])",
        "config-dbsupport-sqlite": "* [{{int:version-db-sqlite-url}} SQLite] je lagan sistem baze podataka koji je veoma dobro podržan. ([https://secure.php.net/manual/en/pdo.installation.php Kako kompajlirati PHP sa podrškom SQLite-a], koristi PDO)",
        "config-dbsupport-oracle": "* [{{int:version-db-oracle-url}} Oracle] je baza podataka komercijalnih preduzeća. ([https://secure.php.net/manual/en/oci8.installation.php Kako kompajlirati PHP sa podrškom OCI8-a])",
-       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je baza podataka komercijalnih preduzeća za Vindous. ([https://secure.php.net/manual/en/sqlsrv.installation.php Kako kompajlirati PHP sa podrškom SQLSRV-a])",
+       "config-dbsupport-mssql": "* [{{int:version-db-mssql-url}} Microsoft SQL Server] je baza podataka komercijalnih preduzeća za Windows. ([https://secure.php.net/manual/en/sqlsrv.installation.php Kako kompajlirati PHP sa podrškom SQLSRV-a])",
        "config-header-mysql": "Podešavanja MariaDB/MySQL-a",
        "config-header-postgres": "Podešavanja PostgreSQL-a",
        "config-header-sqlite": "Podešavanja SQLite-a",
        "config-header-oracle": "Podešavanja Oracle-a",
        "config-header-mssql": "Podešavanja Microsoft SQL Server-a",
        "config-invalid-db-type": "Nevažeći tip baze podataka.",
+       "config-missing-db-name": "Morate da unesete vrednost za „{{int:config-db-name}}”.",
+       "config-missing-db-host": "Morate da unesete vrednost za „{{int:config-db-host}}”.",
+       "config-missing-db-server-oracle": "Morate da unesete vrednost za „{{int:config-db-host-oracle}}”.",
+       "config-invalid-db-server-oracle": "Nevažeća TNS baza podataka „$1”.\nKoristite ili „TNS Name” ili nisku „Easy Connect”.\n([http://docs.oracle.com/cd/E11882_01/network.112/e10836/naming.htm Oracle metodi imenovanja]).",
+       "config-invalid-db-name": "Nevažeće ime baze podataka „$1”.\nKoristite samo ASCII slova (a-z, A-Z), brojeve (0-9) i podvlake (_).",
+       "config-invalid-db-prefix": "Nevažeći prefiks baze podataka „$1”.\nKoristite samo ASCII slova (a-z, A-Z), brojeve (0-9), podvlake (_) i crtice (-).",
+       "config-connection-error": "$1.\n\nProverite host, korisničko ime i lozinku, pa pokušajte ponovo.",
+       "config-invalid-schema": "Nevažeća šema za MediaWiki „$1”.\nKoristite samo ASCII slova (a-z, A-Z), brojeve (0-9) i podvlake (_).",
+       "config-db-sys-create-oracle": "Instalacioni program podržava samo korišćenje SYSDBA naloga za otvaranje novog.",
+       "config-db-sys-user-exists-oracle": "Korisnički nalog „$1” već postoji. SYSDBA se samo može koristiti za otvaranje novog naloga!",
+       "config-postgres-old": "Neophodan je PostgreSQL $1 ili noviji. Vi imate $2.",
        "config-mssql-old": "Neophodan je Microsoft SQL Server $1 ili noviji. Vi imate $2.",
-       "config-sqlite-readonly": "Datoteka <code>$1</code> nije zapisiva.",
+       "config-sqlite-name-help": "Odaberite ime koje identifikuje vaš wiki.\nNe koristite razmake ili crtice.\nOvo će se koristiti za ime datoteke SQLite podataka.",
+       "config-sqlite-mkdir-error": "Greška pri pravljenju direktorijuma sa podacima „$1”.\nProverite lokaciju, pa pokušajte ponovo.",
+       "config-sqlite-dir-unwritable": "Nije moguće upisati u direktorijum „$1”.\nPromenite mu dozvole, tako da veb-server može da upisuje u njemu, pa pokušajte ponovo.",
+       "config-sqlite-connection-error": "$1.\n\nProverite direktorijum sa podacima i ime baze podataka ispod, pa pokušajte ponovo.",
+       "config-sqlite-readonly": "Datoteka <code>$1</code> nije upisiva.",
+       "config-sqlite-cant-create-db": "Nije moguće napraviti datoteku baze podataka <code>$1</code>.",
+       "config-sqlite-fts3-downgrade": "PHP-u nedostaje FTS3 podrška, poništavanje nadogradnje tabela.",
+       "config-can-upgrade": "Postoje MediaWiki tabele u ovoj bazi podataka.\nDa biste ih nadogradili na MediaWiki $1, kliknite na <strong>Nastavi</strong>.",
+       "config-upgrade-error": "Došlo je do greške pri nadogradnji MediaWiki tabela u bazi podataka.\n\nZa više informacija, pogledajte evidenciju iznad, da biste pokušali ponovo, kliknite na <strong>Nastavi</strong>.",
+       "config-upgrade-done": "Nadogradnja je završena.\n\nSada možete da [$1 počnete da koristite svoj wiki].\n\nAko želite da ponovo generišete datoteku <code>LocalSettings.php</code>, kliknite na dugme ispod.\nOvo se <strong>ne preporučuje</strong> osim ako imate probleme sa wiki-jem.",
+       "config-upgrade-done-no-regenerate": "Nadogradnja je završena.\n\nSada možete da [$1 počnete da koristite svoj wiki].",
        "config-regenerate": "Regeneriši LocalSettings.php →",
+       "config-show-table-status": "Upit <code>SHOW TABLE STATUS</code> nije uspeo!",
+       "config-unknown-collation": "<strong>Upozorenje:</strong> Baza podataka koristi neprepoznata pravila poređenja.",
        "config-db-web-account": "Nalog baze podataka za veb-pristup",
+       "config-db-web-help": "Izaberite korisnički ime i lozinku koju će veb-server koristiti za povezivanje sa serverom baze podataka, tokom svakodnevnog rada na wiki-ju.",
        "config-db-web-account-same": "Koristi isti nalog kao i za instalaciju",
+       "config-db-web-create": "Otvori nalog ako već ne postoji.",
+       "config-db-web-no-create-privs": "Nalog koji ste naveli za instalaciju nema dovoljne privilegije da otvori nalog.\nNalog koji ovde navedete već mora da postoji.",
+       "config-mysql-engine": "Mehanizam skladišta:",
        "config-mysql-innodb": "InnoDB (preporučeno)",
        "config-mysql-myisam": "MyISAM",
        "config-mssql-auth": "Tip potvrde identiteta:",
-       "config-mssql-sqlauth": "Potvrda identiteta za SQL Server",
-       "config-mssql-windowsauth": "Potvrda identiteta za Windows",
-       "config-site-name": "Ime vikija:",
+       "config-mssql-sqlauth": "SQL Server potvrda identiteta",
+       "config-mssql-windowsauth": "Windows potvrda identiteta",
+       "config-site-name": "Ime wiki-ja:",
+       "config-site-name-help": "Ovo će se pojaviti u naslovnoj traci pregledača i na raznim drugim mestima.",
        "config-site-name-blank": "Unesite ime sajta.",
        "config-project-namespace": "Imenski prostor projekta:",
        "config-ns-generic": "Projekat",
-       "config-ns-site-name": "Isti kao ime vikija: $1",
+       "config-ns-site-name": "Isti kao wiki ime: $1",
        "config-ns-other": "Drugo (navedite)",
        "config-ns-other-default": "MyWiki",
+       "config-ns-invalid": "Navedeni imenski prostor „<nowiki>$1</nowiki>” nije važeći.\nNavedite drugi imenski prostor projekta.",
+       "config-ns-conflict": "Navedeni imenski prostor „<nowiki>$1</nowiki>” sukobi se sa podrazumevanim MediaWiki imenskim prostorom.\nNavedite drugi imenski prostor projekta.",
        "config-admin-box": "Nalog administratora",
-       "config-admin-name": "Korisničko ime:",
+       "config-admin-name": "Vaše korisničko ime:",
        "config-admin-password": "Lozinka:",
        "config-admin-password-confirm": "Ponovite lozinku:",
-       "config-admin-help": "Ovde unesite željeno korisničko ime; na primer, „Jovan Krstić”.\nOvo ime ćete koristiti za prijavu na viki.",
+       "config-admin-help": "Ovde unesite željeno korisničko ime; na primer, „Aleksandar Živković”.\nOvo ime ćete koristiti za prijavu na wiki.",
        "config-admin-name-blank": "Unesite korisničko ime administratora.",
+       "config-admin-name-invalid": "Navedeno korisničko ime „<nowiki>$1</nowiki>” nije važeće.\nNavedite drugo.",
        "config-admin-password-blank": "Unesite lozinku za nalog administratora.",
        "config-admin-password-mismatch": "Lozinke koje ste uneli se ne poklapaju.",
-       "config-admin-email": "Imejl-adresa:",
-       "config-admin-error-bademail": "Uneli ste nevažeću imejl-adresu.",
-       "config-pingback": "Podeli podatke o ovoj instalaciji sa programerima Medijavikija.",
-       "config-almost-done": "Skoro ste završili!\nSada možete preskočiti preostalu konfiguraciju i odmah instalirati viki.",
+       "config-admin-email": "Adresa e-pošte:",
+       "config-admin-error-user": "Došlo je do unutrašnje greške pri pravljenju administratora pod imenom „<nowiki>$1</nowiki>”.",
+       "config-admin-error-password": "Došlo je do unutrašnje greške pri postavljanju lozinke za administratora „<nowiki>$1</nowiki>”: <pre>$2</pre>",
+       "config-admin-error-bademail": "Uneli ste nevažeću adresu e-pošte.",
+       "config-subscribe": "Pretplatite se na [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce release announcements dopisnu listu].",
+       "config-subscribe-noemail": "Pokušali ste da se pretplatite na dopisnu listu za objave o novim izdanjima bez pružanja adrese e-pošte.\nPružite adresu e-pošte ako želite da se pretplatite na nju.",
+       "config-pingback": "Deli podatke o ovoj instalaciji sa MediaWiki programerima.",
+       "config-almost-done": "Skoro ste gotovi!\nSada možete preskočiti preostalu konfiguraciju i odmah instalirati wiki.",
        "config-optional-continue": "Postavi mi još pitanja.",
-       "config-optional-skip": "Dosadno mi je, samo instaliraj viki.",
+       "config-optional-skip": "Već mi je dosadno, samo instaliraj wiki.",
        "config-profile": "Profil korisničkih grupa:",
-       "config-profile-wiki": "Otvoren viki",
+       "config-profile-wiki": "Otvoren wiki",
        "config-profile-no-anon": "Neophodno je otvoriti nalog",
        "config-profile-fishbowl": "Samo ovlašćeni urednici",
-       "config-profile-private": "Privatan viki",
-       "config-profile-help": "Viki najbolje funkcioniše kada dozvoljavate što više korisnika da uređuju kako je to moguće.\nU Medijavikiju, lako je pregledati nedavne promene i vratiti svaku štetu koju počine naivni ili zlonamerni korisnici.\n\nMeđutim, mnogi su pronašli Medijaviki da je koristan u širokoj raznolikosti uloga, a ponekad nije lako uveriti se u sve prednosti načina vikija.\nTako da imate izbor.\n\nModel <strong>{{int:config-profile-wiki}}</strong> dozvoljava svima da uređuju, bez prijavljivanja.\nVikiji sa <strong>{{int:config-profile-no-anon}}</strong> pružaju dodatnu odgovornost, ali može sprečiti slučajne doprinose.\n\n<strong>{{int:config-profile-fishbowl}}</strong> scenario dozvoljava odobrenim korisnicima da uređuju, ali svi mogu videti stranice, uključujući istoriju.\n<strong>{{int:config-profile-private}}</strong> samo dozvoljava odobrenim korisnicima da vide stranice, sa istom grupom dozvoljenom da uređuje.\n\nSložene konfiguracije korisničkih prava su dostupne nakon instalacije, pogledajte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights odgovarajući ručni unos].",
+       "config-profile-private": "Privatan wiki",
+       "config-profile-help": "Wiki-ji najbolje funkcionišu kada dozvoljavate što više korisnika da uređuju kako je to moguće.\nU MediaWiki-ju, lako je pregledati nedavne promene i vratiti svaku štetu koju počine naivni ili zlonamerni korisnici.\n\nMeđutim, mnogi su pronašli MediaWiki da je koristan u širokoj raznolikosti uloga, a ponekad nije lako uveriti se u sve prednosti načina wiki-ja.\nTako da imate izbor.\n\nModel <strong>{{int:config-profile-wiki}}</strong> dozvoljava svima da uređuju, bez prijavljivanja.\nWiki-ji sa <strong>{{int:config-profile-no-anon}}</strong> pružaju dodatnu odgovornost, ali može sprečiti slučajne doprinose.\n\n<strong>{{int:config-profile-fishbowl}}</strong> scenario dozvoljava odobrenim korisnicima da uređuju, ali svi mogu videti stranice, uključujući istoriju.\n<strong>{{int:config-profile-private}}</strong> samo dozvoljava odobrenim korisnicima da vide stranice, sa istom grupom dozvoljenom da uređuje.\n\nSložene konfiguracije korisničkih prava su dostupne nakon instalacije, pogledajte [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:User_rights odgovarajući ručni unos].",
        "config-license": "Autorska prava i licenca:",
-       "config-license-none": "Bez zaglavlja sa licencom",
-       "config-license-cc-by-sa": "Creative Commons Autorstvo-Deliti pod istim uslovima (CC BY-SA)",
-       "config-license-cc-by": "Creative Commons Autorstvo (CC BY)",
-       "config-license-cc-by-nc-sa": "Creative Commons Autorstvo-Nekomercijalno-Deliti pod istim uslovima (CC BY-NC-SA)",
+       "config-license-none": "Bez podnožja za licencu",
+       "config-license-cc-by-sa": "Creative Commons Autorstvo-Deliti pod istim uslovima",
+       "config-license-cc-by": "Creative Commons Autorstvo",
+       "config-license-cc-by-nc-sa": "Creative Commons Autorstvo-Nekomercijalno-Deliti pod istim uslovima",
        "config-license-cc-0": "Creative Commons Zero (javno vlasništvo)",
-       "config-license-gfdl": "GNU-ova licenca za slobodnu dokumentaciju izdanje 1.3 ili novije",
+       "config-license-gfdl": "GNU licenca za slobodnu dokumentaciju 1.3 ili novija",
        "config-license-pd": "Javno vlasništvo",
        "config-license-cc-choose": "Izaberi prilagođenu Creative Commons licencu",
-       "config-email-settings": "Podešavanja imejla",
-       "config-enable-email": "Omogući odlazni imejl",
-       "config-email-user": "Omogući korisnicima da međusobno razmenjuju imejlove",
+       "config-email-settings": "Podešavanja e-pošte",
+       "config-enable-email": "Omogući odlaznu e-poštu",
+       "config-email-user": "Omogući slanje e-poruka među korisnicima",
+       "config-email-user-help": "Dozvoli svim korisnicima da međusobno šalju e-poruke ako imaju omogućeno odgovarajuće podešavanje.",
        "config-email-usertalk": "Omogući obaveštenje o korisničkoj stranici za razgovor",
+       "config-email-usertalk-help": "Dozvoli korisnicima da primaju obaveštenja o promenama korisničkih stranica za razgovor, ako su to omogućili u svojim podešavanjima.",
        "config-email-watchlist": "Omogući obaveštenja o spisku nadgledanja",
-       "config-email-auth": "Omogući potvrdu identiteta putem imejla",
+       "config-email-watchlist-help": "Dozvoli korisnicima da primaju obaveštenja o svojim nadgledanim stranicama, ako su to omogućili u svojim podešavanjima.",
+       "config-email-auth": "Omogući potvrdu identiteta putem e-pošte",
+       "config-email-sender": "Povratna adresa e-pošte:",
        "config-upload-settings": "Otpremanja slika i datoteka",
        "config-upload-enable": "Omogući otpremanje datoteka",
        "config-upload-deleted": "Direktorijum za izbrisane datoteke:",
-       "config-logo": "URL logotipa:",
+       "config-upload-deleted-help": "Odaberite direktorijum u kojem će se arhivirati izbrisane datoteke.\nU idealnom slučaju, ovo ne bi trebalo da bude dostupno preko veba.",
+       "config-logo": "URL adresa logotipa:",
        "config-instantcommons": "Omogući Instant Commons",
+       "config-cc-error": "Creative Commons birač licence nije davao rezultate.\nUnesite ime licence ručno.",
        "config-cc-again": "Izaberite ponovo…",
        "config-cc-not-chosen": "Odaberite koju Creative Commons licencu želite i kliknite na „nastavi”.",
        "config-advanced-settings": "Napredna konfiguracija",
        "config-cache-options": "Podešavanja za keširanje objekta:",
-       "config-cache-none": "Nema keširanja (funkcionalnost nije uklonjena, ali brzina može uticati na veće viki sajtove)",
+       "config-cache-none": "Nema keširanja (funkcionalnost nije uklonjena, ali brzina može uticati na veće wiki sajtove)",
+       "config-cache-accel": "Keširanje PHP objekta (APC, APCu or WinCache)",
        "config-cache-memcached": "Koristi Memcached (zahteva dodatno podešavanje i konfiguraciju)",
        "config-memcached-servers": "Memcached serveri:",
+       "config-memcached-help": "Lista IP adresa za korišćenje za Memcached.\nTreba da navedete jednu u svaki red i port za korišćenje. Na primer:\n 127.0.0.1:11211\n 192.168.1.25:1234",
+       "config-memcache-needservers": "Izabrali ste Memcached tip keša, ali niste naveli nijedan server.",
+       "config-memcache-badip": "Uneli ste nevažeću IP adresu za Memcached: $1.",
+       "config-memcache-noport": "Niste naveli port za korišćenje za Memcached server: $1.\nAko ne znate port, podrazumevani je 11211.",
+       "config-memcache-badport": "Brojevi Memcached porta treba da budu između $1 i $2.",
        "config-extensions": "Dodaci",
+       "config-extensions-help": "Gorenavedeni dodaci su otkriveni u direktorijumu <code>./extensions</code>.\n\nOni mogu da traže dodatnu konfiguraciju, ali možete da ih omogućite odmah.",
        "config-skins": "Teme",
-       "config-skins-use-as-default": "Koristi ovu temu kao podrazumevanu",
+       "config-skins-help": "Gorenavedene teme su otkrivene u direktorijumu <code>./skins</code>. Morate da omogućite najmanje jednu i odaberete podrazumevanu.",
+       "config-skins-use-as-default": "Podrazumevano koristi ovu temu",
+       "config-skins-missing": "Teme nisu pronađene. MediaWiki će koristiti rezervnu temu sve dok ne instalirate odgovarajuće.",
        "config-skins-must-enable-some": "Morate odabrati barem jednu temu za omogućavanje.",
-       "config-install-begin": "Pritiskom na „{{int:config-continue}}”, započećete instalaciju Medijavikija.\nAko želite da izvršite promene, pritisnite „{{int:config-back}}”.",
+       "config-skins-must-enable-default": "Tema koju ste odabrali za podrazumevanu mora da se omogući.",
+       "config-install-alreadydone": "<strong>Upozorenje:</strong> Izgleda da već imate instaliran MediaWiki i pokušavate da ga ponovo instalirate.\nProdužite ka sledećoj stranici.",
+       "config-install-begin": "Pritiskom na „{{int:config-continue}}”, započećete instalaciju MediaWiki-ja.\nAko želite da izvršite promene, pritisnite „{{int:config-back}}”.",
        "config-install-step-done": "gotovo",
        "config-install-step-failed": "nije uspelo",
        "config-install-extensions": "Uključivanje dodataka",
-       "config-install-database": "Podešavam bazu podataka",
+       "config-install-database": "Postavljanje baze podataka",
        "config-install-schema": "Pravljenje šeme",
        "config-install-pg-schema-not-exist": "Šema PostgreSQL ne postoji.",
-       "config-install-user": "Pravim korisnika baze podataka",
+       "config-install-pg-schema-failed": "Pravljenje tabela nije uspelo.\nUverite se da korisnik „$1” može da piše u šemi „$2”.",
+       "config-install-pg-commit": "Izvršavanje promena",
+       "config-install-pg-plpgsql": "Proveravanje jezika PL/pgSQL",
+       "config-pg-no-plpgsql": "Morate da instalirate jezik PL/pgSQL u bazi podataka $1",
+       "config-pg-no-create-privs": "Nalog koji ste naveli za instalaciju nema dovoljne privilegije da otvori nalog.",
+       "config-install-user": "Pravljenje korisnika baze podataka",
        "config-install-user-alreadyexists": "Korisnik „$1” već postoji",
+       "config-install-user-create-failed": "Otvaranje naloga „$1” nije uspelo: $2",
+       "config-install-user-grant-failed": "Dodeljivanje dozvole korisniku „$1” nije uspelo: $2",
+       "config-install-user-missing": "Navedeni korisnik „$1” ne postoji.",
+       "config-install-user-missing-create": "Navedeni korisnik „$1” ne postoji.\nKliknite na polje za potvrdu „otvori nalog” ispod ako želite da ga otvorite.",
        "config-install-tables": "Pravljenje tabela",
+       "config-install-tables-exist": "<strong>Upozorenje:</strong> Izgleda da MediaWiki tabele već postoje.\nPreskakanje pravljenja.",
+       "config-install-tables-failed": "<strong>Greška:</strong> Pravljenje tabele nije uspelo zbog sledeće greške: $1",
        "config-install-interwiki": "Popunjavanje podrazumevane tabele međuvikija",
-       "config-install-stats": "Pokretanje statistika",
+       "config-install-interwiki-list": "Nije moguće čitati datoteku <code>interwiki.list</code>.",
+       "config-install-interwiki-exists": "<strong>Upozorenje:</strong> Izgleda da tabela međuvikija već ima unose.\nPreskakanje podrazumevane liste.",
+       "config-install-stats": "Pokretanje statistike",
        "config-install-keys": "Generisanje tajnih ključeva",
-       "config-install-sysop": "Pravljenje korisničkog naloga administratora",
+       "config-install-updates": "Spreči pokretanje nepotrebnih ažuriranja",
+       "config-install-updates-failed": "<strong>Greška:</strong> Umetanje klučeva za ažuriranje u tabele nije uspelo zbog sledeće greške: $1",
+       "config-install-sysop": "Otvaranje korisničkog naloga administratora",
        "config-install-subscribe-fail": "Nije moguće pretplatiti se na mediawiki-announce: $1",
+       "config-install-subscribe-notpossible": "cURL nije instaliran, a parametar <code>allow_url_fopen</code> nije dostupan.",
        "config-install-mainpage": "Pravljenje glavne strane sa podrazumevanim sadržajem",
        "config-install-mainpage-exists": "Glavna strana već postoji, preskakanje",
+       "config-install-extension-tables": "Pravljenje tabela za omogućene dodatke",
        "config-install-mainpage-failed": "Nije moguće umetnuti glavnu stranu: $1",
-       "config-install-done": "<strong>Čestitamo!</strong>\nInstalirali ste Medijaviki.\n\nInstalacioni program je generisao datoteku <code>LocalSettings.php</code>.\nOna sadrži svu vašu konfiguraciju.\n\nMoraćete da je preuzmete i stavite u bazu vaše viki instalacije (isti direktorijum kao index.php). Preuzimanje bi automatski trebalo početi.\n\nAko preuzimanje nije ponuđeno, ili ako ga otkažete, možete ponovo pokrenuti preuzimanje tako što ćete kliknuti na dolenavedenu vezu:\n\n$3\n\n<strong>Napomena:</strong> Ako to odmah ne uradite, ova generisana konfiguraciona datoteka neće vam biti dostupna kasnije ako izađete iz instalacije bez preuzimanja.\n\nKada je to učinjeno, možete da <strong>[$2 posetite svoj viki]</strong>.",
-       "config-install-done-path": "<strong>Čestitamo!</strong>\nInstalirali ste Medijaviki.\n\nInstalacioni program je generisao datoteku <code>LocalSettings.php</code>.\nOna sadrži svu vašu konfiguraciju.\n\nMoraćete da je preuzmete i stavite u <code>$4</code>. Preuzimanje bi automatski trebalo početi.\n\nAko preuzimanje nije ponuđeno, ili ako ga otkažete, možete ponovo pokrenuti preuzimanje tako što ćete kliknuti na dolenavedenu vezu:\n\n$3\n\n<strong>Napomena:</strong> Ako to odmah ne uradite, ova generisana konfiguraciona datoteka neće vam biti dostupna kasnije ako izađete iz instalacije bez preuzimanja.\n\nKada je to učinjeno, možete da <strong>[$2 posetite svoj viki]</strong>.",
-       "config-install-success": "Medijaviki je uspešno instaliran. Sada možete posetiti <$1$2> da biste videli svoj viki.\nAko imate pitanja, pogledajte naš spisak često postavljanih pitanja: <https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> ili koristite jedan od foruma za podršku koji su povezani na toj stranici.",
-       "config-download-localsettings": "Preuzmi <code>LocalSettings.php</code>",
+       "config-install-done": "<strong>Čestitamo!</strong>\nInstalirali ste MediaWiki.\n\nInstalacioni program je generisao datoteku <code>LocalSettings.php</code>.\nOna sadrži svu vašu konfiguraciju.\n\nMoraćete da je preuzmete i stavite u bazu vaše wiki instalacije (isti direktorijum kao index.php). Preuzimanje bi automatski trebalo početi.\n\nAko preuzimanje nije ponuđeno, ili ako ga otkažete, možete ponovo pokrenuti preuzimanje tako što ćete kliknuti na dolenavedenu vezu:\n\n$3\n\n<strong>Napomena:</strong> Ako to odmah ne uradite, ova generisana konfiguraciona datoteka neće vam biti dostupna kasnije ako izađete iz instalacije bez preuzimanja.\n\nKada je to učinjeno, možete da <strong>[$2 posetite svoj wiki]</strong>.",
+       "config-install-done-path": "<strong>Čestitamo!</strong>\nInstalirali ste MediaWiki.\n\nInstalacioni program je generisao datoteku <code>LocalSettings.php</code>.\nOna sadrži svu vašu konfiguraciju.\n\nMoraćete da je preuzmete i stavite u <code>$4</code>. Preuzimanje bi automatski trebalo početi.\n\nAko preuzimanje nije ponuđeno, ili ako ga otkažete, možete ponovo pokrenuti preuzimanje tako što ćete kliknuti na dolenavedenu vezu:\n\n$3\n\n<strong>Napomena:</strong> Ako to odmah ne uradite, ova generisana konfiguraciona datoteka neće vam biti dostupna kasnije ako izađete iz instalacije bez preuzimanja.\n\nKada je to učinjeno, možete da <strong>[$2 posetite svoj wiki]</strong>.",
+       "config-install-success": "MediaWiki je uspešno instaliran. Sada možete posetiti <$1$2> da biste videli svoj wiki.\nAko imate pitanja, pogledajte našu listu često postavljanih pitanja: <https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ> ili koristite jedan od foruma za podršku koji su povezani na toj stranici.",
+       "config-download-localsettings": "Preuzmi datoteku <code>LocalSettings.php</code>",
        "config-help": "pomoć",
        "config-help-tooltip": "kliknite da biste proširili",
-       "config-nofile": "Nije moguće pronaći datoteku „$1”. Da nije izbrisana?",
-       "config-extension-link": "Jeste li znali da vaš viki podržava [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions dodatke]?\n\nMožete ih pregledati [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category po kategoriji].",
+       "config-nofile": "Nije moguće pronaći datoteku „$1”. Nije li izbrisana?",
+       "config-extension-link": "Jeste li znali da vaš wiki podržava [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions dodatke]?\n\nMožete ih pregledati [https://www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category po kategoriji].",
        "config-skins-screenshots": "„$1” (snimci ekrana: $2)",
        "config-skins-screenshot": "$1 ($2)",
        "config-extensions-requires": "$1 (zahteva $2)",
        "config-screenshot": "snimak ekrana",
        "config-extension-not-found": "Nije moguće pronaći datoteku registracije za dodatak „$1”",
-       "mainpagetext": "<strong>Medijaviki je instaliran.</strong>",
-       "mainpagedocfooter": "Pogledajte [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents korisnički vodič] za korišćenje programa.\n\n== Uvod ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Pomoć u vezi sa podešavanjima]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ Često postavljana pitanja]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Dopisni spisak o izdanjima Medijavikija]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Naučite kako da se borite protiv spama na svom vikiju]"
+       "config-extension-dependency": "Došlo je do greške zavisnosti pri instaliranju dodatka „$1”: $2",
+       "mainpagetext": "<strong>MediaWiki je instaliran.</strong>",
+       "mainpagedocfooter": "Pogledajte [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents Vodič za korisnike] za informacije o tome kako koristiti wiki softver.\n\n== Uvod ==\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Lista postavki konfiguracije]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ MediaWiki ČPP]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Dopisna lista o MediaWiki izdanjima]\n* [https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam Naučite kako da se borite protiv nepoželjnog sadržaja na svom wiki-ju]"
 }
index 24f4757..e9b903c 100644 (file)
        "config-sqlite-cant-create-db": "Kunde inte skapa databasfilen <code>$1</code>.",
        "config-sqlite-fts3-downgrade": "PHP saknar stöd för FTS3, nedgraderar tabeller",
        "config-can-upgrade": "Det finns MediaWiki-tabeller i den här databasen.\nFör att uppgradera dem till MediaWiki $1, klicka på '''Fortsätt'''.",
+       "config-upgrade-error": "Ett fel uppstod när MediaWiki-tabellerna i din databas uppdaterades.\n\nFör mer information, se loggen ovan. Klicka på <strong>Fortsätt</strong> för att försöka igen.",
        "config-upgrade-done": "Uppgraderingen slutfördes.\n\nDu kan nu [$1 börja använda din wiki].\n\nOm du vill förnya din <code>LocalSettings.php</code>-fil, klicka på knappen nedan.\nDetta '''rekommenderas inte''' om du har problem med din wiki.",
        "config-upgrade-done-no-regenerate": "Uppgraderingen slutfördes.\n\nDu kan nu [$1 börja använda din wiki].",
        "config-regenerate": "Återskapa LocalSettings.php →",
index c572559..9931d83 100644 (file)
@@ -298,7 +298,7 @@ class JobQueueDB extends JobQueue {
                                // Get the job object from the row...
                                $title = Title::makeTitle( $row->job_namespace, $row->job_title );
                                $job = Job::factory( $row->job_cmd, $title,
-                                       self::extractBlob( $row->job_params ), $row->job_id );
+                                       self::extractBlob( $row->job_params ) );
                                $job->metadata['id'] = $row->job_id;
                                $job->metadata['timestamp'] = $row->job_timestamp;
                                break; // done
index c39823f..1c7647c 100644 (file)
@@ -41,11 +41,38 @@ class CategoryMembershipChangeJob extends Job {
 
        const ENQUEUE_FUDGE_SEC = 60;
 
-       public function __construct( Title $title, array $params ) {
+       /**
+        * @var ParserCache
+        */
+       private $parserCache;
+
+       /**
+        * @param Title $title The title of the page for which to update category emmbership.
+        * @param string $revisionTimestamp The timestamp of the new revision that triggered the job.
+        * @return JobSpecification
+        */
+       public static function newSpec( Title $title, $revisionTimestamp ) {
+               return new JobSpecification(
+                       'categoryMembershipChange',
+                       [
+                               'pageId' => $title->getArticleID(),
+                               'revTimestamp' => $revisionTimestamp,
+                       ],
+                       [],
+                       $title
+               );
+       }
+
+       /**
+        * Constructor for use by the Job Queue infrastructure.
+        * @note Don't call this when queueing a new instance, use newSpec() instead.
+        */
+       public function __construct( ParserCache $parserCache, Title $title, array $params ) {
                parent::__construct( 'categoryMembershipChange', $title, $params );
                // Only need one job per page. Note that ENQUEUE_FUDGE_SEC handles races where an
                // older revision job gets inserted while the newer revision job is de-duplicated.
                $this->removeDuplicates = true;
+               $this->parserCache = $parserCache;
        }
 
        public function run() {
@@ -236,10 +263,12 @@ class CategoryMembershipChangeJob extends Job {
                $options = $page->makeParserOptions( 'canonical' );
                $options->setTimestamp( $parseTimestamp );
 
-               // This could possibly use the parser cache if it checked the revision ID,
-               // but that's more complicated than it's worth.
-               $output = $renderer->getRenderedRevision( $rev->getRevisionRecord(), $options )
-                       ->getRevisionParserOutput();
+               $output = $rev->isCurrent() ? $this->parserCache->get( $page, $options ) : null;
+
+               if ( !$output || $output->getCacheRevisionId() !== $rev->getId() ) {
+                       $output = $renderer->getRenderedRevision( $rev->getRevisionRecord(), $options )
+                               ->getRevisionParserOutput();
+               }
 
                // array keys will cast numeric category names to ints
                // so we need to cast them back to strings to avoid breaking things!
index 9cfaf67..a270105 100644 (file)
@@ -418,7 +418,7 @@ class XmlTypeCheck {
         * We whitelist an extremely restricted subset of DTD features.
         *
         * Safe is defined as:
-        *  * Only contains entity defintions (e.g. No <!ATLIST )
+        *  * Only contains entity definitions (e.g. No <!ATLIST )
         *  * Entity definitions are not "system" entities
         *  * Entity definitions are not "parameter" (i.e. %) entities
         *  * Entity definitions do not reference other entites except &amp;
index c6bcc7a..a7ef3d5 100644 (file)
@@ -64,7 +64,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
        protected $keyspace = 'local';
        /** @var LoggerInterface */
        protected $logger;
-       /** @var callback|null */
+       /** @var callable|null */
        protected $asyncHandler;
        /** @var int Seconds */
        protected $syncTimeout;
@@ -462,7 +462,7 @@ abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
                $fname = __METHOD__;
                $expiry = min( $expiry ?: INF, self::TTL_DAY );
                $loop = new WaitConditionLoop(
-                       function () use ( $key, $timeout, $expiry, $fname ) {
+                       function () use ( $key, $expiry, $fname ) {
                                $this->clearLastError();
                                if ( $this->add( "{$key}:lock", 1, $expiry ) ) {
                                        return true; // locked!
index a473210..abf9e8b 100644 (file)
@@ -230,7 +230,7 @@ class RedisBagOStuff extends BagOStuff {
                                        }
                                }
                        } catch ( RedisException $e ) {
-                               $this->handleException( $server, $conn, $e );
+                               $this->handleException( $conn, $e );
                                $result = false;
                        }
                }
index e7586cf..ed5c7f5 100644 (file)
@@ -1166,7 +1166,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
         *
         * @param string $key
         * @param int $ttl
-        * @param callback $callback
+        * @param callable $callback
         * @param array $opts Options map for getWithSetCallback()
         * @param float|null &$asOf Cache generation timestamp of returned value [returned]
         * @return mixed
index 2c40c72..7865db4 100644 (file)
@@ -97,9 +97,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        protected $connLogger;
        /** @var LoggerInterface */
        protected $queryLogger;
-       /** @var callback Error logging callback */
+       /** @var callable Error logging callback */
        protected $errorLogger;
-       /** @var callback Deprecation logging callback */
+       /** @var callable Deprecation logging callback */
        protected $deprecationLogger;
 
        /** @var resource|null Database connection */
@@ -3742,7 +3742,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                                }
                        }
                        if ( $pos < 0 ) {
-                               throw new DBUnexpectedError( "Atomic section not found (for $fname)" );
+                               throw new DBUnexpectedError( $this, "Atomic section not found (for $fname)" );
                        }
                        // Remove all descendant sections and re-index the array
                        $excisedIds = [];
index 532d818..2795883 100644 (file)
@@ -1112,11 +1112,13 @@ interface IDatabase {
        /**
         * Change the current database
         *
+        * This should not be called outside LoadBalancer for connections managed by a LoadBalancer
+        *
         * @param string $db
         * @return bool True unless an exception was thrown
         * @throws DBConnectionError If databasesAreIndependent() is true and an error occurs
         * @throws DBError
-        * @deprecated Since 1.32
+        * @deprecated Since 1.32 Use selectDomain() instead
         */
        public function selectDB( $db );
 
@@ -1125,6 +1127,8 @@ interface IDatabase {
         *
         * This will throw an error for some database types if the database unspecified
         *
+        * This should not be called outside LoadBalancer for connections managed by a LoadBalancer
+        *
         * @param string|DatabaseDomain $domain
         * @since 1.32
         * @throws DBConnectionError
index 57f60ca..7987052 100644 (file)
@@ -83,6 +83,14 @@ interface ILBFactory {
         */
        public function resolveDomainID( $domain );
 
+       /**
+        * Close all connection and redefine the local domain for testing or schema creation
+        *
+        * @param DatabaseDomain|string $domain
+        * @since 1.33
+        */
+       public function redefineLocalDomain( $domain );
+
        /**
         * Create a new load balancer object. The resulting object will be untracked,
         * not chronology-protected, and the caller is responsible for cleaning it up.
@@ -322,8 +330,9 @@ interface ILBFactory {
         * Set a new table prefix for the existing local domain ID for testing
         *
         * @param string $prefix
+        * @since 1.33
         */
-       public function setDomainPrefix( $prefix );
+       public function setLocalDomainPrefix( $prefix );
 
        /**
         * Close all open database connections on all open load balancers.
index d213dc9..9a6c224 100644 (file)
@@ -618,7 +618,15 @@ abstract class LBFactory implements ILBFactory {
                $this->indexAliases = $aliases;
        }
 
+       /**
+        * @param string $prefix
+        * @deprecated Since 1.33
+        */
        public function setDomainPrefix( $prefix ) {
+               $this->setLocalDomainPrefix( $prefix );
+       }
+
+       public function setLocalDomainPrefix( $prefix ) {
                $this->localDomain = new DatabaseDomain(
                        $this->localDomain->getDatabase(),
                        null,
@@ -626,7 +634,17 @@ abstract class LBFactory implements ILBFactory {
                );
 
                $this->forEachLB( function ( ILoadBalancer $lb ) use ( $prefix ) {
-                       $lb->setDomainPrefix( $prefix );
+                       $lb->setLocalDomainPrefix( $prefix );
+               } );
+       }
+
+       public function redefineLocalDomain( $domain ) {
+               $this->closeAll();
+
+               $this->localDomain = DatabaseDomain::newFromId( $domain );
+
+               $this->forEachLB( function ( ILoadBalancer $lb ) {
+                       $lb->redefineLocalDomain( $this->localDomain );
                } );
        }
 
index 78815f2..e1a3162 100644 (file)
@@ -136,6 +136,14 @@ interface ILoadBalancer {
         */
        public function resolveDomainID( $domain );
 
+       /**
+        * Close all connection and redefine the local domain for testing or schema creation
+        *
+        * @param DatabaseDomain|string $domain
+        * @since 1.33
+        */
+       public function redefineLocalDomain( $domain );
+
        /**
         * Get the index of the reader connection, which may be a replica DB
         *
@@ -644,8 +652,9 @@ interface ILoadBalancer {
         * Set a new table prefix for the existing local domain ID for testing
         *
         * @param string $prefix
+        * @since 1.33
         */
-       public function setDomainPrefix( $prefix );
+       public function setLocalDomainPrefix( $prefix );
 
        /**
         * Make certain table names use their own database, schema, and table prefix
index 537301c..bc51726 100644 (file)
@@ -1918,7 +1918,15 @@ class LoadBalancer implements ILoadBalancer {
                $this->indexAliases = $aliases;
        }
 
+       /**
+        * @param string $prefix
+        * @deprecated Since 1.33
+        */
        public function setDomainPrefix( $prefix ) {
+               $this->setLocalDomainPrefix( $prefix );
+       }
+
+       public function setLocalDomainPrefix( $prefix ) {
                // Find connections to explicit foreign domains still marked as in-use...
                $domainsInUse = [];
                $this->forEachOpenConnection( function ( IDatabase $conn ) use ( &$domainsInUse ) {
@@ -1950,6 +1958,12 @@ class LoadBalancer implements ILoadBalancer {
                } );
        }
 
+       public function redefineLocalDomain( $domain ) {
+               $this->closeAll();
+
+               $this->setLocalDomain( DatabaseDomain::newFromId( $domain ) );
+       }
+
        /**
         * @param DatabaseDomain $domain
         */
index fa5ebfc..739dbec 100644 (file)
@@ -444,11 +444,12 @@ class EmailNotification {
        /**
         * Does the per-user customizations to a notification e-mail (name,
         * timestamp in proper timezone, etc) and sends it out.
-        * Returns true if the mail was sent successfully.
+        * Returns Status if email was sent successfully or not (Status::newGood()
+        * or Status::newFatal() respectively).
         *
         * @param User $watchingUser
         * @param string $source
-        * @return bool
+        * @return Status
         * @private
         */
        function sendPersonalised( $watchingUser, $source ) {
index 9977f45..c32a720 100644 (file)
@@ -290,7 +290,7 @@ class Exif {
                        $this->byteOrder = 'BE'; // BE seems about twice as popular as LE in jpg's.
                }
 
-               $this->debugFile( $this->basename, __FUNCTION__, true );
+               $this->debugFile( __FUNCTION__, true );
                if ( function_exists( 'exif_read_data' ) ) {
                        Wikimedia\suppressWarnings();
                        $data = exif_read_data( $this->file, 0, true );
index 010cf80..e3e7343 100644 (file)
@@ -217,7 +217,7 @@ abstract class MediaTransformOutput {
         * @return bool Success
         */
        public function streamFile( $headers = [] ) {
-               $this->streamFileWithStatus( $headers )->isOK();
+               return $this->streamFileWithStatus( $headers )->isOK();
        }
 
        /**
index 9f7f280..4b0d319 100644 (file)
@@ -295,7 +295,7 @@ class Article implements Page {
                        $content = ContentHandler::makeContent( $text, $this->getTitle() );
                } else {
                        $message = $this->getContext()->getUser()->isLoggedIn() ? 'noarticletext' : 'noarticletextanon';
-                       $content = new MessageContent( $message, null, 'parsemag' );
+                       $content = new MessageContent( $message, null );
                }
 
                return $content;
index 9f623ba..c7c7069 100644 (file)
@@ -26,6 +26,7 @@ use MediaWiki\MediaWikiServices;
 use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\Revision\RevisionRenderer;
 use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Revision\SlotRecord;
 use MediaWiki\Storage\DerivedPageDataUpdater;
 use MediaWiki\Storage\PageUpdater;
@@ -232,6 +233,13 @@ class WikiPage implements Page, IDBAccessObject {
                return MediaWikiServices::getInstance()->getRevisionRenderer();
        }
 
+       /**
+        * @return SlotRoleRegistry
+        */
+       private function getSlotRoleRegistry() {
+               return MediaWikiServices::getInstance()->getSlotRoleRegistry();
+       }
+
        /**
         * @return ParserCache
         */
@@ -952,12 +960,17 @@ class WikiPage implements Page, IDBAccessObject {
                                // links.
                                $hasLinks = (bool)count( $editInfo->output->getLinks() );
                        } else {
-                               // NOTE: keep in sync with revisionRenderer::getLinkCount
+                               // NOTE: keep in sync with RevisionRenderer::getLinkCount
+                               // NOTE: keep in sync with DerivedPageDataUpdater::isCountable
                                $hasLinks = (bool)wfGetDB( DB_REPLICA )->selectField( 'pagelinks', 1,
                                        [ 'pl_from' => $this->getId() ], __METHOD__ );
                        }
                }
 
+               // TODO: MCR: determine $hasLinks for each slot, and use that info
+               // with that slot's Content's isCountable method. That requires per-
+               // slot ParserOutput in the ParserCache, or per-slot info in the
+               // pagelinks table.
                return $content->isCountable( $hasLinks );
        }
 
@@ -1665,6 +1678,7 @@ class WikiPage implements Page, IDBAccessObject {
                        $this, // NOTE: eventually, PageUpdater should not know about WikiPage
                        $this->getRevisionStore(),
                        $this->getRevisionRenderer(),
+                       $this->getSlotRoleRegistry(),
                        $this->getParserCache(),
                        JobQueueGroup::singleton(),
                        MessageCache::singleton(),
@@ -1769,7 +1783,8 @@ class WikiPage implements Page, IDBAccessObject {
                        $this, // NOTE: eventually, PageUpdater should not know about WikiPage
                        $this->getDerivedDataUpdater( $user, null, $forUpdate, true ),
                        $this->getDBLoadBalancer(),
-                       $this->getRevisionStore()
+                       $this->getRevisionStore(),
+                       $this->getSlotRoleRegistry()
                );
 
                $pageUpdater->setUsePageCreationLog( $wgPageCreationLog );
index 11825fa..81e23ad 100644 (file)
@@ -5066,9 +5066,10 @@ class Parser {
                        $ig->setShowFilename( false );
                }
                if ( isset( $params['caption'] ) ) {
-                       $caption = $params['caption'];
-                       $caption = htmlspecialchars( $caption );
-                       $caption = $this->replaceInternalLinks( $caption );
+                       // NOTE: We aren't passing a frame here or below.  Frame info
+                       // is currently opaque to Parsoid, which acts on OT_PREPROCESS.
+                       // See T107332#4030581
+                       $caption = $this->recursiveTagParse( $params['caption'] );
                        $ig->setCaptionHtml( $caption );
                }
                if ( isset( $params['perrow'] ) ) {
@@ -5524,6 +5525,40 @@ class Parser {
                # that are later expanded to html- so expand them now and
                # remove the tags
                $tooltip = $this->mStripState->unstripBoth( $tooltip );
+               # Compatibility hack!  In HTML certain entity references not terminated
+               # by a semicolon are decoded (but not if we're in an attribute; that's
+               # how link URLs get away without properly escaping & in queries).
+               # But wikitext has always required semicolon-termination of entities,
+               # so encode & where needed to avoid decode of semicolon-less entities.
+               # See T209236 and
+               # https://www.w3.org/TR/html5/syntax.html#named-character-references
+               # T210437 discusses moving this workaround to Sanitizer::stripAllTags.
+               $tooltip = preg_replace( "/
+                       &                       # 1. entity prefix
+                       (?=                     # 2. followed by:
+                       (?:                     #  a. one of the legacy semicolon-less named entities
+                               A(?:Elig|MP|acute|circ|grave|ring|tilde|uml)|
+                               C(?:OPY|cedil)|E(?:TH|acute|circ|grave|uml)|
+                               GT|I(?:acute|circ|grave|uml)|LT|Ntilde|
+                               O(?:acute|circ|grave|slash|tilde|uml)|QUOT|REG|THORN|
+                               U(?:acute|circ|grave|uml)|Yacute|
+                               a(?:acute|c(?:irc|ute)|elig|grave|mp|ring|tilde|uml)|brvbar|
+                               c(?:cedil|edil|urren)|cent(?!erdot;)|copy(?!sr;)|deg|
+                               divide(?!ontimes;)|e(?:acute|circ|grave|th|uml)|
+                               frac(?:1(?:2|4)|34)|
+                               gt(?!c(?:c|ir)|dot|lPar|quest|r(?:a(?:pprox|rr)|dot|eq(?:less|qless)|less|sim);)|
+                               i(?:acute|circ|excl|grave|quest|uml)|laquo|
+                               lt(?!c(?:c|ir)|dot|hree|imes|larr|quest|r(?:Par|i(?:e|f|));)|
+                               m(?:acr|i(?:cro|ddot))|n(?:bsp|tilde)|
+                               not(?!in(?:E|dot|v(?:a|b|c)|)|ni(?:v(?:a|b|c)|);)|
+                               o(?:acute|circ|grave|rd(?:f|m)|slash|tilde|uml)|
+                               p(?:lusmn|ound)|para(?!llel;)|quot|r(?:aquo|eg)|
+                               s(?:ect|hy|up(?:1|2|3)|zlig)|thorn|times(?!b(?:ar|)|d;)|
+                               u(?:acute|circ|grave|ml|uml)|y(?:acute|en|uml)
+                       )
+                       (?:[^;]|$))     #  b. and not followed by a semicolon
+                       # S = study, for efficiency
+                       /Sx", '&amp;', $tooltip );
                $tooltip = Sanitizer::stripAllTags( $tooltip );
 
                return $tooltip;
index de67b84..032d481 100644 (file)
@@ -57,7 +57,7 @@ class ParserOptions {
 
        /**
         * Lazy-loaded options
-        * @var callback[]
+        * @var callable[]
         */
        private static $lazyOptions = [
                'dateformat' => [ __CLASS__, 'initDateFormat' ],
index 41c6bf4..a41e7b6 100644 (file)
@@ -66,7 +66,6 @@ class RemexStripTagHandler implements TokenHandler {
                'fieldset' => true,
                'figcaption' => true,
                'figure' => true,
-               'figcaption' => true,
                'footer' => true,
                'form' => true,
                'h1' => true,
index 84f8083..f8c3bc2 100644 (file)
@@ -349,18 +349,18 @@ class Sanitizer {
 
        /**
         * Regular expression to match HTML/XML attribute pairs within a tag.
-        * Allows some... latitude. Based on,
-        * https://www.w3.org/TR/html5/syntax.html#before-attribute-value-state
-        * Used in Sanitizer::fixTagAttributes and Sanitizer::decodeTagAttributes
+        * Based on https://www.w3.org/TR/html5/syntax.html#before-attribute-name-state
+        * Used in Sanitizer::decodeTagAttributes
         * @return string
         */
        static function getAttribsRegex() {
                if ( self::$attribsRegex === null ) {
-                       $attribFirst = "[:_\p{L}\p{N}]";
-                       $attrib = "[:_\.\-\p{L}\p{N}]";
-                       $space = '[\x09\x0a\x0c\x0d\x20]';
+                       $spaceChars = '\x09\x0a\x0c\x0d\x20';
+                       $space = "[{$spaceChars}]";
+                       $attrib = "[^{$spaceChars}\/>=]";
+                       $attribFirst = "(?:{$attrib}|=)";
                        self::$attribsRegex =
-                               "/(?:^|$space)({$attribFirst}{$attrib}*)
+                               "/({$attribFirst}{$attrib}*)
                                        ($space*=$space*
                                        (?:
                                                # The attribute value: quoted or alone
@@ -368,11 +368,29 @@ class Sanitizer {
                                                | '([^']*)(?:'|\$)
                                                | (((?!$space|>).)*)
                                        )
-                               )?(?=$space|\$)/sxu";
+                               )?/sxu";
                }
                return self::$attribsRegex;
        }
 
+       /**
+        * Lazy-initialised attribute name regex, see getAttribNameRegex()
+        */
+       private static $attribNameRegex;
+
+       /**
+        * Used in Sanitizer::decodeTagAttributes to filter attributes.
+        * @return string
+        */
+       static function getAttribNameRegex() {
+               if ( self::$attribNameRegex === null ) {
+                       $attribFirst = "[:_\p{L}\p{N}]";
+                       $attrib = "[:_\.\-\p{L}\p{N}]";
+                       self::$attribNameRegex = "/^({$attribFirst}{$attrib}*)$/sxu";
+               }
+               return self::$attribNameRegex;
+       }
+
        /**
         * Return the various lists of recognized tags
         * @param array $extratags For any extra tags to include
@@ -1434,18 +1452,24 @@ class Sanitizer {
                        return [];
                }
 
-               $attribs = [];
                $pairs = [];
                if ( !preg_match_all(
                        self::getAttribsRegex(),
                        $text,
                        $pairs,
                        PREG_SET_ORDER ) ) {
-                       return $attribs;
+                       return [];
                }
 
+               $attribs = [];
                foreach ( $pairs as $set ) {
                        $attribute = strtolower( $set[1] );
+
+                       // Filter attribute names with unacceptable characters
+                       if ( !preg_match( self::getAttribNameRegex(), $attribute ) ) {
+                               continue;
+                       }
+
                        $value = self::getTagAttributeCallback( $set );
 
                        // Normalize whitespace
index 04ee6e9..3c56535 100644 (file)
@@ -87,7 +87,7 @@ class PasswordPolicyChecks {
                $username = $user->getName();
                $contLang = MediaWikiServices::getInstance()->getContentLanguage();
                if (
-                       $policyVal && $contLang->lc( $password ) === $contLang->lc( $username )
+                       $policyVal && hash_equals( $contLang->lc( $username ), $contLang->lc( $password ) )
                ) {
                        $status->error( 'password-name-match' );
                }
@@ -110,12 +110,15 @@ class PasswordPolicyChecks {
                $status = Status::newGood();
                $username = $user->getName();
                if ( $policyVal ) {
-                       if ( isset( $blockedLogins[$username] ) && $password == $blockedLogins[$username] ) {
+                       if (
+                               isset( $blockedLogins[$username] ) &&
+                               hash_equals( $blockedLogins[$username], $password )
+                       ) {
                                $status->error( 'password-login-forbidden' );
                        }
 
                        // Example from ApiChangeAuthenticationRequest
-                       if ( $password === 'ExamplePassword' ) {
+                       if ( hash_equals( 'ExamplePassword', $password ) ) {
                                $status->error( 'password-login-forbidden' );
                        }
                }
index 32a5404..769954d 100644 (file)
@@ -796,6 +796,7 @@ class DefaultPreferencesFactory implements PreferencesFactory {
                        'section' => 'rendering/timeoffset',
                        'id' => 'wpTimeCorrection',
                        'filter' => TimezoneFilter::class,
+                       'placeholder-message' => 'timezone-useoffset-placeholder',
                ];
        }
 
index e43b3b8..07fab78 100644 (file)
@@ -46,6 +46,7 @@ class ExtensionProcessor implements Processor {
                'PasswordPolicy',
                'RateLimits',
                'RawHtmlMessages',
+               'ReauthenticateTime',
                'RecentChangesFlags',
                'RemoveCredentialsBlacklist',
                'RemoveGroups',
index d9c369d..ef11628 100644 (file)
@@ -292,7 +292,7 @@ class ResourceLoaderImage {
         * @return string New SVG file data
         */
        protected function variantize( $variantConf, ResourceLoaderContext $context ) {
-               $dom = new DomDocument;
+               $dom = new DOMDocument;
                $dom->loadXML( file_get_contents( $this->getPath( $context ) ) );
                $root = $dom->documentElement;
                $wrapper = $dom->createElement( 'g' );
@@ -315,7 +315,7 @@ class ResourceLoaderImage {
         * @return string Massaged SVG image data
         */
        protected function massageSvgPathdata( $svg ) {
-               $dom = new DomDocument;
+               $dom = new DOMDocument;
                $dom->loadXML( $svg );
                foreach ( $dom->getElementsByTagName( 'path' ) as $node ) {
                        $pathData = $node->getAttribute( 'd' );
index a8bf814..19fe0c3 100644 (file)
@@ -120,14 +120,17 @@ class RevisionDeleteUser {
                        $actorId = $dbw->selectField( 'actor', 'actor_id', [ 'actor_name' => $name ], __METHOD__ );
                        if ( $actorId ) {
                                # Hide name from live edits
-                               $subquery = $dbw->selectSQLText(
+                               $ids = $dbw->selectFieldValues(
                                        'revision_actor_temp', 'revactor_rev', [ 'revactor_actor' => $actorId ], __METHOD__
                                );
-                               $dbw->update(
-                                       'revision',
-                                       [ self::buildSetBitDeletedField( 'rev_deleted', $op, $delUser, $dbw ) ],
-                                       [ "rev_id IN ($subquery)" ],
-                                       __METHOD__ );
+                               if ( $ids ) {
+                                       $dbw->update(
+                                               'revision',
+                                               [ self::buildSetBitDeletedField( 'rev_deleted', $op, $delUser, $dbw ) ],
+                                               [ 'rev_id' => $ids ],
+                                               __METHOD__
+                                       );
+                               }
 
                                # Hide name from deleted edits
                                $dbw->update(
index cb1f831..f1da246 100644 (file)
@@ -80,7 +80,7 @@ class SearchSuggestionSet {
 
        /**
         * Call array_map on the suggestions array
-        * @param callback $callback
+        * @param callable $callback
         * @return array
         */
        public function map( $callback ) {
@@ -89,7 +89,7 @@ class SearchSuggestionSet {
 
        /**
         * Filter the suggestions array
-        * @param callback $callback Callable accepting single SearchSuggestion
+        * @param callable $callback Callable accepting single SearchSuggestion
         *  instance returning bool false to remove the item.
         * @return int The number of suggestions removed
         */
index 1476e85..8466399 100644 (file)
@@ -254,7 +254,7 @@ abstract class AuthManagerSpecialPage extends SpecialPage {
 
                $allReqs = AuthManager::singleton()->getAuthenticationRequests(
                        $this->authAction, $this->getUser() );
-               $this->authRequests = array_filter( $allReqs, function ( $req ) use ( $subPage ) {
+               $this->authRequests = array_filter( $allReqs, function ( $req ) {
                        return !in_array( get_class( $req ), $this->getRequestBlacklist(), true );
                } );
        }
index 513e7a9..ef61ac5 100644 (file)
@@ -378,7 +378,6 @@ class SpecialExport extends SpecialPage {
                }
 
                /* Ok, let's get to it... */
-               $lb = false;
                $db = wfGetDB( DB_REPLICA );
 
                $exporter = new WikiExporter( $db, $history );
@@ -406,10 +405,6 @@ class SpecialExport extends SpecialPage {
                }
 
                $exporter->closeStream();
-
-               if ( $lb ) {
-                       $lb->closeAll();
-               }
        }
 
        /**
index 7661f28..50f3710 100644 (file)
@@ -205,7 +205,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
 
                # Either submit or create our form
                if ( $this->mIsAllowed && $this->submitClicked ) {
-                       $this->submit( $request );
+                       $this->submit();
                } else {
                        $this->showForm();
                }
index bf4d9af..81abf1c 100644 (file)
@@ -227,8 +227,7 @@ class PreferencesFormOOUI extends OOUIHTMLForm {
         * @return string
         */
        function getLegend( $key ) {
-               $aliasKey = ( $key === 'optoutwatchlist' || $key === 'optoutrc' ) ? 'opt-out' : $key;
-               $legend = parent::getLegend( $aliasKey );
+               $legend = parent::getLegend( $key );
                Hooks::run( 'PreferencesGetLegend', [ $this, $key, &$legend ] );
                return $legend;
        }
index 552e92f..506cd3c 100644 (file)
@@ -149,14 +149,17 @@ class ActiveUsersPager extends UsersPager {
                // is done in two queries to avoid huge quicksorts and to make COUNT(*) correct.
                $dbr = $this->getDatabase();
                $res = $dbr->select( 'ipblocks',
-                       [ 'ipb_user', 'MAX(ipb_deleted) AS block_status' ],
+                       [ 'ipb_user', 'MAX(ipb_deleted) AS deleted, MAX(ipb_sitewide) AS sitewide' ],
                        [ 'ipb_user' => $uids ],
                        __METHOD__,
                        [ 'GROUP BY' => [ 'ipb_user' ] ]
                );
                $this->blockStatusByUid = [];
                foreach ( $res as $row ) {
-                       $this->blockStatusByUid[$row->ipb_user] = $row->block_status; // 0 or 1
+                       $this->blockStatusByUid[$row->ipb_user] = [
+                               'deleted' => $row->deleted,
+                               'sitewide' => $row->sitewide,
+                       ];
                }
                $this->mResult->seek( 0 );
        }
@@ -181,13 +184,20 @@ class ActiveUsersPager extends UsersPager {
 
                $item = $lang->specialList( $ulinks, $groups );
 
+               // If there is a block, 'deleted' and 'sitewide' are both set on
+               // $this->blockStatusByUid[$row->user_id].
+               $blocked = '';
                $isBlocked = isset( $this->blockStatusByUid[$row->user_id] );
-               if ( $isBlocked && $this->blockStatusByUid[$row->user_id] == 1 ) {
-                       $item = "<span class=\"deleted\">$item</span>";
+               if ( $isBlocked ) {
+                       if ( $this->blockStatusByUid[$row->user_id]['deleted'] == 1 ) {
+                               $item = "<span class=\"deleted\">$item</span>";
+                       }
+                       if ( $this->blockStatusByUid[$row->user_id]['sitewide'] == 1 ) {
+                               $blocked = ' ' . $this->msg( 'listusers-blocked', $userName )->escaped();
+                       }
                }
                $count = $this->msg( 'activeusers-count' )->numParams( $row->recentedits )
                        ->params( $userName )->numParams( $this->RCMaxAge )->escaped();
-               $blocked = $isBlocked ? ' ' . $this->msg( 'listusers-blocked', $userName )->escaped() : '';
 
                return Html::rawElement( 'li', [], "{$item} [{$count}]{$blocked}" );
        }
index 74ec6b5..e8a7d2d 100644 (file)
@@ -224,7 +224,7 @@ class BlockListPager extends TablePager {
                                                'ul',
                                                [],
                                                implode( '', array_map( function ( $prop ) {
-                                                       return HTML::rawElement(
+                                                       return Html::rawElement(
                                                                'li',
                                                                [],
                                                                $prop
@@ -264,7 +264,7 @@ class BlockListPager extends TablePager {
                                continue;
                        }
 
-                       $items[] = HTML::rawElement(
+                       $items[] = Html::rawElement(
                                'li',
                                [],
                                Linker::link( $restriction->getTitle() )
index f16a5cb..b85bc2f 100644 (file)
@@ -59,8 +59,6 @@ class NewPagesPager extends ReverseChronologicalPager {
                        }
                }
 
-               $rcIndexes = [];
-
                if ( $namespace !== false ) {
                        if ( $this->opts->getValue( 'invert' ) ) {
                                $conds[] = 'rc_namespace != ' . $this->mDb->addQuotes( $namespace );
@@ -105,17 +103,11 @@ class NewPagesPager extends ReverseChronologicalPager {
                Hooks::run( 'SpecialNewpagesConditions',
                        [ &$pager, $this->opts, &$conds, &$tables, &$fields, &$join_conds ] );
 
-               $options = [];
-
-               if ( $rcIndexes ) {
-                       $options = [ 'USE INDEX' => [ 'recentchanges' => $rcIndexes ] ];
-               }
-
                $info = [
                        'tables' => $tables,
                        'fields' => $fields,
                        'conds' => $conds,
-                       'options' => $options,
+                       'options' => [],
                        'join_conds' => $join_conds
                ];
 
index bc24d26..fbf179d 100644 (file)
@@ -142,7 +142,8 @@ class UsersPager extends AlphabeticPager {
                                'user_id' => $this->creationSort ? 'user_id' : 'MAX(user_id)',
                                'edits' => 'MAX(user_editcount)',
                                'creation' => 'MIN(user_registration)',
-                               'ipb_deleted' => 'MAX(ipb_deleted)' // block/hide status
+                               'ipb_deleted' => 'MAX(ipb_deleted)', // block/hide status
+                               'ipb_sitewide' => 'MAX(ipb_sitewide)'
                        ],
                        'options' => $options,
                        'join_conds' => [
@@ -214,7 +215,8 @@ class UsersPager extends AlphabeticPager {
                        $created = $this->msg( 'usercreated', $d, $t, $row->user_name )->escaped();
                        $created = ' ' . $this->msg( 'parentheses' )->rawParams( $created )->escaped();
                }
-               $blocked = !is_null( $row->ipb_deleted ) ?
+
+               $blocked = !is_null( $row->ipb_deleted ) && $row->ipb_sitewide === '1' ?
                        ' ' . $this->msg( 'listusers-blocked', $userName )->escaped() :
                        '';
 
index ee6f250..58541b2 100644 (file)
@@ -54,11 +54,7 @@ class UploadFromChunks extends UploadFromFile {
                if ( $stash ) {
                        $this->stash = $stash;
                } else {
-                       if ( $user ) {
-                               wfDebug( __METHOD__ . " creating new UploadFromChunks instance for " . $user->getId() . "\n" );
-                       } else {
-                               wfDebug( __METHOD__ . " creating new UploadFromChunks instance with no user\n" );
-                       }
+                       wfDebug( __METHOD__ . " creating new UploadFromChunks instance for " . $user->getId() . "\n" );
                        $this->stash = new UploadStash( $this->repo, $this->user );
                }
        }
index 5f772a4..0e04946 100644 (file)
@@ -935,7 +935,7 @@ class User implements IDBAccessObject, UserIdentity {
                if ( $s === false ) {
                        $result = null;
                } else {
-                       $result = $s->user_id;
+                       $result = (int)$s->user_id;
                }
 
                self::$idCacheByName[$name] = $result;
@@ -2304,16 +2304,18 @@ class User implements IDBAccessObject, UserIdentity {
                if ( !$blocked ) {
                        $block = $this->getBlock( $fromReplica );
                        if ( $block ) {
-                               // A sitewide block covers everything except maybe the user's
-                               // talk page. A partial block covering the user's talk page
-                               // overrides the editownusertalk flag, however.
-                               // TODO: Do we really want a partial block on the user talk
-                               //  namespace to ignore editownusertalk?
-                               $blocked = $block->isSitewide();
-                               if ( $blocked && $title->equals( $this->getTalkPage() ) ) {
-                                       $blocked = $block->prevents( 'editownusertalk' );
-                               }
-                               if ( !$block->isSitewide() ) {
+                               // Special handling for a user's own talk page. The block is not aware
+                               // of the user, so this must be done here.
+                               if ( $title->equals( $this->getTalkPage() ) ) {
+                                       // If the block is sitewide, then whatever is set is what is honored.
+                                       if ( $block->isSitewide() ) {
+                                               $blocked = $block->prevents( 'editownusertalk' );
+                                       } else {
+                                               // If the block is partial, then only a true value is honored,
+                                               // otherwise fallback to the partial block settings.
+                                               $blocked = $block->prevents( 'editownusertalk' ) ?: $block->appliesToTitle( $title );
+                                       }
+                               } else {
                                        $blocked = $block->appliesToTitle( $title );
                                }
                        }
index 11cc21f..15c0cf9 100644 (file)
@@ -74,7 +74,7 @@ class UIDGenerator {
                        }
                        Wikimedia\restoreWarnings();
                        if ( !preg_match( '/^[0-9a-f]{12}$/i', $nodeId ) ) {
-                               $nodeId = MWCryptRand::generateHex( 12, true );
+                               $nodeId = MWCryptRand::generateHex( 12 );
                                $nodeId[1] = dechex( hexdec( $nodeId[1] ) | 0x1 ); // set multicast bit
                        }
                        file_put_contents( $this->nodeIdFile, $nodeId ); // cache
index 8be2d6a..4a330ad 100644 (file)
@@ -153,25 +153,27 @@ class ConverterRule {
                        $to = trim( $v[1] );
                        $v = trim( $v[0] );
                        $u = explode( '=>', $v, 2 );
+                       $vv = $this->mConverter->validateVariant( $v );
                        // if $to is empty (which is also used as $from in bidtable),
                        // strtr() could return a wrong result.
-                       if ( count( $u ) == 1 && $to !== '' && in_array( $v, $variants ) ) {
-                               $bidtable[$v] = $to;
+                       if ( count( $u ) == 1 && $to !== '' && $vv ) {
+                               $bidtable[$vv] = $to;
                        } elseif ( count( $u ) == 2 ) {
                                $from = trim( $u[0] );
                                $v = trim( $u[1] );
+                               $vv = $this->mConverter->validateVariant( $v );
                                // if $from is empty, strtr() could return a wrong result.
-                               if ( array_key_exists( $v, $unidtable )
-                                       && !is_array( $unidtable[$v] )
+                               if ( array_key_exists( $vv, $unidtable )
+                                       && !is_array( $unidtable[$vv] )
                                        && $from !== ''
-                                       && in_array( $v, $variants ) ) {
-                                       $unidtable[$v] = [ $from => $to ];
-                               } elseif ( $from !== '' && in_array( $v, $variants ) ) {
-                                       $unidtable[$v][$from] = $to;
+                                       && $vv ) {
+                                       $unidtable[$vv] = [ $from => $to ];
+                               } elseif ( $from !== '' && $vv ) {
+                                       $unidtable[$vv][$from] = $to;
                                }
                        }
                        // syntax error, pass
-                       if ( !isset( $this->mConverter->mVariantNames[$v] ) ) {
+                       if ( !isset( $this->mConverter->mVariantNames[$vv] ) ) {
                                $bidtable = [];
                                $unidtable = [];
                                break;
index 50963b0..d7cd8b5 100644 (file)
@@ -1833,22 +1833,19 @@ class Language {
                while ( $hebrewMonth <= 12 ) {
                        # Calculate days in this month
                        if ( $isLeap && $hebrewMonth == 6 ) {
-                               # Adar in a leap year
-                               if ( $isLeap ) {
-                                       # Leap year - has Adar I, with 30 days, and Adar II, with 29 days
-                                       $days = 30;
+                               # Leap year - has Adar I, with 30 days, and Adar II, with 29 days
+                               $days = 30;
+                               if ( $hebrewDay <= $days ) {
+                                       # Day in Adar I
+                                       $hebrewMonth = 13;
+                               } else {
+                                       # Subtract the days of Adar I
+                                       $hebrewDay -= $days;
+                                       # Try Adar II
+                                       $days = 29;
                                        if ( $hebrewDay <= $days ) {
-                                               # Day in Adar I
-                                               $hebrewMonth = 13;
-                                       } else {
-                                               # Subtract the days of Adar I
-                                               $hebrewDay -= $days;
-                                               # Try Adar II
-                                               $days = 29;
-                                               if ( $hebrewDay <= $days ) {
-                                                       # Day in Adar II
-                                                       $hebrewMonth = 14;
-                                               }
+                                               # Day in Adar II
+                                               $hebrewMonth = 14;
                                        }
                                }
                        } elseif ( $hebrewMonth == 2 && $yearPattern == 2 ) {
index 3c8d300..8fdf4f5 100644 (file)
@@ -1176,8 +1176,21 @@ class LanguageConverter {
                        //    [1] => 'zh-hant:<span style="font-size:120%;">yyy</span>'
                        //    [2] => ''
                        //  ]
-                       $pat = '/;\s*(?=';
+                       $expandedVariants = [];
                        foreach ( $this->mVariants as $variant ) {
+                               $expandedVariants[ $variant ] = 1;
+                               // Accept standard BCP 47 names for variants as well.
+                               $expandedVariants[ LanguageCode::bcp47( $variant ) ] = 1;
+                       }
+                       // Accept old deprecated names for variants
+                       foreach ( LanguageCode::getDeprecatedCodeMapping() as $old => $new ) {
+                               if ( isset( $expandedVariants[ $new ] ) ) {
+                                       $expandedVariants[ $old ] = 1;
+                               }
+                       }
+
+                       $pat = '/;\s*(?=';
+                       foreach ( $expandedVariants as $variant => $ignore ) {
                                // zh-hans:xxx;zh-hant:yyy
                                $pat .= $variant . '\s*:|';
                                // xxx=>zh-hans:yyy; xxx=>zh-hant:zzz
index 580f64a..31c9f46 100644 (file)
@@ -76,8 +76,8 @@ class KuConverter extends LanguageConverter {
                't' => 'ت', 'v' => 'ڤ',
                'x' => 'خ', 'y' => 'ی', 'z' => 'ز',
 
-               'B' => 'ب', 'C' => 'ج', 'Ç' => 'چ', 'D' => 'د', 'F' => 'ف', 'G' => 'گ', 'H' => 'ھ',
-               'H' => 'ہ', 'H' => 'ه', 'H' => 'ح', 'J' => 'ژ', 'K' => 'ك', 'K' => 'ک', 'L' => 'ل',
+               'B' => 'ب', 'C' => 'ج', 'Ç' => 'چ', 'D' => 'د', 'F' => 'ف', 'G' => 'گ',
+               'H' => 'ح', 'J' => 'ژ', 'K' => 'ک', 'L' => 'ل',
                'M' => 'م', 'N' => 'ن', 'P' => 'پ', 'Q' => 'ق', 'R' => 'ر', 'S' => 'س', 'Ş' => 'ش',
                'T' => 'ت', 'V' => 'ڤ', 'W' => 'و', 'X' => 'خ',
                'Y' => 'ی', 'Z' => 'ز',
index 36821b0..ba1e1b6 100644 (file)
@@ -40,7 +40,7 @@ class ShiConverter extends LanguageConverter {
                'ⴰ' => 'a', 'ⴱ' => 'b', 'ⴳ' => 'g', 'ⴷ' => 'd', 'ⴹ' => 'ḍ', 'ⴻ' => 'e',
                'ⴼ' => 'f', 'ⴽ' => 'k', 'ⵀ' => 'h', 'ⵃ' => 'ḥ', 'ⵄ' => 'ε', 'ⵅ' => 'x',
                'ⵇ' => 'q', 'ⵉ' => 'i', 'ⵊ' => 'j', 'ⵍ' => 'l', 'ⵎ' => 'm', 'ⵏ' => 'n',
-               'âµ\93' => 'u', 'âµ\94' => 'r', 'âµ\95' => 'á¹\9b', 'âµ\96' => 'γ', 'âµ\99' => 's', 'âµ\9a' => 'á¹£',
+               'ⵓ' => 'u', 'ⵔ' => 'r', 'ⵕ' => 'ṛ', 'ⵙ' => 's', 'ⵚ' => 'ṣ',
                'ⵛ' => 'š', 'ⵜ' => 't', 'ⵟ' => 'ṭ', 'ⵡ' => 'w', 'ⵢ' => 'y', 'ⵣ' => 'z',
                'ⵥ' => 'ẓ', 'ⵯ' => 'ʷ', 'ⵖ' => 'ɣ', 'ⵠ' => 'v', 'ⵒ' => 'p',
        ];
index e205dc9..0f1e456 100644 (file)
@@ -50,7 +50,6 @@ class UzConverter extends LanguageConverter {
                'т' => 't', 'Т' => 'T',
                'у' => 'u', 'У' => 'U',
                'ф' => 'f', 'Ф' => 'F',
-               'ц' => 'c', 'Ц' => 'C',
                'ў' => 'oʻ', 'Ў' => 'Oʻ',
                // note: at the beginning of a word and right after a consonant, only "s" is used
                'ц' => 'ts', 'Ц' => 'Ts',
index 92c1f86..bd90fc6 100644 (file)
@@ -657,12 +657,8 @@ class CrhExceptions {
                                self::WB . ')/u' => '$1ö$2ь$3',
                        '/' . self::WB . '([bcgkpşBCGKPŞ])Ö([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
                                self::WB . ')/u' => '$1Ö$2Ь$3',
-                       '/' . self::WB . '([bcgkpşBCGKPŞ])Ö([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
-                               self::WB . ')/u' => '$1Ö$2Ь$3',
                        '/' . self::WB . '([bcgkpşBCGKPŞ])ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
                                self::WB . ')/u' => '$1ü$2ь$3',
-                       '/' . self::WB . '([bcgkpşBCGKPŞ])Ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
-                               self::WB . ')/u' => '$1Ü$2Ь$3',
                        '/' . self::WB . '([bcgkpşBCGKPŞ])Ü([' . Crh::L_N_CONS . '])([' . Crh::L_CONS . ']|' .
                                self::WB . ')/u' => '$1Ü$2Ь$3',
 
index 717450f..84d118e 100644 (file)
        "ns-specialprotected": "Laman kusuih h'an jeuet geupeusaneut",
        "titleprotected": "Nan nyoe ka geupeulindông nibak neuandam lé [[User:$1|$1]].\nDalèhjih nakeuh <em>$2</em>.",
        "invalidtitle-knownnamespace": "Nan nyang hana sah ngön ruweueng nan \"$2\" ngön \"$3\"",
-       "exception-nologin": "Goh lom tamong log",
+       "exception-nologin": "Goh lom neutamöng",
        "exception-nologin-text": "Droëneuh suwah [[Special:Userlogin|neutamöng]] mangat jeuët neupeuhah laman nyoë",
        "virus-unknownscanner": "Antivirus hana geuturi:",
-       "logouttext": "'''Droeneuh ka neutubiet log.'''\n\nBeuneuteupue meunyoe na padum-padum laman nyang deuh lagèe na neutamöng log, sampoe ka lheuh neupeugléh ''cache''.",
+       "logouttext": "<strong>Droeneuh ka neuteubiet.</strong>\n\nBeu neutupeue meunyo na padum-padum laman nyang leumah lagèe na neutamöng, sampoe ka neupeugléh cache browser.",
        "cannotlogoutnow-title": "H'an jeuet teubiet jinoe",
        "welcomeuser": "Seulamat trôk teuka, $1 !",
        "welcomecreation-msg": "Akun-neuh ka geupeugöt. \nDroeneuh jeuet neugantoe {{SITENAME}} [[Special:Preferences|peuatô]] meunyö neumeuh'eut.",
        "yourname": "Ureuëng ngui:",
        "userlogin-yourname": "Ureuëng ngui",
-       "userlogin-yourname-ph": "Peutamöng nan ureuëng ngui droëneuh",
+       "userlogin-yourname-ph": "Peutamöng nan ureueng ngui",
        "createacct-another-username-ph": "Pasoë nan ureuëng ngui droëneuh",
        "yourpassword": "Lageuem tamöng:",
        "userlogin-yourpassword": "Lageuem tamöng",
-       "userlogin-yourpassword-ph": "Pasoe lageuem tamöng droeneuh",
+       "userlogin-yourpassword-ph": "Pasoe lageuem tamöng",
        "createacct-yourpassword-ph": "Pasoe lageuem tamöng",
        "yourpasswordagain": "Pasoe lom lageuem tamöng:",
        "createacct-yourpasswordagain": "Peunyo lageuem tamöng",
        "userlogin-joinproject": "Neugabông ngön {{SITENAME}}",
        "createaccount": "Peudapeuta nan barô",
        "userlogin-resetpassword-link": "Tuwö lageuem tamöng?",
-       "userlogin-helplink2": "Beunantu tamöng log",
+       "userlogin-helplink2": "Beunantu tamöng",
        "userlogin-loggedin": "Droëneuh ka neutamöng seubagoë $1. Neungui blangko di yup keu neutamöng seubagoë ureuëng ngui la’én",
        "userlogin-createanother": "Peugöt akun laén",
        "createacct-emailrequired": "Alamat surat-e",
        "createaccounterror": "H'an jeuet peugöt akun: $1",
        "nocookiesnew": "Akun ureueng ngui nyoe ka geupeugöt, tapi droeneuh goh lom neutamöng.\n{{SITENAME}} jingui kuki keu jipeutamöng ureueng ngui.\nKuki droeneuh hana geupeuudép.\nNeupeuudép kuki dilèe, lheueh nyan neutamöng ngön nan ureueng ngui ngön lageuem tamöng barô droeneuh.",
        "noname": "Nan ureuëng ngui nyang Droënueh peutamöng hana sah.",
-       "loginsuccesstitle": "Meuhasé tamöng log",
+       "loginsuccesstitle": "Meuhasé neutamöng",
        "loginsuccess": "'''Droëneuh  jinoë ka neutamöng di {{SITENAME}} sibagoë \"$1\".'''",
        "nosuchuser": "Hana ureuëng ngui ngön nan \"$1\".\nHaraih rayek ngön haraih ubeut na peungarôh.\nNeuparéksa ijaan-neuh, atawa [[Special:CreateAccount|neupeugöt akun]].",
        "nosuchusershort": "Hana ureuëng ngui ngön nan \"$1\".\nPréksa keulayi neu’ija Droëneuh.",
        "revdelete-hide-comment": "Mohtasa neuandam",
        "revdelete-radio-same": "(bèk neugantoe)",
        "revdelete-radio-set": "Teusom",
-       "revdelete-radio-unset": "Deuih",
+       "revdelete-radio-unset": "Leumah",
        "revdelete-log": "Alasan:",
        "revdel-restore": "Gantoë neuleumah",
        "pagehist": "Riwayat laman",
        "sp-contributions-logs": "log",
        "sp-contributions-talk": "marit",
        "sp-contributions-search": "Mita soë nyang tuléh",
-       "sp-contributions-username": "Alamat IP atawa nan ureuëng ngui:",
+       "sp-contributions-username": "Alamat IP atawa nan ureueng ngui:",
        "sp-contributions-toponly": "Peuleumah geunantoe nyang baro mantong",
        "sp-contributions-newonly": "Peuleumah pumeugöt laman mantöng",
        "sp-contributions-hideminor": "Peusom peusaneut bacut",
index 2186ac9..9c713b5 100644 (file)
@@ -12,7 +12,8 @@
                        "Peserey",
                        "SamGamgee",
                        "SmartNart12",
-                       "TheRossatron"
+                       "TheRossatron",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Зэпыщэхэм якIэгъэтхъын:",
        "right-editcontentmodel": "НэкIубгъом и кIоцIырытым и модел зэблэхъун",
        "right-editinterface": "Нэбгырэ-интерфейсым еIэзэн",
        "right-editusercss": "НэмыкI нэбгырэмэ я CSS файлэмэ яIэзэн",
+       "right-edituserjson": "НэмыкI нэбгырэмэ я JSON файлэмэ яIэзэн",
        "right-edituserjs": "НэмыкI нэбгырэмэ я JavaScript файлэмэ яIэзэн",
        "right-editmyusercss": "Уи CSS файлэмэ яIэзэн",
+       "right-editmyuserjson": "Уи JSON файлэмэ яIэзэн",
        "right-editmyuserjs": "Уи JavaScript файлэмэ яIэзэн",
        "right-viewmywatchlist": "Уи лъыплъэ купым еплъ",
        "right-editmyoptions": "УигъэпсыкIэмэ яIаз",
index b5c162c..26ed04e 100644 (file)
@@ -11,7 +11,8 @@
                        "Nemo bis",
                        "Shbib Al-Subaie",
                        "Macofe",
-                       "علاء"
+                       "علاء",
+                       "Meno25"
                ]
        },
        "tog-usenewrc": ")جمّع التعديلات حسب الصفحة في أحدث التغييرات وقائمة المراقبة (يتطلب جافاسكربت",
        "previewconflict": "هذا العرض يوضح النص الموجود في صندوق التحرير العلوي والذي سيظهر إذا اخترت الحفظ.",
        "session_fail_preview": "'''عذرا! لم نتمكن من حفظ التعديلات التي قمت بها نتيجة لضياع بيانات هذه الجلسة.\nمن فضلك حاول مرة أخرى.\nفي حال استمرار المشكلة حاول أن تقوم [[Special:UserLogout|بالخروج]] ومن ثم الولوج مرة أخرى.'''",
        "session_fail_preview_html": "'''عذرا! لم نستطع معالجة تعديلك بسبب فقدان بيانات الجلسة.'''\n\n''لأن {{SITENAME}} بها HTML الخام مفعلة، العرض المسبق مخفي كاحتياط ضد هجمات الجافا سكريبت.''\n\n'''إذا كانت هذه محاولة تعديل صادقة، من فضلك حاول مرة أخرى.\nإذا كانت مازالت لا تعمل، حاول [[Special:UserLogout|تسجيل الخروج]] ثم تسجيل الدخول مجددا.'''",
-       "token_suffix_mismatch": "'''تعديلك تم رفضه لأن عميلك أخطأ في علامات الترقيم\nفي نص التعديل. تم رفض التعديل لمنع فساد نص المقالة.\nهذا يحدث أحيانا عندما تستخدم خدمة بروكسي مجهول معيبة مبنية على الوب.'''",
+       "token_suffix_mismatch": "<strong>تعديلك تم رفضه لأن عميلك أخطأ في علامات الترقيم في نص التعديل.</strong>\nتم رفض التعديل لمنع فساد نص المقالة.\nهذا يحدث أحيانا عندما تستخدم خدمة بروكسي مجهول معيبة مبنية على الويب.",
        "edit_form_incomplete": "'''بعض أجزاء من نموذج التعديل لم تصل إلى الخادم؛ تأكد من أن تعديلاتك لم تمس وحاول مجددا.'''",
        "editing": "تبديل $1",
        "creating": "عملان «$1»",
index 4df3cfd..6fc476a 100644 (file)
        "passwordtooshort": "يجب أن تتكون كلمة السر على الأقل من {{PLURAL:$1|حرف واحد|حرفين|$1 حروف|$1 حرفا|$1 حرف}}.",
        "passwordtoolong": "كلمات السر لا يجب أن تكون أطول من  {{PLURAL:$1|1 حرف|$1 حروف}}.",
        "passwordtoopopular": "لا يمكن استخدام كلمات المرور المختارة بشكل عام; يُرجَى اختيار كلمة مرور يصعب تخمينها.",
+       "passwordinlargeblacklist": "كلمة المرور التي تم إدخالها موجودة في قائمة كلمات المرور شائعة الاستخدام; الرجاء اختيار كلمة مرور فريدة.",
        "password-name-match": "يجب أن تكون كلمة المرور مختلفة عن اسم المستخدم.",
        "password-login-forbidden": "تم منع استخدام اسم المستخدم هذا وكلمة السر.",
        "mailmypassword": "أعد تعيين كلمة السر",
        "botpasswords-label-needsreset": "(تحتاج كلمة المرور إلى إعادة الضبط)",
        "botpasswords-label-appid": "اسم البوت:",
        "botpasswords-label-create": "أنشأ",
-       "botpasswords-label-update": "حدث",
+       "botpasswords-label-update": "تحدÙ\8aث",
        "botpasswords-label-cancel": "ألغ",
        "botpasswords-label-delete": "احذف",
        "botpasswords-label-resetpassword": "أعد ضبط كلمة السر",
        "resettokens-no-tokens": "ما من مفاتيح للتغيير.",
        "resettokens-tokens": "مفاتيح:",
        "resettokens-token-label": "$1 (القيمة الحالية: $2)",
-       "resettokens-watchlist-token": "رمز تغذية الوب (آتوم/آس إس إس) [[Special:Watchlist|للتغيرات التي على قائمة مراقبتك]]",
+       "resettokens-watchlist-token": "رمز تغذية الويب (آتوم/آس إس إس) [[Special:Watchlist|للتغيرات التي على قائمة مراقبتك]]",
        "resettokens-done": "تغيير المفاتيح",
        "resettokens-resetbutton": "غير المفاتيح المختارة",
        "bold_sample": "نص غليظ",
        "previewconflict": "هذا العرض يوضح النص الموجود في صندوق التحرير العلوي والذي سيظهر إذا اخترت الحفظ.",
        "session_fail_preview": "'''عذرا! لم نتمكن من حفظ التعديلات التي قمت بها نتيجة لضياع بيانات هذه الجلسة.\nمن فضلك حاول مرة أخرى.\nفي حال استمرار المشكلة حاول أن تقوم [[Special:UserLogout|بالخروج]] ومن ثم الولوج مرة أخرى.''' و تاكد في  متصفحك من الكوكيز  الخاصة  بهذا الموقع.",
        "session_fail_preview_html": "'''عذرا! لم نستطع معالجة تعديلك بسبب فقدان بيانات الجلسة.'''\n\n''لأن {{SITENAME}} بها HTML الخام مفعلة، العرض المسبق مخفي كاحتياط ضد هجمات الجافا سكريبت.''\n\n'''إذا كانت هذه محاولة تعديل صادقة، من فضلك حاول مرة أخرى.\nإذا كانت مازالت لا تعمل، حاول [[Special:UserLogout|تسجيل الخروج]] ثم تسجيل الدخول مجددا.'''و تاكد في  متصفحك من الكوكيز  الخاصة  بهذا الموقع.",
-       "token_suffix_mismatch": "'''تعديلك تم رفضه لأن عميلك أخطأ في علامات الترقيم\nفي نص التعديل. تم رفض التعديل لمنع فساد نص المقالة.\nهذا يحدث أحيانا عندما تستخدم خدمة بروكسي مجهول معيبة مبنية على الوب.'''",
+       "token_suffix_mismatch": "<strong>تعديلك تم رفضه لأن عميلك أخطأ في علامات الترقيم في نص التعديل.</strong>\nتم رفض التعديل لمنع فساد نص المقالة.\nهذا يحدث أحيانا عندما تستخدم خدمة بروكسي مجهول معيبة مبنية على الويب.",
        "edit_form_incomplete": "'''بعض أجزاء من نموذج التعديل لم تصل إلى الخادم؛ تأكد من أن تعديلاتك لم تمس وحاول مجددا.'''",
        "editing": "تعديل $1",
        "creating": "إنشاء «$1»",
        "timezonelegend": "المنطقة الزمنية:",
        "localtime": "الوقت المحلي:",
        "timezoneuseserverdefault": "استخدام الويكي الافتراضي ($1)",
-       "timezoneuseoffset": "آخر (حدد الفرق)",
+       "timezoneuseoffset": "غير ذلك (حدد الإزاحة أدناه)",
+       "timezone-useoffset-placeholder": "مثال القيم: \"-07:00\" أو \"01:00\"",
        "servertime": "وقت الخادم:",
        "guesstimezone": "أدخل التوقيت من المتصفح",
        "timezoneregion-africa": "أفريقيا",
        "prefs-editor": "محرر",
        "prefs-preview": "عرض مسبق",
        "prefs-advancedrc": "خيارات متقدمة",
-       "prefs-opt-out": "إلغاء الاشتراك في التحسينات",
        "prefs-advancedrendering": "خيارات متقدمة",
        "prefs-advancedsearchoptions": "خيارات متقدمة",
        "prefs-advancedwatchlist": "خيارات متقدمة",
        "upload-tryagain-nostash": "ارفع الملف المعاد رفعه والوصف المعدل",
        "uploadnologin": "غير مسجل الدخول",
        "uploadnologintext": "يجب عليك $1 لترفع الملفات.",
-       "upload_directory_missing": "Ù\85جÙ\84د Ø§Ù\84رÙ\81ع ($1) Ù\85Ù\81Ù\82Ù\88د Ù\88Ù\84Ù\85 Ù\8aÙ\85Ù\83Ù\86 Ø¥Ù\86شاؤÙ\87 Ø¨Ù\88اسطة Ø®Ø§Ø¯Ù\88Ù\85 Ø§Ù\84Ù\88ب.",
-       "upload_directory_read_only": "Ù\85جÙ\84د Ø§Ù\84رÙ\81ع ($1) Ù\84ا Ù\8aÙ\85Ù\83Ù\86 Ø§Ù\84Ù\83تابة Ø¹Ù\84Ù\8aÙ\87 Ø¨Ù\88اسطة Ø®Ø§Ø¯Ù\88Ù\85 Ø§Ù\84Ù\88ب.",
+       "upload_directory_missing": "Ù\85جÙ\84د Ø§Ù\84رÙ\81ع ($1) Ù\85Ù\81Ù\82Ù\88د Ù\88Ù\84Ù\85 Ù\8aÙ\85Ù\83Ù\86 Ø¥Ù\86شاؤÙ\87 Ø¨Ù\88اسطة Ø®Ø§Ø¯Ù\85 Ø§Ù\84Ù\88Ù\8aب.",
+       "upload_directory_read_only": "Ù\85جÙ\84د Ø§Ù\84رÙ\81ع ($1) Ù\84ا Ù\8aÙ\85Ù\83Ù\86 Ø§Ù\84Ù\83تابة Ø¹Ù\84Ù\8aÙ\87 Ø¨Ù\88اسطة Ø®Ø§Ø¯Ù\85 Ø§Ù\84Ù\88Ù\8aب.",
        "uploaderror": "خطأ في الرفع",
        "upload-recreate-warning": "'''تحذير: سبق حذف أو نقل ملف بهذا الاسم.'''\n\nسجلا الحذف والنقل لهذه الصفحة معروضان هنا للتيسير:",
        "uploadtext": "استخدم الاستمارة بالأسفل لرفع الملفات.\nلرؤية أو البحث في الملفات المرفوعة سابقا، راجع [[Special:FileList|قائمة الملفات المرفوعة]]، عمليات الرفع (وإعادة الرفع) مسجلة في [[Special:Log/upload|سجل الرفع]] وعمليات الحذف في [[Special:Log/delete|سجل الحذف]].\n\nلإدراج صورة في صفحة، استخدم الوصلات في الصيغ التالية:\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.jpg]]</nowiki></code>''' لاستخدام النسخة الكاملة لملف\n* '''<code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:File.png|200px|thumb|left|نص بديل]]</nowiki></code>''' لاستخدام صورة عرضها 200 بكسل في صندوق في الجانب الأيسر مع 'نص بديل' كوصف\n* '''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' للوصل للملف مباشرة بدون عرض الملف.",
        "copyuploaddisabled": "الرفع من مسار معطل.",
        "uploaddisabledtext": "رفع الملفات معطل.",
        "php-uploaddisabledtext": "رفع ملفات PHP معطل. من فضلك تحقق من إعدادات رفع الملفات.",
-       "uploadscripted": "هذا الملف يضم كود HTML أو كود آخر يمكن أن يفسره متصفح الوب بطريقة خاطئة.",
+       "uploadscripted": "هذا الملف يضم كود HTML أو كود آخر يمكن أن يفسره متصفح الويب بطريقة خاطئة.",
        "upload-scripted-pi-callback": "لا يمكن رفع ملف يحتوي على تعليمة معالجة XML-stylesheet",
        "upload-scripted-dtd": "لا يمكن رفع ملفات SVG التي تحتوي على إعلان DTD غير قياسي.",
        "uploaded-script-svg": "تم العثور على عنصر سكريبت \"$1\" في ملف الSVG المرفوع.",
        "unlockdbsuccesssub": "تم إزالة قفل قاعدة البيانات",
        "lockdbsuccesstext": "لقد أغلقت قاعدة البيانات.<br />\nتذكر أن [[Special:UnlockDB|تزيل الغلق]] بعد اكتمال أعمال الصيانة.",
        "unlockdbsuccesstext": "تم إعادة فتح قاعدة البيانات",
-       "lockfilenotwritable": "ملف غلق قاعدة البيانات لا يمكن الكتابة عليه.\nلغلق قاعدة البيانات أو إزالة الغلق يجب أن يكون هذا الملف قابلاً للكتابة من قبل خادوم الويب.",
+       "lockfilenotwritable": "ملف غلق قاعدة البيانات لا يمكن الكتابة عليه.\nلغلق قاعدة البيانات أو إزالة الغلق يجب أن يكون هذا الملف قابلا للكتابة من قبل خادم الويب.",
        "databaselocked": "قاعدة البيانات مقفلة بالفعل.",
        "databasenotlocked": "قاعدة البيانات ليست مغلقة.",
        "lockedbyandtime": "(من $1 على $2 في $3 )",
        "filedelete-missing": "الملف \"$1\" لم يمكن حذفه، لأنه غير موجود.",
        "filedelete-old-unregistered": "مراجعة الملف المحددة \"$1\" ليست في قاعدة البيانات.",
        "filedelete-current-unregistered": "الملف المحدد \"$1\" ليس في قاعدة البيانات.",
-       "filedelete-archive-read-only": "Ù\85جÙ\84د Ø§Ù\84أرشÙ\8aÙ\81 \"$1\" Ù\84ا Ù\8aÙ\85Ù\83Ù\86 Ø§Ù\84Ù\83تابة Ø¹Ù\84Ù\8aÙ\87 Ø¨Ù\88اسطة Ø®Ø§Ø¯Ù\88Ù\85 Ø§Ù\84Ù\88ب.",
+       "filedelete-archive-read-only": "Ù\85جÙ\84د Ø§Ù\84أرشÙ\8aÙ\81 \"$1\" Ù\84ا Ù\8aÙ\85Ù\83Ù\86 Ø§Ù\84Ù\83تابة Ø¹Ù\84Ù\8aÙ\87 Ø¨Ù\88اسطة Ø®Ø§Ø¯Ù\85 Ø§Ù\84Ù\88Ù\8aب.",
        "previousdiff": "→ التعديل السابق",
        "nextdiff": "التعديل اللاحق ←",
        "mediawarning": "'''تحذير''': قد يحتوي نوع هذا الملف على كود خبيث، يمكن عند تشغيله السيطرة على نظامك.",
        "tags-create-already-exists": "الوسم \"$1\" موجود بالفعل.",
        "tags-create-warnings-above": "{{PLURAL:$2|التحذير التالي حدث|التحذيرات التالية حدثت}} عند محاولة إنشاء الوسم \"$1\":",
        "tags-create-warnings-below": "هل تود متابعة إنشاء الوسم؟",
-       "tags-delete-title": "احذÙ\81 Ø§Ù\84Ù\88سÙ\85",
+       "tags-delete-title": "حذف الوسم",
        "tags-delete-explanation-initial": "أنت على وشك حذف الوسم \"$1\" من قاعدة البيانات.",
        "tags-delete-explanation-in-use": "ستتم إزالته من {{PLURAL:$2|$2 مراجعة او مدخلة سجل|كل $2 مراجعات و/أو مدخلات سجل}} الذي هو مطبق عليهم حاليا.",
        "tags-delete-explanation-warning": "هذا الفعل <strong>غير رجعي</strong> و <strong>لا يمكن التراجع عنه</strong>، ولا حتى بواسطة إداريي قاعدة البيانات. كن متاكدا من أن هذا هو الوسم الذي تريد حذفه.",
        "permanentlink-submit": "الذهاب إلى المراجعة",
        "dberr-problems": "عذرا! هذا الموقع يعاني من صعوبات تقنية.",
        "dberr-again": "جرب الانتظار بضع دقائق وإعادة التحميل.",
-       "dberr-info": "(لا يمكن الوصول إلى خادوم قاعدة البيانات: $1)",
-       "dberr-info-hidden": "(لا يمكن الاتصال بخادم قاعدة البيانات)",
+       "dberr-info": "(لا يمكن الوصول إلى قاعدة البيانات: $1)",
+       "dberr-info-hidden": "(لا يمكن الاتصال بقاعدة البيانات)",
        "htmlform-invalid-input": "توجد مشكلات ضمن بعض من مدخلاتك",
        "htmlform-select-badoption": "القيمة التي تم تحديدها غير صالحة كخيار.",
        "htmlform-int-invalid": "القيمة التي حددتها ليست عددا صحيحا.",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "لا يمكن أن تتطابق كلمة المرور مع كلمات المرور المدرجة على القائمة السوداء تحديدا",
        "passwordpolicies-policy-maximalpasswordlength": "يجب أن يكون طول كلمة المرور أقل من $1 {{PLURAL:$1|حرف|أحرف}}",
        "passwordpolicies-policy-passwordcannotbepopular": "لا يمكن أن تكون كلمة المرور {{PLURAL:$1|كلمة المرور الشائعة|في قائمة كلمات المرور الشائعة الـ$1}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "لا يمكن أن تكون كلمة المرور في قائمة كلمات المرور الـ100.000 الأكثر استخداما.",
        "easydeflate-invaliddeflate": "المحتوى المقدم لا يتم تفريغه بشكل صحيح",
        "unprotected-js": "لأسباب تتعلق بالأمان; لا يمكن تحميل جافا سكريبت من الصفحات غير المحمية; الرجاء إنشاء جافا سكريبت فقط في نطاق ميدياويكي: أو كصفحة فرعية للمستخدم"
 }
index cb249c0..177da10 100644 (file)
        "resetpass_submit": "اظبط الباسورد و ادخل",
        "changepassword-success": "الباسورد بتاعتك اتغيرت بنجاح!",
        "changepassword-throttled": "انت عملت  محاولات لوجين كتيره  ع الحساب ده.\nمن فضلك استنى $1 قبل المحاولة مرة تانيه.",
+       "botpasswords-label-update": "تحديث",
        "resetpass_forbidden": "مش ممكن تغيير الباسورد",
        "resetpass-no-info": "لازم تسجل دخولك علشان تقدر توصل للصفحة دى على طول.",
        "resetpass-submit-loggedin": "غير الباسورد",
index b3fd36a..2eb3003 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Vista previa",
        "prefs-advancedrc": "Opciones avanzaes",
-       "prefs-opt-out": "Borrase de los ameyoramientos",
        "prefs-advancedrendering": "Opciones avanzaes",
        "prefs-advancedsearchoptions": "Opciones avanzaes",
        "prefs-advancedwatchlist": "Opciones avanzaes",
index 9809108..65348c0 100644 (file)
        "explainconflict": "سیز صحیفه‌‌نی رئداکته باشقا بیری ده ديَیشیکلیک ائتدی. \nيوخاریداکی يازی صحیفه‌‌نین بو آنکی حالینی گؤستریر. \nسیزین ديَیشیکلیکلری‌نین آلتا گؤستریلمیشدیر. سون دئغیشیکلئرینیزی يازی‌نین ایچینه داخیل ائتمه‌يینیز لازیم اولاجاق. \n«$1» ائ باسدیغینیزداع' ' يالنیزعع' يوخاریداکی يازی يازیلاجاق.",
        "yourtext": "یازینیز",
        "storedversion": "قئید ائدیلمیش نوسخه",
-       "editingold": "'دیققت! سیز بو صحیفه‌نین کؤهنه نوسخه سین دییشدیر ائدیرسینیز. مقالنی یادداشدا ساخلایاجاغینیز حالدا بو نوسخه سونرا ائدیلمیش هر بیر دییشیک‌لیک ایتیریله‌جک.'",
+       "editingold": "<strong>تذکور: سیز بو صفحه‌نین کؤهنه نوسخه‌سینی دییشدیریرسینیز. ذخیره ائدیرسز، بو نوسخه‌دن سونرا ائدیلمیش هر بیر دییشیک‌لیک ایتیریله‌جکدیر.'",
        "yourdiff": "فرق‌لر",
        "copyrightwarning": "خاهیش اولونور دقته آلاسینیز کی، {{SITENAME}}داکی بوتون فالیت‌لرینیز $2 لیسئنزیاسینا تابع اولدوغو حساب ائدیلیر (تفرروات اوچون باخ: $1). اگر یازدیق‌لارینیزین اساس‌لی شکیلده رئداکته ائدیلمه‌سینی و ایستنیلدیگی واخت باشقا یئره اؤتورولمه‌سینی ایستمیرسینیزسه، یازی‌لارینیزی بورادا درج ائتمیین.\n<br />\nسیز عینی زاماندا سؤز وئریرسینیز کی، بو یازی‌لاری سیز اؤزونوز یازمیسینیز و یا اونلاری هامییا آچیق موهیت‌دن یا دا بونا بنزر منبع‌دن کؤچورموسونوز.\n\n----\n\n</div> ایستیلئ=\"فونت-weight: بولد؛ فونت-سیزئ: 110%؛ جولور:رئد؛\">موللیف حقوق‌لاری ایله قورونموش هئچ بیر ایشی ایجازه‌سیز درج ائتمیین!</div>",
        "copyrightwarning2": "خاهیش ائدیریک، {{SITENAME}} سایتینا ائده‌جه‌یم بوتون روسوم دیگر عضو‌لر طرفین‌دن دوزئنلئنئبیلئجئغینی، دییش‌دیریله و یا سیلینئبیلئجئغینی خاتیرلایین. یازی‌لارینین مئرهامئتسیزجئ دئغیشتیریلی بیلمسینه راضی‌لیق گؤسترمیرسه بورا ایشتیراک ائتمیین. <br />\nآیریجا بو علاوه یازینی سیزین یازدیغینیزدان یا دا سربست کوپیالاما ایجازه‌سی وئرن بیر قایناق‌دان کوپیالادیغینیزی بیزه اؤهده‌لرینه ائتمکدسینیز (دئتال‌لار اوچون ایستیناد: $1).",
        "parser-unstrip-loop-warning": "تکرارلاما دونمه سی قبول ائدیلدی",
        "unstrip-depth-warning": "حداکثر ارجاع دستور دا unstrip تجاوز گئچیب دیر ($1)",
        "converter-manual-rule-error": "خطا ال مبدیلی قانون لاریندا",
-       "undo-success": "بو دَییشیک‌لیک گئری آلینا بیلر. لطفاً آشاغی‌داکی موقاییسه ائتمیی نظارت ائدین، حقیقتن بو دییشیک‌لیگی ائتمک ایستدیگینیزدن امین اولون و صحیفنی یازا‌راق بیر اوولکی دییشیک‌لیگی گئرییه آلین.",
+       "undo-success": "بو دَییشیک‌لیک قایتاریلا بیلر. لوطفاً آشاغی‌داکی موقایسه‌نی یوْخلاییب، دوغرودان بو دییشیک‌لیگی ائتمک ایستدیگینیزدن آرخایین اولون و صفحه‌نی ذخیره ائتمکله قاباقکی دییشیکلیگی قایتارین.",
        "undo-failure": "دییشیک‌لیک‌لرین توققوشماسی نتیجه‌سینده گئرییه قایتارما ایشی اوغورسوز اولدو.",
        "undo-norev": "دوزلیش‌لر گئری قایتاریلا بیلینمیر، چونکی اونلار یا مؤوجود دئییل، یا دا سیلینیب.",
        "undo-nochange": "نظره گلیر دَییشدیرمه قاباغجادان قایتاریلیب.",
        "showhideselectedversions": "سئچیلمیش نوسخه‌لری گؤستر/گیزلد",
        "editundo": "قایتار",
        "diff-empty": "فرقیسیز",
-       "diff-multi-sameuser": "(همن کی ایشلدیچی طرفیندن ائدیلمیش  {{PLURAL:$1|بیر دَییشلیک|$1 بیر نئچه دَییشلیک}} گوستریلمیر)",
+       "diff-multi-sameuser": "(بۇ ایشلدنین طرفیندن ائدیلمیش  {{PLURAL:$1|بیر دَییشیکلیک|$1 بیر نئچه دَییشیکلیک}} گؤستریلمیر)",
        "diff-multi-otherusers": "({{PLURAL:$1|۱ میانی نوسخه لر|$1 میانی نوسخه لر}} دَییک اولونموش {{PLURAL:$2|۱ ایشلدچی|$2 ایشلدچی}}طرفیندن گوستریلمیر)",
        "diff-multi-manyusers": "{{PLURAL:$2|بیر|$2}}-دن چوخ ایستیفاده‌چی یارادان {{PLURAL:$1|بیر|$1}} نوسخه، گؤستریلمه‌ییب‌دیر",
        "difference-missing-revision": "بو فرقین ($1) {{PLURAL:$2|بیر|$2}} نوسخه‌سی تاپیلانمادی.\n\nعموماً بو خطا، سیلینن بیر صحیفه‌یه واختی گئچمیش بیر فرق باغلانتی‌سیلا گلمک ایله آرا گلر.\n[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}سیلمک سیاهی‌سی]ندا باشقا بیلگیلر اولا بیلر.",
        "rcfilters-other-review-tools": "داها یوخلاما آلتلری",
        "rcfilters-group-results-by-page": "دییشیکلیکلری صفحه‌لرینه گؤره سیرالا",
        "rcfilters-activefilters": "چالیشقان فیلترلر",
+       "rcfilters-activefilters-hide": "گیزلت",
+       "rcfilters-advancedfilters": "گئنیش فیلترلر",
        "rcfilters-limit-title": "دَییشدیرمه سایی‌سی",
        "rcfilters-date-popup-title": "آختاریش چاغی",
        "rcfilters-days-title": "سوْن گۆنلر",
        "rcfilters-quickfilters": "ذخیره اولونموش فیلترلر",
        "rcfilters-quickfilters-placeholder-title": "هله‌لیک هئچ بیر فیلتر ذخیره اوْلونماییبدیر",
        "rcfilters-savedqueries-defaultlabel": "ذخیره اوْلونموش فیلترلر",
+       "rcfilters-savedqueries-setdefault": "دفالت حالتده تنظیمله",
+       "rcfilters-savedqueries-new-name-placeholder": "فیلتر هدفینی آچیقلا",
+       "rcfilters-savedqueries-apply-label": "فیلتر یارات",
        "rcfilters-clear-all-filters": "بۆتون فیلترلری سیل",
        "rcfilters-show-new-changes": "اَن سون دَییشیکلیکلره باخ",
        "rcfilters-search-placeholder": "سوْن دییشیکلیکلری فیلترله (منودان سئچین یوْخسا فیلتر آدینی آختارین)",
        "rcfilters-filterlist-feedbacklink": "بیزه بو فیلترلره گؤره دوشوندوگونوزو بیلیندیرین!",
        "rcfilters-highlightbutton-title": "نتیجه‌لری هایلایتلا",
        "rcfilters-filtergroup-authorship": "دییشدیرن",
+       "rcfilters-filtergroup-userExpLevel": "ایشلدن آدیازدیرما و تجروبه‌سی",
+       "rcfilters-filter-user-experience-level-registered-label": "آدیازدیریلمیش",
+       "rcfilters-filter-user-experience-level-unregistered-label": "آدیازدیریلمامیش",
+       "rcfilters-filter-user-experience-level-learner-label": "اؤیرننلر",
+       "rcfilters-filter-user-experience-level-experienced-label": "تجروبه‌لی ایشلدنلر",
        "rcfilters-filtergroup-automated": "اوْتوماتیک دییشدیرمه‌لر",
+       "rcfilters-filter-bots-description": "اوْتوماتیک آلتلر الی ایله دییشدیرمه‌لر",
        "rcfilters-filter-humans-label": "اینسان (غئیر روْبات)",
        "rcfilters-filter-humans-description": "اینسان اَلی ایله دییشدیرمه‌لر",
+       "rcfilters-filtergroup-reviewstatus": "یوخلاما وضعیتی",
+       "rcfilters-filter-minor-label": "کیچیک دَییشدیرمه‌لر",
+       "rcfilters-filter-major-label": "کیچیک اوْلمایان دییشدیرمه‌لر",
+       "rcfilters-filtergroup-watchlist": "ایزلنمیش صفحه‌لر",
+       "rcfilters-filter-watchlist-watched-label": "ایزلنمیش",
        "rcfilters-filtergroup-changetype": "دَییشیکلیک نوعو",
        "rcfilters-filter-pageedits-label": "صفحه دییشدیرمه‌لری",
        "rcfilters-filter-newpages-label": "صفحه یاراتما",
        "rcfilters-filter-logactions-label": "چالیشمالار ژورنالی",
        "rcfilters-filtergroup-lastRevision": "سوْن نوسخه‌لر",
        "rcfilters-filter-lastrevision-label": "سوْن نوسخه",
+       "rcfilters-filter-previousrevision-label": "سوْن نوسخه اولمایان",
        "rcfilters-exclude-button-off": "سئچیلمیشلرین چیخاریلماسی",
        "rcfilters-exclude-button-on": "سئچیلمیشلرین چیخاریلماسی",
        "rcfilters-view-tags": "اتیکتلنمیش دییشدیرمه‌لر",
        "trackingcategories-disabled": "بؤلمه باغلانیب‌دیر.",
        "mailnologin": "گؤندرمه آدرسی یوخدور",
        "mailnologintext": "باشقا ایستیفاده‌چیلره ایمیل گؤندرک اوچون، [[Special:UserLogin|گیریش]] ائدیب و [[Special:Preferences|ترجیحلر]]ینیزده گئچرلی ایمیل آدرسی وئرمه‌لیسینیز.",
-       "emailuser": "بÙ\88 Ø§Û\8cستÛ\8cÙ\81ادÙ\87â\80\8cÚ\86Û\8câ\80\8cÛ\8cÙ\87 Ø§Û\8cÙ\85یل گؤندر",
-       "emailuser-title-target": "بÙ\88 {{GENDER:$1|اÛ\8cستÛ\8cÙ\81ادÙ\87â\80\8cÚ\86Û\8c}}â\80\8cÛ\8cÙ\87 Ø§Û\8cÙ\85یل گؤندر",
+       "emailuser": "بÙ\88 Ø§Û\8cØ´Ù\84دÙ\86Ù\87 Ø§Û\8cÙ\85ئیل گؤندر",
+       "emailuser-title-target": "بÙ\88 {{GENDER:$1|اÛ\8cØ´Ù\84دÙ\86Ù\87}}â\80\8c Ø§Û\8cÙ\85ئیل گؤندر",
        "emailuser-title-notarget": "ایستیفاده‌چی‌یه ایمیل گؤندر",
        "emailpagetext": "آشاغیداکی فورمدان، بو {{GENDER:$1|ایستیفاده‌چی}}‌یه ایمئیل گؤندرمک اۆچون ایستیفاده ائده بیلرسینیز.\n[[Special:Preferences|اؤز ترجیحلرینیز]]ده وئرن ایمئیل آدرسی، بو ایمئیلین \"From\" یئرینده گؤستریله‌رک ایمئیلی آلان سیزه موستقیم جاواب گؤندره بیلر.",
        "defemailsubject": "«$1» آدلی ایستیفاده‌چی‌دن، {{SITENAME}} ایمیلی",
        "tag-filter-submit": "سۆزگَج",
        "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|اِتیکِت|اِتیکِتلر}}]]: $2",
        "tag-mw-new-redirect": "یئنی یوْللاندیرما",
+       "tag-mw-removed-redirect": "یوْللاندیرما سیلیندی",
        "tag-mw-blank": "بوْشالتما",
        "tags-title": "اِتیکتلر",
        "tags-intro": "بو صفحه، نرم افزار دَییشدیرمه‌لری علامتله‌ین اِتیکِتلری و اونلارین معنالارینی گؤستریر.",
index 3394558..124d23b 100644 (file)
        "timezonelegend": "Часавы пояс:",
        "localtime": "Мясцовы час:",
        "timezoneuseserverdefault": "Выкарыстоўваць стандартныя налады {{GRAMMAR:родны|{{SITENAME}}}} ($1)",
-       "timezoneuseoffset": "Іншы (пазначце розьніцу ў часе)",
+       "timezoneuseoffset": "Іншы (пазначце ніжэй розьніцу ў часе)",
+       "timezone-useoffset-placeholder": "Напрыклад: «-07:00» ці «01:00»",
        "servertime": "Час на сэрвэры:",
        "guesstimezone": "Запоўніць з браўзэра",
        "timezoneregion-africa": "Афрыка",
        "prefs-editor": "Рэдактар",
        "prefs-preview": "Папярэдні прагляд",
        "prefs-advancedrc": "Дадатковыя налады",
-       "prefs-opt-out": "Адмовіцца ад паляпшэньняў",
        "prefs-advancedrendering": "Дадатковыя налады",
        "prefs-advancedsearchoptions": "Дадатковыя налады",
        "prefs-advancedwatchlist": "Дадатковыя налады",
        "sharedupload-desc-edit": "Гэты файл паходзіць з $1 і можа выкарыстоўвацца іншымі праектамі.\nКалі спатрэбіцца, вы можаце зьмяніць апісаньне файлу на [$2 адпаведнай старонцы].",
        "sharedupload-desc-create": "Гэты файл паходзіць з $1 і можа выкарыстоўвацца іншымі праектамі.\nКалі спатрэбіцца, вы можаце зьмяніць апісаньне на [$2 адпаведнай старонцы].",
        "filepage-nofile": "Файл з гэтай назвай не існуе.",
-       "filepage-nofile-link": "Файл з гэтай назвай не існуе, але Вы можаце [$1 загрузіць яго].",
+       "filepage-nofile-link": "Файл з такой назвай не існуе, але вы можаце [$1 загрузіць яго].",
        "uploadnewversion-linktext": "Загрузіць новую вэрсію гэтага файла",
-       "shared-repo-from": "$1",
+       "shared-repo-from": "з $1",
        "shared-repo": "агульнага сховішча",
        "shared-repo-name-wikimediacommons": "Вікісховішча",
        "upload-disallowed-here": "Вы ня можаце перазапісаць гэты файл.",
        "filerevert": "Вярнуць $1",
-       "filerevert-legend": "Вярнуць папярэднюю вэрсію файла",
-       "filerevert-intro": "Вы вяртаеце '''[[Media:$1|$1]]''' да [вэрсіі $4 ад $3, $2].",
+       "filerevert-legend": "Вярнуць папярэднюю вэрсію файлу",
+       "filerevert-intro": "Вы вяртаеце файл <strong>[[Media:$1|$1]]</strong> да [$4 вэрсіі ад $3, $2].",
        "filerevert-comment": "Прычына:",
        "filerevert-defaultcomment": "Вернутая вэрсія ад $2 $1 ($3)",
        "filerevert-submit": "Вярнуць",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль ня можа супадаць з паролямі з чорнага сьпісу",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль мусіць быць даўжынёй менш за $1 {{PLURAL:$1|сымбаль|сымбалі|сымбаляў}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Пароль ня можа {{PLURAL:$1|супадаць з самым папулярным паролем|быць зь сьпісу $1 папулярных пароляў}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль ня можа быць зь сьпісу 100 000 найчасьцей ужываных пароляў.",
        "easydeflate-invaliddeflate": "Пададзены зьмест ня сьціснуты адпаведным чынам",
        "unprotected-js": "З прычынаў бясьпекі JavaScript ня можа быць загружаны зь неабароненых сайтаў. Калі ласка, стварайце javascript выключна ў прасторы назваў MediaWiki: ці як падстаронку ўдзельніка"
 }
index 6edce44..de62590 100644 (file)
        "view": "Паказ",
        "view-foreign": "Глядзець на $1",
        "edit": "Правіць",
-       "edit-local": "Правіць тутэйшае апісанне",
+       "edit-local": "Правіць лакальнае апісанне",
        "create": "Стварыць",
-       "create-local": "Дадаць тутэйшае апісанне",
+       "create-local": "Дадаць лакальнае апісанне",
        "delete": "Выдаліць",
        "undelete_short": "Аднавіць {{PLURAL:$1|адну праўку|$1 правак}}",
        "viewdeleted_short": "Паказаць {{PLURAL:$1|адну сцёртую праўку|$1 сцёртыя праўкі}}",
        "search-showingresults": "{{PLURAL:$4|Вынік <strong>$1</strong> з <strong>$3</strong>|Вынікі <strong>$1 — $2</strong> з <strong>$3</strong>}}",
        "search-nonefound": "Нічога не было знойдзена.",
        "search-nonefound-thiswiki": "Няма вынікаў, якія б адпавядалі такому запыту на гэтым сайце.",
-       "powersearch-legend": "Падрабязны пошук",
+       "powersearch-legend": "Пашыраны пошук",
        "powersearch-ns": "Шукаць у прасторах назваў:",
        "powersearch-togglelabel": "Пазначыць:",
        "powersearch-toggleall": "Усе",
        "prefs-editor": "Рэдактар",
        "prefs-preview": "Перадпаказ",
        "prefs-advancedrc": "Пашыраныя настройкі",
-       "prefs-opt-out": "Адмова ад паляпшэнняў",
        "prefs-advancedrendering": "Пашыраныя настройкі",
        "prefs-advancedsearchoptions": "Пашыраныя настройкі",
        "prefs-advancedwatchlist": "Пашыраныя настройкі",
index a67d212..2cc7e2e 100644 (file)
        "prefs-editor": "Редактор",
        "prefs-preview": "Преглед",
        "prefs-advancedrc": "Разширени настройки",
-       "prefs-opt-out": "Отписване от подобренията",
        "prefs-advancedrendering": "Разширени настройки",
        "prefs-advancedsearchoptions": "Разширени настройки",
        "prefs-advancedwatchlist": "Разширени настройки",
        "right-deletedtext": "Преглед на изтрития текст и промените между изтритите версии",
        "right-browsearchive": "Търсене на изтрити страници",
        "right-undelete": "Възстановяване на страници",
-       "right-suppressrevision": "Преглед и възстановяване на версии, скрити от администраторите",
+       "right-suppressrevision": "Преглед, скриване и възстановяване на отделни версии на страници от който и да е потребител",
        "right-viewsuppressed": "Преглеждане на версии, скрити от който и да е потребител",
        "right-suppressionlog": "Преглеждане на скритите дневници",
        "right-block": "Спиране на достъпа до редактиране",
        "rcfilters-watchlist-markseen-button": "Отбелязване на всички промени като прегледани",
        "rcfilters-watchlist-edit-watchlist-button": "Редактиране на списъка за наблюдение",
        "rcfilters-watchlist-showupdated": "Промени по страници, които не сте посетили откакто са внесени промените, са в <strong>получер</strong>, с удебелени маркери.",
-       "rcfilters-preference-label": "СкÑ\80иване Ð½Ð° Ð¿Ð¾Ð´Ð¾Ð±Ñ\80енаÑ\82а Ð²ÐµÑ\80Ñ\81иÑ\8f Ð½Ð° Ð\9fоÑ\81ледни Ð¿Ñ\80омени",
+       "rcfilters-preference-label": "Ð\98зползване Ð½Ð° Ð¸Ð½Ñ\82еÑ\80Ñ\84ейÑ\81 Ð±ÐµÐ· JavaScript",
        "rcfilters-preference-help": "Отменя преработката на интерфейса направена през 2017 година, както и всички инструменти добавени от тогава до сега.",
-       "rcfilters-watchlist-preference-label": "СкÑ\80иване Ð½Ð° Ð¿Ð¾Ð´Ð¾Ð±Ñ\80енаÑ\82а Ð²ÐµÑ\80Ñ\81иÑ\8f Ð½Ð° Ð¡Ð¿Ð¸Ñ\81Ñ\8aк Ð·Ð° Ð½Ð°Ð±Ð»Ñ\8eдение",
+       "rcfilters-watchlist-preference-label": "Ð\98зползване Ð½Ð° Ð¸Ð½Ñ\82еÑ\80Ñ\84ейÑ\81 Ð±ÐµÐ· JavaScript",
        "rcfilters-watchlist-preference-help": "Отменя преработката на интерфейса направена през 2017 година, както и всички инструменти добавени от тогава до сега.",
        "rcfilters-filter-showlinkedfrom-label": "Показване на промени на страници, към които има връзка от",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Страници, към които има връзка от</strong> избраната страница",
index 777b19a..c20b793 100644 (file)
        "passwordtooshort": "পাসওয়ার্ড কমপক্ষে {{PLURAL:$1|১ অক্ষরের|$1 অক্ষরের}} হতে হবে।",
        "passwordtoolong": "পাসওয়ার্ড {{PLURAL:$1|১|$1}} অক্ষরের চেয়ে দীর্ঘ হতে পারবে না।",
        "passwordtoopopular": "সাধারণভাবে নির্বাচিত পাসওয়ার্ড ব্যবহার করা যাবে না। দয়া করে এমন একটি পাসওয়ার্ড নির্বাচন করুন যা অনুমান করা আরও কঠিন।",
+       "passwordinlargeblacklist": "লিখিত পাসওয়ার্ডটি খুব সাধারণভাবে ব্যবহৃত পাসওয়ার্ডের তালিকায় থাকা একটি পাসওয়ার্ড। দয়া করে একটি আরো শক্তিশালী পাসওয়ার্ড নির্বাচন করুন।",
        "password-name-match": "আপনার পাসওয়ার্ড আপনার ব্যবহারকারী নাম থেকে আলাদা হতে হবে।",
        "password-login-forbidden": "এই ব্যবহারকারীর নাম এবং পাসওয়ার্ডটি ব্যবহার নিষিদ্ধ করা হয়েছে।",
        "mailmypassword": "পাসওয়ার্ড পুনঃস্থাপন",
        "prefs-editor": "সম্পাদক",
        "prefs-preview": "প্রাকদর্শন",
        "prefs-advancedrc": "উচ্চতর পছন্দগুলি",
-       "prefs-opt-out": "উন্নতি অনির্বাচন",
        "prefs-advancedrendering": "উচ্চতর বিকল্পগুলি",
        "prefs-advancedsearchoptions": "উচ্চতর পছন্দগুলি",
        "prefs-advancedwatchlist": "উচ্চতর বিকল্পগুলি",
        "prefs-displayrc": "প্রদর্শনীর পছন্দগুলি",
        "prefs-displaywatchlist": "প্রদর্শনী অপশন",
        "prefs-changesrc": "পরিবর্তন প্রদর্শন",
+       "prefs-changeswatchlist": "পরিবর্তন প্রদর্শন",
        "prefs-pageswatchlist": "নজরে রাখা পাতা",
        "prefs-tokenwatchlist": "টোকেন",
        "prefs-diffs": "পার্থক্য",
        "rcfilters-preference-label": "জাভাস্ক্রিপ্টহীন ইন্টারফেস ব্যবহার করুন",
        "rcfilters-preference-help": "ছাঁকনিগুলি বা আলোকপাতকরণ কার্যকারিতা ছাড়া সাম্প্রতিক পরিবর্তন লোড করে",
        "rcfilters-watchlist-preference-label": "জাভাস্ক্রিপ্টহীন ইন্টারফেস ব্যবহার করুন",
+       "rcfilters-watchlist-preference-help": "ছাঁকনি বা আলোকপাতকরণ বৈশিষ্ট্য ছাড়া নজরতালিকা লোড করে।",
        "rcfilters-target-page-placeholder": "একটি পাতার নাম (বা বিষয়শ্রেণী) লিখুন",
        "rcnotefrom": "<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)।",
        "rclistfromreset": "তারিখ নির্বাচন পুনঃস্থাপন করুন",
        "move-watch": "এই পাতাটি নজরে রাখুন",
        "movepagebtn": "পাতা স্থানান্তর করুন",
        "pagemovedsub": "সরিয়ে নেওয়া হয়েছে",
+       "cannotmove": "নিন্মলিখিত {{PLURAL:$1|কারণে}}, পাতাটি স্থানান্তর করা যায়নি:",
        "movepage-moved": "'''\"$1\"-কে \"$2\" শিরোনামে স্থানান্তর করা হয়েছে'''",
        "movepage-moved-redirect": "একটি পুনর্নির্দেশনা তৈরি হয়েছে।",
        "movepage-moved-noredirect": "পুনর্নির্দেশ তৈরীতে বাধা দেয়া হয়েছে।",
        "passwordpolicies-policy-passwordcannotmatchusername": "পাসওয়ার্ড ব্যবহারকারী নামের মত একই হতে পারে না",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "পাসওয়ার্ড বিশেষত কালো তালিকাভুক্ত পাসওয়ার্ডের সাথে মিলতে পারবে না",
        "passwordpolicies-policy-maximalpasswordlength": "পাসওয়ার্ড $1 {{PLURAL:$1|অক্ষরের}} চেয়ে কম দীর্ঘ হতে হবে",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "পাসওয়ার্ড ১,০০,০০০ সর্বাধিক ব্যবহৃত পাসওয়ার্ডের তালিকায় থাকতে পারবে না।",
        "unprotected-js": "নিরাপত্তার কারণে জাভাস্ক্রিপ্ট অনিরাপদ পৃষ্ঠা থেকে লোড করা যাবে না। শুধুমাত্র মিডিয়াউইকি: নামস্থান বা ব্যবহারকারী উপপাতায় জাভাস্ক্রিপ্ট তৈরি করুন"
 }
index b02033e..806cdb0 100644 (file)
        "prefs-editor": "Aozer",
        "prefs-preview": "Rakwelet",
        "prefs-advancedrc": "Dibarzhioù araokaet",
-       "prefs-opt-out": "Nac'hañ ar c'hemmoù",
        "prefs-advancedrendering": "Dibarzhioù araokaet",
        "prefs-advancedsearchoptions": "Dibarzhioù araokaet",
        "prefs-advancedwatchlist": "Dibarzhioù araokaet",
index 5cc04b5..50f139e 100644 (file)
        "prefs-editor": "Uređivač",
        "prefs-preview": "Pregled",
        "prefs-advancedrc": "Napredne opcije",
-       "prefs-opt-out": "Isključivanje poboljšanja",
        "prefs-advancedrendering": "Napredne opcije",
        "prefs-advancedsearchoptions": "Napredne opcije",
        "prefs-advancedwatchlist": "Napredne opcije",
index 146a029..d2c7d60 100644 (file)
        "prefs-editor": "Edició",
        "prefs-preview": "Previsualització",
        "prefs-advancedrc": "Opcions avançades",
-       "prefs-opt-out": "Renuncia a les millores",
        "prefs-advancedrendering": "Opcions avançades",
        "prefs-advancedsearchoptions": "Opcions avançades",
        "prefs-advancedwatchlist": "Opcions avançades",
        "specialpage-securitylevel-not-allowed-title": "No permès",
        "specialpage-securitylevel-not-allowed": "Ho sentim, no podeu utilitzar la pàgina perquè no es pot verificar la vostra identitat.",
        "authpage-cannot-login": "No s'ha pogut iniciar la sessió.",
-       "authpage-cannot-login-continue": "No es pot continuar amb l'inicio de sessió. Probablement la vostra sessió ha expirat.",
+       "authpage-cannot-login-continue": "No es pot continuar amb l'inici de sessió. Probablement la vostra sessió ha expirat.",
        "authpage-cannot-create": "No s'ha pogut iniciar la creació del compte.",
        "authpage-cannot-create-continue": "No es pot prosseguir la creació del compte. Probablement la vostra sessió ha expirat.",
        "authpage-cannot-link": "No s'ha pogut iniciar l'enllaç del compte.",
index 6394cc7..eeaf3db 100644 (file)
@@ -11,7 +11,8 @@
                        "Kaganer",
                        "Исмаил Садуев",
                        "Macofe",
-                       "Nemo bis"
+                       "Nemo bis",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "КӀел сиз хьакха хьажорган:",
        "prefs-editor": "Тадар",
        "prefs-preview": "Хьалххе хьажар",
        "prefs-advancedrc": "Кхин гӀирс нисбар",
-       "prefs-opt-out": "Дика кечъяр цаэшар",
        "prefs-advancedrendering": "Кхин гӀирс нисбар",
        "prefs-advancedsearchoptions": "Кхин гӀирс нисбар",
        "prefs-advancedwatchlist": "Кхин гӀирс нисбар",
        "right-editsemiprotected": "«{{int:protect-level-autoconfirmed}}» бахьанца ларйина агӀонаш нисъяр",
        "right-editinterface": "лелош йолу интерфейсан хийцам бар",
        "right-editusercss": "кхечу декъашхойн CSS-файлаш нсяр",
+       "right-edituserjson": "кхечу декъашхойн JSON-файлаш нисяр",
        "right-edituserjs": "кхечу декъашхойн JavaScript-файлаш нисяр",
        "right-editmyusercss": "Декъашхочун CSS файлаш таяр",
        "right-editmyuserjs": "Лелош йолу шен JavaScript-файлаш таяр",
index 0bc33d1..4a56710 100644 (file)
        "prefs-editor": "دەستکاریکەر",
        "prefs-preview": "پێشبینین",
        "prefs-advancedrc": "ھەڵبژاردەکانی پێشکەوتوو",
-       "prefs-opt-out": "گەڕاندنەوەی چاکسازییەکان",
        "prefs-advancedrendering": "هەڵبژاردە پێشکەوتووەکان",
        "prefs-advancedsearchoptions": "هەڵبژاردە پێشکەوتووەکان",
        "prefs-advancedwatchlist": "هەڵبژاردە پێشکەوتووەکان",
index af00619..52b3bf6 100644 (file)
        "timezonelegend": "Časové pásmo:",
        "localtime": "Místní čas:",
        "timezoneuseserverdefault": "Použít časové pásmo wiki ($1)",
-       "timezoneuseoffset": "Jiné (zadejte posun)",
+       "timezoneuseoffset": "Jiné (níže zadejte posun)",
+       "timezone-useoffset-placeholder": "Příklady hodnot: „-07:00“ nebo „01:00“",
        "servertime": "Čas na serveru:",
        "guesstimezone": "Načíst z prohlížeče",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Editor",
        "prefs-preview": "Náhled",
        "prefs-advancedrc": "Rozšířené možnosti",
-       "prefs-opt-out": "Nepoužívat vylepšení",
        "prefs-advancedrendering": "Rozšířené možnosti",
        "prefs-advancedsearchoptions": "Rozšířené možnosti",
        "prefs-advancedwatchlist": "Rozšířené možnosti",
        "log-action-filter-suppress-reblock": "Utajení uživatele novým zablokováním",
        "log-action-filter-upload-upload": "Nové načtení",
        "log-action-filter-upload-overwrite": "Znovunačtení",
-       "authmanager-authn-not-in-progress": "Autentizace neprobíhá nebo se ztratila data sezení. Začněte prosím znovu od začátku.",
+       "authmanager-authn-not-in-progress": "Autentizace neprobíhá nebo se ztratila data relace. Začněte, prosíme, znovu od začátku.",
        "authmanager-authn-no-primary": "Uvedené přihlašovací údaje se nepodařilo autentizovat.",
        "authmanager-authn-no-local-user": "Uvedené přihlašovací údaje neodpovídají žádnému uživateli této wiki.",
        "authmanager-authn-no-local-user-link": "Uvedené přihlašovací údaje jsou platné, ale nejsou přiřazeny žádnému uživateli na této wiki. Přihlašte se jiným způsobem nebo si založte nový uživatelský účet a budete mít možnost s tímto účtem propojit vaše stávající přihlašovací údaje.",
        "authmanager-change-not-supported": "Uvedené přihlašovací údaje nelze změnit, protože by je nikdo nepoužíval.",
        "authmanager-create-disabled": "Zakládání účtů je zakázáno.",
        "authmanager-create-from-login": "Pro založení účtu vyplňte uvedená pole.",
-       "authmanager-create-not-in-progress": "Zakládání účtu neprobíhá nebo se ztratila data sezení. Začněte prosím znovu od začátku.",
+       "authmanager-create-not-in-progress": "Zakládání účtu neprobíhá nebo se ztratila data relace. Začněte, prosíme, znovu od začátku.",
        "authmanager-create-no-primary": "Uvedené přihlašovací údaje nelze použít pro založení účtu.",
        "authmanager-link-no-primary": "Uvedené přihlašovací údaje nelze použít pro propojení účtů.",
-       "authmanager-link-not-in-progress": "Propojování účtů neprobíhá nebo se ztratila data sezení. Začněte prosím znovu od začátku.",
+       "authmanager-link-not-in-progress": "Propojování účtů neprobíhá nebo se ztratila data relace. Začněte, prosíme, znovu od začátku.",
        "authmanager-authplugin-setpass-failed-title": "Změna hesla se nezdařila",
        "authmanager-authplugin-setpass-failed-message": "Autentizační modul změnu hesla zamítl.",
        "authmanager-authplugin-create-fail": "Autentizační modul založení účtu zamítl.",
        "authmanager-autocreate-noperm": "Automatické zakládání účtů není povoleno.",
        "authmanager-autocreate-exception": "Automatické založení účtu je dočasně zakázáno kvůli předchozím chybám.",
        "authmanager-userdoesnotexist": "Uživatelský účet „$1“ není zaregistrován.",
-       "authmanager-userlogin-remembermypassword-help": "Zda se má heslo zapamatovat déle než jen po dobu tohoto sezení.",
+       "authmanager-userlogin-remembermypassword-help": "Zda se má heslo zapamatovat déle než jen po dobu této relace.",
        "authmanager-username-help": "Uživatelské jméno pro autentizaci.",
        "authmanager-password-help": "Heslo pro autentizaci.",
        "authmanager-domain-help": "Doména pro externí autentizaci.",
        "specialpage-securitylevel-not-allowed-title": "Není povoleno",
        "specialpage-securitylevel-not-allowed": "Je nám líto, ale nemáte povolení použít tuto stránku, protože se nepodařilo ověřit vaši totožnost.",
        "authpage-cannot-login": "Nepodařilo se zahájit přihlašování.",
-       "authpage-cannot-login-continue": "Nepodařilo se pokračovat v přihlašování. Patrně vypršela platnost vašeho sezení.",
+       "authpage-cannot-login-continue": "Nepodařilo se pokračovat v přihlašování. Patrně vypršela platnost vaší relace.",
        "authpage-cannot-create": "Nepodařilo se zahájit zakládání účtu.",
-       "authpage-cannot-create-continue": "Nepodařilo se pokračovat v zakládání účtu. Patrně vypršela platnost vašeho sezení.",
+       "authpage-cannot-create-continue": "Nepodařilo se pokračovat v zakládání účtu. Patrně vypršela platnost vaší relace.",
        "authpage-cannot-link": "Nepodařilo se zahájit propojování účtů.",
-       "authpage-cannot-link-continue": "Nepodařilo se pokračovat v propojování účtů. Patrně vypršela platnost vašeho sezení.",
+       "authpage-cannot-link-continue": "Nepodařilo se pokračovat v propojování účtů. Patrně vypršela platnost vaší relace.",
        "cannotauth-not-allowed-title": "Přístup odmítnut",
        "cannotauth-not-allowed": "Nemáte oprávnění použít tuto stránku",
        "changecredentials": "Změna přihlašovacích údajů",
index 424dbe1..c831929 100644 (file)
        "tog-watchlisthideminor": "Skjul mindre ændringer i overvågningslisten",
        "tog-watchlisthideliu": "Skjul indloggede brugeres redigeringer i overvågningslisten",
        "tog-watchlistreloadautomatically": "Opdater overvågningslisten automatisk, når et filter ændres (kræver JavaScript)",
-       "tog-watchlistunwatchlinks": "Tilføj direkte henvisninger for at overvåge/fjerne overvågning til overvågningsposter (JavaScript krævet for at skifte funktionalitet)",
+       "tog-watchlistunwatchlinks": "Føj mærker ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) til at slå overvågning til og fra for overvågede sider med ændringer (JavaScript kræves for at kunne slå til og fra)",
        "tog-watchlisthideanons": "Skjul anonyme brugeres redigeringer i overvågningslisten",
        "tog-watchlisthidepatrolled": "Skjul patruljerede ændringer i overvågningslisten",
        "tog-watchlisthidecategorization": "Skjul kategorisering af sider",
        "timezonelegend": "Tidszone:",
        "localtime": "Lokaltid:",
        "timezoneuseserverdefault": "Brug wiki'ens standardindstilling ($1)",
-       "timezoneuseoffset": "Anden (angiv forskel)",
+       "timezoneuseoffset": "Anden (angiv forskel forneden)",
+       "timezone-useoffset-placeholder": "Eksempelværdier: \"-07:00\" eller \"01:00\"",
        "servertime": "Serverens tid:",
        "guesstimezone": "Hent tidszone fra browseren",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Redigeringsprogrammet",
        "prefs-preview": "Forhåndsvisning",
        "prefs-advancedrc": "Avancerede indstillinger",
-       "prefs-opt-out": "Vælg ikke at få forbedringer",
        "prefs-advancedrendering": "Avancerede indstillinger",
        "prefs-advancedsearchoptions": "Avancerede indstillinger",
        "prefs-advancedwatchlist": "Avancerede indstillinger",
index 23935a2..5aa132e 100644 (file)
        "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-not-allowed-here": "Der Inhalt „$1“ ist auf der Seite [[$2]] im Schlitz „$3“ nicht erlaubt",
        "editwarning-warning": "Das Verlassen dieser Seite kann dazu führen, dass deine Änderungen verloren gehen.\nWenn du angemeldet bist, kannst du das Anzeigen dieser Warnung im Bereich „{{int:prefs-editing}}“ deiner Einstellungen abschalten.",
        "editpage-invalidcontentmodel-title": "Das Inhaltsmodell wird nicht unterstützt.",
        "editpage-invalidcontentmodel-text": "Das Inhaltsmodell „$1“ wird nicht unterstützt.",
        "timezonelegend": "Zeitzone:",
        "localtime": "Ortszeit:",
        "timezoneuseserverdefault": "Standardzeit dieses Wikis nutzen ($1)",
-       "timezoneuseoffset": "Andere (Unterschied angeben)",
+       "timezoneuseoffset": "Andere (unten Unterschied angeben)",
+       "timezone-useoffset-placeholder": "Beispielwerte: „-07:00“ oder „01:00“",
        "servertime": "Aktuelle Zeit auf dem Server:",
        "guesstimezone": "Vom Browser übernehmen",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Bearbeitungsprogramm",
        "prefs-preview": "Vorschau",
        "prefs-advancedrc": "Erweiterte Optionen",
-       "prefs-opt-out": "Von den Verbesserungen abmelden",
        "prefs-advancedrendering": "Erweiterte Optionen",
        "prefs-advancedsearchoptions": "Erweiterte Optionen",
        "prefs-advancedwatchlist": "Erweiterte Optionen",
index 79f89e9..d22d6d2 100644 (file)
        "specialpages-group-changes": "अल्लैका परिवर्तन लगहरू",
        "tags": "मान्य परिवर्तन ट्यागहरू",
        "tag-filter": "[[Special:Tags|पुछड]] छानिन्या",
-       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|à¤\9fà¥\8dयाà¤\97|à¤\9fà¥\8dयाà¤\97हरà¥\82}}]]: $2",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|à¤\9fà¥\8dयाà¤\97|à¤\9fà¥\8dयाà¤\97à¤\85न}}]]: $2",
        "tags-active-no": "नाइँ",
        "tags-hitcount": "$1 {{PLURAL:$1|परिवर्तन|परिवर्तनहरू}}",
        "tags-create-no-name": "तमीले ट्याग नाम निर्दिष्ट गद्दु पड्ड्या हुन्छ ।",
index 95de070..25545a4 100644 (file)
        "localtime": "Τοπική ώρα:",
        "timezoneuseserverdefault": "Χρήση της προεπιλογής του wiki ($1)",
        "timezoneuseoffset": "Ἀλλη (καθορισμός της διαφοράς)",
+       "timezone-useoffset-placeholder": "Τιμές ως παράδειγμα: \"-07:00\" or \"01:00\"",
        "servertime": "Η ώρα του διακομιστή:",
        "guesstimezone": "Συμπλήρωση μέσω του browser",
        "timezoneregion-africa": "Αφρική",
        "prefs-editor": "Συντάκτης",
        "prefs-preview": "Προεπισκόπηση",
        "prefs-advancedrc": "Προηγμένες επιλογές",
-       "prefs-opt-out": "Απόρριψη βελτιώσεων",
        "prefs-advancedrendering": "Προηγμένες επιλογές",
        "prefs-advancedsearchoptions": "Προηγμένες επιλογές",
        "prefs-advancedwatchlist": "Προηγμένες επιλογές",
index 72e6716..159e705 100644 (file)
        "edit-gone-missing": "Could not update the page.\nIt appears to have been deleted.",
        "edit-conflict": "Edit conflict.",
        "edit-no-change": "Your edit was ignored because no change was made to the text.",
+       "edit-slots-cannot-add": "The following {{PLURAL:$1|slot is|slots are}} not supported here: $2.",
+       "edit-slots-cannot-remove": "The following {{PLURAL:$1|slot is|slots are}} required and cannot be removed: $2.",
+       "edit-slots-missing": "The following {{PLURAL:$1|slot is|slots are}} missing: $2.",
        "postedit-confirmation-created": "The page has been created.",
        "postedit-confirmation-restored": "The page has been restored.",
        "postedit-confirmation-saved": "Your edit was saved.",
        "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-not-allowed-here": "\"$1\" content is not allowed on page [[$2]] in slot \"$3\"",
        "editwarning-warning": "Leaving this page may cause you to lose any changes you have made.\nIf you are logged in, you can disable this warning in the \"{{int:prefs-editing}}\" section of your preferences.",
        "editpage-invalidcontentmodel-title": "Content model not supported",
        "editpage-invalidcontentmodel-text": "The content model \"$1\" is not supported.",
        "timezonelegend": "Time zone:",
        "localtime": "Local time:",
        "timezoneuseserverdefault": "Use wiki default ($1)",
-       "timezoneuseoffset": "Other (specify offset)",
+       "timezoneuseoffset": "Other (specify offset below)",
+       "timezone-useoffset-placeholder": "Example values: \"-07:00\" or \"01:00\"",
        "servertime": "Server time:",
        "guesstimezone": "Fill in from browser",
        "timezoneregion-africa": "Africa",
        "prefs-editor": "Editor",
        "prefs-preview": "Preview",
        "prefs-advancedrc": "Advanced options",
-       "prefs-opt-out": "Opt out of improvements",
        "prefs-advancedrendering": "Advanced options",
        "prefs-advancedsearchoptions": "Advanced options",
        "prefs-advancedwatchlist": "Advanced options",
index 5be4e7c..449b65c 100644 (file)
@@ -53,7 +53,9 @@
                        "Rafaneta",
                        "NMaia",
                        "Joao Xavier",
-                       "Surfo"
+                       "Surfo",
+                       "YvesNevelsteen",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Substrekado de ligiloj:",
        "badaccess": "Vi ne havas sufiĉe da redaktorajtoj por ĉi tiu paĝo.",
        "badaccess-group0": "Vi ne rajtas plenumi la agon, kiun vi petis.",
        "badaccess-groups": "La ago, kiun vi petis, estas limigita al uzantoj en {{PLURAL:$2|la grupo|unu el la grupoj}}: $1.",
-       "versionrequired": "Versio $1 de MediaWiki nepras",
+       "versionrequired": "Versio $1 de MediaWiki estas deviga",
        "versionrequiredtext": "La versio $1 de MediaWiki estas necesa por uzi ĉi tiun paĝon. Vidu [[Special:Version|paĝon pri versio]].",
        "ok": "Bone",
        "retrievedfrom": "Elŝutita el  \"$1\"",
        "nospecialpagetext": "<strong>Vi petis malvalidan specialan paĝon.</strong>\n\nListo de validaj specialaj paĝoj estas trovebla ĉe [[Special:SpecialPages|{{int:specialpages}}]].",
        "error": "Eraro",
        "databaseerror": "Datumbaza eraro",
-       "databaseerror-text": "Datumbaza eraro de la mendo okazis.\nĈi tiu eble indikas cimon de la programaro.",
+       "databaseerror-text": "Datumbaza eraro de la serĉmendo okazis.\nĈi tiu eble indikas cimon de la programaro.",
        "databaseerror-textcl": "Datumbaza eraro de la mendo okazis.",
-       "databaseerror-query": "Mendo: $1",
+       "databaseerror-query": "Serĉmendo: $1",
        "databaseerror-function": "Funkcio: $1",
        "databaseerror-error": "Eraro: $1",
        "transaction-duration-limit-exceeded": "Por eviti krei egan atendotempon de replikado, tiu transakcio estis ĉesigita pro la skribdaŭro ($1) superigis la limon da $2 {{plural:$2|sekondo|sekondoj}}.",
        "passwordtooshort": "Pasvortoj devas esti longaj almenaŭ  $1 {{PLURAL:$1|1 signon|$1 signojn}}.",
        "passwordtoolong": "Pasvorto ne povas esti pli longa ol {{PLURAL:$1|1 signo|$1 signoj}}.",
        "passwordtoopopular": "Ne eblas uzi kutimajn pasvortojn. Bonvolu uzi pasvorton, kiu estas malpli facile divenebla.",
+       "passwordinlargeblacklist": "La enigita pasvorto estas en listo de tre ofte uzita pasvortojn. Bonvolu elekti pli unikan pasvorton.",
        "password-name-match": "Via pasvorto devas nepre malsami vian salutnomon.",
        "password-login-forbidden": "Estas malpermesite uzi tiun ĉi salutnomon kaj pasvorton.",
        "mailmypassword": "Refari pasvorton",
        "blocked-notice-logextract": "Ĉi tiu uzanto estas ĉi-momente forbarita.\nLa lasta protokolero estas jene montrata por via referenco:",
        "clearyourcache": "<strong>Notu:</strong>Post konservado, vi forviŝu la kaŝmemoron de via foliumilo por vidi la ŝanĝojn. \n* <strong>Firefox / Safari:</strong> Premu majuskligan klavon klakante <em>Reŝarĝi</em>, aŭ premu aŭ <em>Stir-F5</em> aŭ <em>Stir-R</em> (<em>⌘-R</em> kun Makintoŝo)\n* <strong>Google Chrome:</strong> Premu <em>Stir-majuskligklavon-R</em> (<em>⌘-Majuskligklavo-R</em> kun Makintoŝo)\n* <strong>Interreta Esplorilo</strong>: Premu <em>Stir</em> klakante <em>Refreŝu</em>, aŭ premu <em>Stir-F5</em> \n* <strong>Opera:</strong> Iru al <em>menuo →  parametroj</em> (<em>Opera →  Agordoj</em> per Makintoŝa) kaj tiam al <em>privateco kaj sekureco →  Nuligi retuman datenon → kaŝmemorataj bildoj kaj dosieroj</em>.",
        "usercssyoucanpreview": "'''Konsileto:''' Uzu la butonon \"Antaŭrigardi\" por provi vian novan CSS-kodon antaŭ konservado.",
+       "userjsonyoucanpreview": "<strong>Konsileto:</strong> Uzu la butonon \"{{int:showpreview}}\" por provi vian novan JSON antaŭ konservado.",
        "userjsyoucanpreview": "'''Konsileto:''' Uzu la butonon \"{{int:showpreview}}\" por provi vian novan Ĝavaskriptan kodon antaŭ konservado.",
        "usercsspreview": "'''Notu ke vi nur antaŭvidas vian uzanto-CSS.\nĜi ne jam estis konservita!'''",
+       "userjsonpreview": "<strong>Memoru ke vi nun nur provas kaj antaŭrigardas vian JSON. Ĝi ne estas jam konservita!</strong>",
        "userjspreview": "'''Memoru ke vi nun nur provas kaj antaŭrigardas vian uzantan Ĝavaskripton, ĝi ne estas jam konservita'''",
        "sitecsspreview": "'''Konsciu ke vi nur antaŭrigardas tiun ĉi CSS.'''\n'''Ĝi ne jam estis savita!''",
+       "sitejsonpreview": "<strong>Memoru ke vi nun nur provas kaj antaŭrigardas vian JSON-agordojn. Ĝi ne estas jam konservita!</strong>",
        "sitejspreview": "'''Konsciu ke vi nur antaŭrigardas tiun ĉi Ĝavaskripta kodon''. ''Ĝi ne jam estis konservita''.",
        "userinvalidconfigtitle": "<strong>Averto:</strong> Ne ekzistas etoso \"$1\".\nRememoru ke individuaj .css-aj, .json-aj kaj .js-aj paĝoj uzas minusklan titolon, ekz. {{ns:user}}:Foo/vector.css kontraŭe al {{ns:user}}:Foo/Vector.css.",
        "updated": "(Ĝisdatigita)",
        "prefs-dateformat": "Data formato",
        "prefs-timeoffset": "Tempa deŝovo",
        "prefs-advancedediting": "Ĝeneralaj opcioj",
+       "prefs-developertools": "Iloj por programistoj",
        "prefs-editor": "Redaktilo",
        "prefs-preview": "Antaŭrigardo",
        "prefs-advancedrc": "Progresaj opcioj",
        "prefs-advancedwatchlist": "Progresaj opcioj",
        "prefs-displayrc": "Montraj opcioj",
        "prefs-displaywatchlist": "Montraj opcioj",
+       "prefs-changesrc": "Ŝanĝoj montritaj",
+       "prefs-changeswatchlist": "Ŝanĝoj montritaj",
+       "prefs-pageswatchlist": "Atentataj paĝoj",
        "prefs-tokenwatchlist": "Ĵetono",
        "prefs-diffs": "Diferencoj",
        "prefs-help-prefershttps": "Ĉi tiu agordo ekefikos je via sekva ensaluto.",
        "editinguser": "Ŝanĝado de uzantorajtoj de la {{GENDER:$1|uzanto}} <strong>[[User:$1|$1]]</strong> $2",
        "viewinguserrights": "Vidi uzantorajtojn de {{GENDER:$1|uzanto}} <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "Redakti grupojn de uzantoj",
-       "userrights-viewusergroup": "Vidi grupojn de uzantoj",
+       "userrights-viewusergroup": "Vidi {{GENDER:$1|user}}-grupojn",
        "saveusergroups": "Konservi grupojn de {{GENDER:$1|uzantoj}}",
        "userrights-groupsmember": "Membro de:",
        "userrights-groupsmember-auto": "Implica membro de:",
        "right-ipblock-exempt": "Preterpasi IP-forbarojn, aŭtomatajn forbarojn, kaj ĝeneralajn forbarojn",
        "right-unblockself": "Malforbari oni mem",
        "right-protect": "Ŝanĝi protektniveloj kaj redakti protektitajn paĝojn",
-       "right-editprotected": "Redakti protektitajn paĝojn (sen kaskada protektado)",
+       "right-editprotected": "Redakti paĝojn protektitajn kiel \"{{int:protect-level-sysop}}\"",
        "right-editsemiprotected": "Redakti paĝojn protektitajn kiel \"{{int:protect-level-autoconfirmed}}\"",
        "right-editcontentmodel": "Redakti paĝan enhavmodelon",
        "right-editinterface": "Redakti la uzantointerfacon",
        "right-editusercss": "Redaktu CSS-dosierojn de aliaj uzantoj",
+       "right-edituserjson": "Redakti JSON-dosierojn de aliaj uzantoj",
        "right-edituserjs": "Redaktu JS-dosierojn de aliaj uzantoj",
        "right-editmyusercss": "Redakti viajn proprajn CSS-dosierojn",
+       "right-editmyuserjson": "Redakti viajn proprajn JSON-dosierojn",
        "right-editmyuserjs": "Redakti viajn proprajn JavaScript-dosierojn",
        "right-viewmywatchlist": "Vidi vian propran atentaron",
        "right-editmywatchlist": "Redakti vian propran atentaron. Notu, ke kelkaj agoj ankoraŭ ebligas aldoni paĝojn sen ĉi tiu rajto.",
        "rcfilters-savedqueries-new-name-label": "Nomo",
        "rcfilters-savedqueries-new-name-placeholder": "Priskribas la celon de la filtrilo",
        "rcfilters-savedqueries-apply-label": "Krei filtrilon",
+       "rcfilters-savedqueries-apply-and-setdefault-label": "Krei defaŭltan filtrilon",
        "rcfilters-savedqueries-cancel-label": "Nuligi",
+       "rcfilters-savedqueries-add-new-title": "Konservi la nunajn filtrilajn agordojn",
        "rcfilters-restore-default-filters": "Restarigi defaŭltajn filtrilojn",
        "rcfilters-clear-all-filters": "Nuligi ĉiujn filtrilojn",
        "rcfilters-show-new-changes": "Vidi la plej novajn ŝanĝojn",
        "rcfilters-filter-editsbyself-description": "Viaj kontribuoj.",
        "rcfilters-filter-editsbyother-label": "ŝanĝoj faritaj de aliuloj",
        "rcfilters-filter-editsbyother-description": "Ĉiuj ŝanĝoj, escepte de viaj.",
-       "rcfilters-filtergroup-userExpLevel": "Spertonivelo (nur por registritaj uzantoj)",
+       "rcfilters-filtergroup-userExpLevel": "Registriĝo kaj spertonivelo de uzanto",
        "rcfilters-filter-user-experience-level-registered-label": "Registritaj",
        "rcfilters-filter-user-experience-level-registered-description": "Ensalutitaj redaktantoj.",
        "rcfilters-filter-user-experience-level-unregistered-label": "Neregistritaj",
        "rcfilters-filter-bots-description": "Redaktoj farita de aŭtomatigitaj iloj.",
        "rcfilters-filter-humans-label": "Homa (ne robota)",
        "rcfilters-filter-humans-description": "Redaktoj farita de homaj redaktantoj.",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "Ne patrolita",
+       "rcfilters-filter-reviewstatus-manual-description": "Redaktoj mane markita kiel patrolita.",
+       "rcfilters-filter-reviewstatus-manual-label": "Mane patrolita",
+       "rcfilters-filter-reviewstatus-auto-description": "Redaktoj de altnivelaj uzantoj kies laboro estas aŭtomate markita kiel patrolita.",
+       "rcfilters-filter-reviewstatus-auto-label": "Aŭtomate patrolita",
        "rcfilters-filtergroup-significance": "Signifo",
        "rcfilters-filter-minor-label": "Etaj redaktoj",
        "rcfilters-filter-minor-description": "Redaktoj kiujn la aŭtoro markis kiel \"redakteto\".",
        "rcfilters-filter-major-label": "Redaktoj kiujn la aŭtoro ne markis kiel \"redakteto\".",
        "rcfilters-filter-major-description": "Redaktoj kiujn la aŭtoro ne markis kiel \"redakteto\".",
+       "rcfilters-filtergroup-watchlist": "Atentataj paĝoj",
+       "rcfilters-filter-watchlist-watched-label": "Sur atentaro",
+       "rcfilters-filter-watchlist-watched-description": "Ŝanĝoj al paĝoj sur via atentaro.",
+       "rcfilters-filter-watchlist-watchednew-label": "Nova ŝanĝoj en la atentaro",
+       "rcfilters-filter-watchlist-watchednew-description": "Ŝanĝoj al priatentataj paĝoj kiujn vi ne vizitis ekde kiam la ŝanĝoj okazis.",
+       "rcfilters-filter-watchlist-notwatched-label": "Ne sur la atentaro",
+       "rcfilters-filter-watchlist-notwatched-description": "Ĉio krom ŝanĝoj al viaj priatentataj paĝoj.",
+       "rcfilters-filtergroup-watchlistactivity": "Agado en la atentaro",
+       "rcfilters-filter-watchlistactivity-unseen-label": "Nevidataj ŝanĝoj",
+       "rcfilters-filter-watchlistactivity-unseen-description": "Ŝanĝoj al paĝoj kiujn vi ne vizitis ekde kiam la ŝanĝoj okazis.",
+       "rcfilters-filter-watchlistactivity-seen-label": "Viditaj ŝanĝoj",
+       "rcfilters-filter-watchlistactivity-seen-description": "Ŝanĝoj al paĝoj kiujn vi vizitis ekde kiam la ŝanĝoj okazis.",
        "rcfilters-filtergroup-changetype": "Tipo de ŝanĝo",
        "rcfilters-filter-pageedits-label": "Redaktoj de paĝoj",
        "rcfilters-filter-pageedits-description": "Redaktoj al vikia enhavo, diskutoj, kategoriaj priskriboj…",
        "rcfilters-filter-categorization-description": "Registroj de paĝoj aldonitaj aŭ forigitaj de kategorioj",
        "rcfilters-filter-logactions-label": "Registritaj agoj",
        "rcfilters-filter-logactions-description": "Administraciaj agoj, kontaj kreoj, paĝaj forigoj, alŝutoj…",
+       "rcfilters-filtergroup-lastRevision": "Lastaj revizioj",
+       "rcfilters-filter-lastrevision-label": "Lasta revizio",
+       "rcfilters-filter-lastrevision-description": "Nur la plej lasta ŝanĝo al paĝo.",
+       "rcfilters-filter-previousrevision-label": "Ne la lasta revizio",
+       "rcfilters-filter-previousrevision-description": "Ĉiuj ŝanĝoj kiu ne estas la \"lasta revizio\".",
+       "rcfilters-filter-excluded": "Ekskludita",
+       "rcfilters-liveupdates-button": "Aŭtomata ĝisdatigo",
+       "rcfilters-liveupdates-button-title-on": "Malŝalti aŭtomatajn ĝisdatigojn",
+       "rcfilters-liveupdates-button-title-off": "Montri novajn ŝanĝojn dum ili okazas",
        "rcfilters-watchlist-markseen-button": "Marku ĉiujn ŝanĝojn viditaj",
+       "rcfilters-watchlist-edit-watchlist-button": "Redakti vian atentaron",
+       "rcfilters-watchlist-showupdated": "Ŝanĝoj en paĝo, kiun vi ne vizitis post la ŝanĝo, aperas <strong>graslitere</strong>, kun nigra disketo.",
        "rcnotefrom": "Malsupre estas la {{PLURAL:$5|ŝanĝo|ŝanĝoj}} ekde <strong>$3, $4</strong> (montrante ĝis <strong>$1</strong>).",
        "rclistfrom": "Montri novajn ŝanĝojn ekde \"$3 $2\"",
        "rcshowhideminor": "$1 etajn redaktojn",
        "filedesc": "Resumo",
        "fileuploadsummary": "Resumo:",
        "filereuploadsummary": "Dosieraj ŝanĝoj:",
-       "filestatus": "Aŭtorrajta statuso:",
+       "filestatus": "Aŭtorrajta stato:",
        "filesource": "Fonto:",
        "ignorewarning": "Ignori averton kaj konservi dosieron ĉiukaze",
        "ignorewarnings": "Ignori ĉiajn avertojn",
        "fileexists": "Dosiero kun tiu ĉi nomo jam ekzistas.\nBonvolu kontroli <strong>[[:$1]]</strong> krom se vi certas ke {{GENDER:|vi}} konscie volas ŝanĝi ĝuste tiun.\n[[$1|thumb]]",
        "filepageexists": "La priskriba paĝo por ĉi tiu dosiero jam estis kreita ĉe <strong>[[:$1]]</strong>, sed neniu dosiero kun ĉi tiu nomo nune ekzistas.\nLa resumo kiun vi entajpos ne aperos en la priskribo-paĝo.\nPor aperigi vian resumon, vi devos permane redakti ĝin.\n[[$1|thumb]]",
        "fileexists-extension": "Dosiero kun simila nomo ekzistas: [[$2|thumb]]\n* Nomo de la alŝutanta dosiero: <strong>[[:$1]]</strong>\n* Nomo de la ekzistanta dosiero: <strong>[[:$2]]</strong>\nBonvolu elekti malsaman nomon.",
-       "fileexists-thumbnail-yes": "Ĉi tiu dosiero ŝajnas kiel bildo de malkreskigita grandeco ''(bildeto)''. [[$1|thumb]]\nBonvolu kontroli la dosieron <strong>[[:$1]]</strong>.\nSe la kontrolita dosiero estas la sama bildo kiel la originala grandeco, ĝi ne nepras alŝuti plian bideton.",
+       "fileexists-thumbnail-yes": "Ĉi tiu dosiero ŝajnas kiel bildo de malkreskigita grandeco ''(bildeto)''. [[$1|thumb]]\nBonvolu kontroli la dosieron <strong>[[:$1]]</strong>.\nSe la kontrolita dosiero estas la sama bildo kiel la originala grandeco, ĝi ne devigas alŝuti plian bideton.",
        "file-thumbnail-no": "La dosiernomo komencas kun <strong>$1</strong>.\nĜi ŝajnas kiel bildo de malgrandigita grandeco ''(thumbnail)''.\nSe vi havas ĉi tiun bildon en plena distingivo, alŝutu ĉi tiun, alikaze bonvolu ŝanĝi la dosieran nomon.",
        "fileexists-forbidden": "Dosiero kun ĉi tiu nomo jam ekzistas kaj ne povas anstataŭigi ĝin.\nSe vi ankoraŭ volas alŝuti vian dosieron, bonvolu reprovi kun nova nomo.\n[[File:$1|thumb|center|$1]]",
        "fileexists-shared-forbidden": "Dosiero kun ĉi tia nomo jam ekzistas en la komuna dosierujo.\nSe vi ankoraŭ volas alŝuti vian dosieron, bonvolu retroigi kaj uzi novan nomon.[[File:$1|thumb|center|$1]]",
        "uploadstash-refresh": "Aktualigi la dosierliston.",
        "uploadstash-thumbnail": "Vidi bildeton",
        "uploadstash-exception": "Ne eblas alŝuti en kaŝkonservejon ($1): \"$2\".",
+       "uploadstash-bad-path-unrecognized-thumb-name": "Nerekonita miniatura nomo.",
        "invalid-chunk-offset": "Malvalida deŝovo de dosierpeco",
        "img-auth-accessdenied": "Atingo malpermisita",
-       "img-auth-nopathinfo": "Mankas PATH_INFO (informo pri dosiervojo).\nVia servilo ne estas konfigurita por sendi ĉi tiun informon.\nEble ĝi estas CGI-bazita kaj ne subtenas img_auth.\nVidu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization (angle).",
+       "img-auth-nopathinfo": "Mankas informo pri vojo.\nVia servilo estu agordita por sendi la variablojn REQUEST_URI kaj/aŭ PATH_INFO.\nSe ĝi jam estas, provu aktivigon de $wgUsePathInfo.\nVidu https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization.",
        "img-auth-notindir": "Petita vojo ne estas en la konfigurita alŝuta dosierujo.",
        "img-auth-badtitle": "Ne povas konstrui validan titolon de \"$1\".",
        "img-auth-nologinnWL": "Vi ne estas ensalutita kaj \"$1\" ne estas en la blankalisto.",
        "deadendpages": "Paĝoj sen interna ligilo",
        "deadendpagestext": "La sekvaj paĝoj ne ligas al aliaj paĝoj en {{SITENAME}}.",
        "protectedpages": "Protektitaj paĝoj",
+       "protectedpages-filters": "Filtriloj",
        "protectedpages-indef": "Nur ĉiamaj protektaĵoj",
        "protectedpages-summary": "Ĉi tiu paĝo listigas ekzistantajn paĝojn, kiuj nuntempe estas protektitaj. Por listo de titoloj, kiuj estas protektitaj kontraŭ kreado, vidu [[{{#special:ProtectedTitles}}|{{int:protectedtitles}}]].",
        "protectedpages-cascade": "Nur kaskadaj protektoj",
        "apisandbox-dynamic-error-exists": "Parametro nomata \"$1\" jam ekzistas.",
        "apisandbox-deprecated-parameters": "Evitindajn parametrojn",
        "apisandbox-fetch-token": "Aŭtoplenigu ĵetonon",
+       "apisandbox-add-multi": "Aldoni",
        "apisandbox-submit-invalid-fields-title": "Iuj kampoj estas malvalidaj.",
        "apisandbox-submit-invalid-fields-message": "Bonvolu ĝustigi la markitajn kampojn kaj provi denove.",
        "apisandbox-results": "Rezultoj",
        "dellogpage": "Protokolo pri forigoj",
        "dellogpagetext": "Jen listo de la plej lastaj forigoj.",
        "deletionlog": "protokolo pri forigoj",
+       "logentry-create-create": "$1 {{GENDER:$2|kreis}} paĝon $3",
        "reverted": "Malfaris al antaŭa revisio",
        "deletecomment": "Kialo:",
        "deleteotherreason": "Alia/plua kialo:",
        "contribsub2": "De {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "Uzanto-konto \"$1\" ne estas registrita.",
        "nocontribs": "Trovis neniajn redaktojn laŭ tiu kriterio.",
-       "uctop": " aktuala",
+       "uctop": "nuna",
        "month": "Ekde monato (kaj pli frue):",
        "year": "Ekde jaro (kaj pli frue):",
        "sp-contributions-newbies": "Montri nur kontribuojn de novaj kontoj",
        "ipb-disableusertalk": "Preventi ĉi tiun uzanton redakti sian diskutpaĝon, dum ĝi estas forbarata",
        "ipb-change-block": "Reforbari la uzanton kun ĉi tiuj preferoj",
        "ipb-confirm": "Konfirmi forbaron",
+       "ipb-sitewide": "Tutreteja",
+       "ipb-partial": "Parta",
+       "ipb-pages-label": "Paĝoj",
        "badipaddress": "Neniu uzanto, aŭ la IP-adreso estas misformita.",
        "blockipsuccesssub": "Forbaro sukcesis.",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] estas forbarita. <br />\nVidu la [[Special:BlockList|liston de forbaroj]] por kontroli.",
        "unblocked-id": "Forbaro $1 estas forigita.",
        "unblocked-ip": "[[Special:Contributions/$1|$1]] estis malforbarita.",
        "blocklist": "Forbaritaj uzantoj",
+       "autoblocklist-submit": "Serĉi",
        "ipblocklist": "Forbaritaj uzantoj",
        "ipblocklist-legend": "Trovi forbaritan uzanton.",
        "blocklist-userblocks": "Kaŝi konto-forbarojn",
        "createaccountblock": "Kreado de kontoj forbarita",
        "emailblock": "retpoŝto forbarita",
        "blocklist-nousertalk": "ne povas redakti sian propran diskuto-paĝon",
+       "blocklist-editing": "redaktado",
+       "blocklist-editing-sitewide": "redaktado (tutreteja)",
        "ipblocklist-empty": "La forbarlibro estas malplena.",
        "ipblocklist-no-results": "Ĉi tiu IP-adreso aŭ salutnomo ne estas forbarita.",
        "blocklink": "forbari",
        "ipbnounblockself": "Vi ne rajtas malforbari vin mem",
        "lockdb": "Ŝlosi datumbazon",
        "unlockdb": "Malŝlosi datumaron",
-       "lockdbtext": "Se vi ŝlosos la datumaron, tio malebligos al ĉiuj uzantoj\nredakti paĝojn, ŝanĝi preferojn, priumi atentarojn, kaj fari diversajn aliajn\naferojn, por kiuj nepras ŝanĝi la datumaron.\nBonvolu certigu, ke vi efektive intencas tion fari, kaj ke vi ja malŝlosos\nla datumaron post ol vi finos vian riparadon.",
-       "unlockdbtext": "Se vi malŝlosos la datumaron, tio reebligos al ĉiuj uzantoj\nredakti paĝojn, ŝanĝi preferojn, priumi la atentaron, kaj fari aliajn aferojn,\npor kiuj nepras ŝanĝi al la datumaro.\nBonvolu certigu, ke vi efektive intencas tion fari.",
+       "lockdbtext": "Se vi ŝlosos la datumaron, tio malebligos al ĉiuj uzantoj\nredakti paĝojn, ŝanĝi preferojn, priumi atentarojn, kaj fari diversajn aliajn\naferojn, por kiuj estas deviga ŝanĝi la datumaron.\nBonvolu certigu, ke vi efektive intencas tion fari, kaj ke vi ja malŝlosos\nla datumaron post ol vi finos vian riparadon.",
+       "unlockdbtext": "Se vi malŝlosos la datumaron, tio reebligos al ĉiuj uzantoj\nredakti paĝojn, ŝanĝi preferojn, priumi la atentaron, kaj fari aliajn aferojn,\npor kiuj estas deviga ŝanĝi al la datumaro.\nBonvolu certigu, ke vi efektive intencas tion fari.",
        "lockconfirm": "Jes, mi vere volas ŝlosi la datumaron.",
        "unlockconfirm": "Jes, mi vere volas malŝlosi la datumaron.",
        "lockbtn": "Ŝlosi datumbazon",
        "fix-double-redirects": "Ĝisdatigi iujn alidirektilojn kiuj direktas al la originala titolo",
        "move-leave-redirect": "Forlasi alidirektilon",
        "protectedpagemovewarning": "'''Averto:''' Ĉi tiu paĝo estis ŝlosita tiel nur uzantoj kun administranto-rajtoj povas movi ĝin.\nJen la lasta protokolero por via referenco:",
-       "semiprotectedpagemovewarning": "'''Averto:''' Ĉi tiu paĝo estis ŝlosita tiel ĝi estas nur movebla de registritaj uzantoj.\nJen la lasta protokolero por via referenco:",
+       "semiprotectedpagemovewarning": "<strong>Averto:</strong> Ĉi tiu paĝo estis ŝlosita tiel, ke ĝin povas movi nur aŭtomate konfirmitaj uzantoj.\nJen por vi la plej nova protokolero:",
        "move-over-sharedrepo": "[[:$1]] ekzistas en komuna dosierujo. Movado de dosiero al ĉi tiu titolo anstataŭigos la komunan dosieron.",
        "file-exists-sharedrepo": "La elektita dosiernomo jam estas uzita en komun dosierujo.\nBonvolu elekti alian nomon.",
        "export": "Elporti paĝojn",
        "tooltip-pt-watchlist": "Listo de paĝoj kies ŝanĝojn vi priatentas.",
        "tooltip-pt-mycontris": "Listo de viaj kontribuoj",
        "tooltip-pt-anoncontribs": "Listo de redaktoj faritaj el ĉi tiu IPa adreso",
-       "tooltip-pt-login": "Vi kuraĝigas ensaluti, tamen ne estas devige.",
+       "tooltip-pt-login": "Ni rekomendas ke vi ensalutu, kvankam tio ne estas devige.",
        "tooltip-pt-logout": "Elsaluti",
-       "tooltip-pt-createaccount": "Ni rekomendas al vi kreon de uzantokonto kaj ensaluto; tamen, tio ne estas deviga",
+       "tooltip-pt-createaccount": "Ni rekomendas ke vi kreu uzantokonton kaj ensalutu, kvankam tio ne estas deviga",
        "tooltip-ca-talk": "Diskuto pri la artikolo",
        "tooltip-ca-edit": "Redakti ĉi tiun paĝon",
        "tooltip-ca-addsection": "Starti novan sekcion",
        "tooltip-ca-watch": "Aldoni ĉi tiun paĝon al via atentaro",
        "tooltip-ca-unwatch": "Forigi tiun ĉi paĝon el via atentaro",
        "tooltip-search": "Serĉi tra {{SITENAME}}",
-       "tooltip-search-go": "Iru al paĝo kun ĉi preciza nomo se ĝi ekzistas",
+       "tooltip-search-go": "Iru al paĝo kun ĉi tiu preciza nomo se ĝi ekzistas",
        "tooltip-search-fulltext": "Serĉi la paĝojn por ĉi tiu teksto",
        "tooltip-p-logo": "Viziti la ĉefpaĝon",
        "tooltip-n-mainpage": "Viziti la ĉefpaĝon",
        "tooltip-t-info": "Pli da informo pri ĉi tiu paĝo",
        "tooltip-t-upload": "Alŝuti dosierojn",
        "tooltip-t-specialpages": "Listo de ĉiuj specialaj paĝoj",
-       "tooltip-t-print": "Printebla versio de ĉi tiu paĝo",
-       "tooltip-t-permalink": "Konstanta ligilo al ĉi versio de la paĝo",
+       "tooltip-t-print": "Presebla versio de ĉi tiu paĝo",
+       "tooltip-t-permalink": "Konstanta ligilo al ĉi tiu versio de la paĝo",
        "tooltip-ca-nstab-main": "Vidi la artikolon",
        "tooltip-ca-nstab-user": "Vidi la personan paĝon de la uzanto",
        "tooltip-ca-nstab-media": "Vidi la paĝon de la dosiero",
        "newimages-summary": "Ĉi tiu speciala paĝo montras la lastajn alŝutitajn dosierojn.",
        "newimages-legend": "Dosiernomo",
        "newimages-label": "Dosiernomo (aŭ parto de ĝi):",
+       "newimages-user": "IP-adreso aŭ uzantnomo",
        "newimages-showbots": "Montri alŝutojn per robotoj",
        "newimages-hidepatrolled": "Malvidigi la patrolitajn alŝutitojn",
        "noimages": "Nenio videbla.",
        "exif-nickname": "Malformala nomo de bildo",
        "exif-rating": "Taksado (el 5)",
        "exif-rightscertificate": "Atestilo de rajtoj-administrado",
-       "exif-copyrighted": "Aŭtorrajta statuso:",
+       "exif-copyrighted": "Aŭtorrajta stato:",
        "exif-copyrightowner": "Posedanto de la aŭtorrajto",
        "exif-usageterms": "Regularo pri uzado",
        "exif-webstatement": "Interreta deklarado pri aŭtorrajtoj",
        "version-specialpages": "Specialaj paĝoj",
        "version-parserhooks": "Sintaksaj hokoj",
        "version-variables": "Variabloj",
+       "version-editors": "Redaktoroj",
        "version-antispam": "Kontraŭspamilo",
        "version-other": "Alia",
        "version-mediahandlers": "Mediaj traktiloj",
        "version-license-not-found": "Por tiu ĉi etendilo ne estis trovitaj pli detalaj permesilaj informoj.",
        "version-credits-title": "Agnosko por $1",
        "version-credits-not-found": "Por tiu ĉi etendilo ne estis trovitaj pli detalaj informoj pri aŭtoroj.",
-       "version-poweredby-credits": "Ĉi tiu vikio funkcias per '''[https://www.mediawiki.org/ MediaWiki]''', aŭtorrajto ©&thinsp;2001–$1 $2.",
+       "version-poweredby-credits": "Ĉi tiu vikio funkcias per <strong>[https://www.mediawiki.org/ MediaWiki]</strong>, aŭtorrajto © 2001–$1 $2.",
        "version-poweredby-others": "aliaj",
        "version-poweredby-translators": "tradukantoj de translatewiki.net",
        "version-credits-summary": "Ni ŝatus agnoski la sekvajn personojn pro siaj kontribuoj al [[Special:Version|MediaWiki]].",
        "tags-create-reason": "Kialo:",
        "tags-create-submit": "Krei",
        "tags-create-no-name": "Vi devas specifi nomon de etikedo.",
-       "tags-create-invalid-chars": "Etikednomoj maldevas enhavi komojn (<code>,</code>) aŭ suprenstrekojn (<code>/</code>).",
+       "tags-create-invalid-chars": "La nomoj de etikedoj ne havu komojn (<code>,</code>), vertikalajn strekojn <code>|</code> aŭ suprenstrekojn (<code>/</code>).",
        "tags-create-invalid-title-chars": "Etikednomoj maldevas enhavi signojn, kiuj ne povas esti uzitaj en paĝo-titoloj.",
        "tags-create-already-exists": "La markilo \"$1\" jam ekzistas.",
        "tags-create-warnings-above": "Dum provo krei la etikedon \"$1\" estis {{PLURAL:$2|trafita jena atentigo|trafitaj jenaj atentigoj}}:",
        "compare-title-not-exists": "La titolo kiun vi specifis ne ekzistas.",
        "compare-revision-not-exists": "La revizio kiun vi specifis ne ekzistas.",
        "diff-form": "Malsamoj",
+       "permanentlink": "Konstanta ligilo",
        "dberr-problems": "Bedaŭrinde, ĉi tiu retejo suferas pro teknikaj problemoj.",
        "dberr-again": "Bonvolu atendi kelkajn minutojn kaj reŝargi.",
        "dberr-info": "(Ne eblas konekti la datumbazon: $1)",
        "htmlform-chosen-placeholder": "Elektu opcion",
        "htmlform-cloner-create": "Aldoni plian",
        "htmlform-cloner-delete": "Forigi",
-       "htmlform-cloner-required": "Almenaŭ unu valoro estas nepra.",
+       "htmlform-cloner-required": "Almenaŭ unu valoro estas deviga.",
        "htmlform-date-placeholder": "JJJJ-MM-TT",
        "htmlform-time-placeholder": "HH:MM:SS",
        "htmlform-datetime-placeholder": "JJJJ-MM-TT HH:MM:SS",
        "special-characters-title-endash": "mallonga streketo",
        "special-characters-title-emdash": "longa streketo",
        "special-characters-title-minus": "minus-signo",
-       "mw-widgets-abandonedit": "Ĉu vi vere volas foriri redaktan reĝimon sen konservo?",
+       "mw-widgets-abandonedit": "Ĉu vi vere volas forlasi la redaktan reĝimon sen konservo?",
        "mw-widgets-abandonedit-discard": "Forĵeti redaktojn",
        "mw-widgets-abandonedit-keep": "Redakti plu",
        "mw-widgets-abandonedit-title": "Ĉu vi certas?",
index bfc5b2c..316dd11 100644 (file)
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
-       "tog-hideminor": "Ocultar las ediciones menores de los cambios recientes",
-       "tog-hidepatrolled": "Ocultar las ediciones verificadas de los cambios recientes",
+       "tog-hideminor": "Ocultar las ediciones menores en cambios recientes",
+       "tog-hidepatrolled": "Ocultar las ediciones verificadas de cambios recientes",
        "tog-newpageshidepatrolled": "Ocultar las páginas verificadas de la lista de páginas nuevas",
        "tog-hidecategorization": "Ocultar la categorización de páginas",
        "tog-extendwatchlist": "Mostrar todos los cambios en la lista de seguimiento, no solo los más recientes",
-       "tog-usenewrc": "Agrupar los cambios por página en los cambios recientes y en la lista de seguimiento",
+       "tog-usenewrc": "Agrupar los cambios por página en cambios recientes y en la lista de seguimiento",
        "tog-numberheadings": "Numerar automáticamente los encabezados",
        "tog-editondblclick": "Editar páginas al hacer doble clic",
        "tog-editsectiononrightclick": "Permitir las modificaciones de sección al hacer clic derecho en sus títulos",
        "tog-watchcreations": "Añadir a mi lista de seguimiento las páginas que cree y los archivos que suba",
        "tog-watchdefault": "Añadir a mi lista de seguimiento las páginas y archivos que edite",
-       "tog-watchmoves": "Añadir a mi lista de seguimiento las páginas y archivos que mueva",
+       "tog-watchmoves": "Añadir a mi lista de seguimiento las páginas y archivos que traslade",
        "tog-watchdeletion": "Añadir las páginas y archivos que borre a mi lista de seguimiento",
        "tog-watchuploads": "Añadir a mi lista de seguimiento los archivos nuevos que suba",
        "tog-watchrollback": "Añadir a mi lista de seguimiento las páginas en las que haya realizado una reversión",
        "tog-enotifwatchlistpages": "Enviarme un mensaje de correo cuando se modifique una página o un archivo de mi lista de seguimiento",
        "tog-enotifusertalkpages": "Enviarme un mensaje de correo cuando se modifique mi página de discusión",
        "tog-enotifminoredits": "Notificarme también por correo electrónico los cambios menores de las páginas y archivos",
-       "tog-enotifrevealaddr": "Revelar mi dirección de correo electrónico en los correos de notificación",
+       "tog-enotifrevealaddr": "Mostrar mi dirección de correo electrónico en los correos de notificación",
        "tog-shownumberswatching": "Mostrar el número de usuarios que la vigilan",
        "tog-oldsig": "Tu firma actual:",
        "tog-fancysig": "Tratar la firma como wikitexto (sin un enlace automático)",
        "underline-default": "Configuración predeterminada de la apariencia o el navegador",
        "editfont-style": "Tipo de letra del área de edición:",
        "editfont-monospace": "Tipo de letra monoespaciado",
-       "editfont-sansserif": "Tipo de letra de palo seco",
-       "editfont-serif": "Tipo de letra con serifas",
+       "editfont-sansserif": "Tipo de letra Sans-serif",
+       "editfont-serif": "Tipo de letra con Serif",
        "sunday": "domingo",
        "monday": "lunes",
        "tuesday": "martes",
        "index-category": "Páginas indizadas",
        "noindex-category": "Páginas no indizadas",
        "broken-file-category": "Páginas con enlaces rotos a archivos",
+       "categoryviewer-pagedlinks": "($1) ($2)",
+       "category-header-numerals": "$1–$2",
        "about": "Acerca de",
        "article": "Página de contenido",
        "newwindow": "(se abre en una ventana nueva)",
        "versionrequired": "Se requiere la versión $1 de MediaWiki",
        "versionrequiredtext": "Se necesita la versión $1 de MediaWiki para utilizar esta página. Para más información, consulta [[Special:Version|la página de versión]].",
        "ok": "Aceptar",
+       "pagetitle": "$1 - {{SITENAME}}",
+       "pagetitle-view-mainpage": "{{SITENAME}}",
+       "backlinksubtitle": "← $1",
        "retrievedfrom": "Obtenido de «$1»",
        "youhavenewmessages": "{{PLURAL:$3|Tienes}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Tienes}} $1 de {{PLURAL:$3|otro usuario|$3 usuarios}} ($2).",
        "page-rss-feed": "Canal RSS de «$1»",
        "page-atom-feed": "Canal Atom de «$1»",
        "feed-atom": "Atom",
+       "feed-rss": "RSS",
        "red-link-title": "$1 (la página no existe)",
        "sort-descending": "Orden descendente",
        "sort-ascending": "Orden ascendente",
        "badarticleerror": "Esta acción no se puede llevar a cabo en esta página.",
        "cannotdelete": "No se ha podido borrar la página o archivo «$1».\nPuede que ya haya sido borrado por otro usuario.",
        "cannotdelete-title": "No se puede borrar la página «$1»",
+       "delete-scheduled": "La página «$1» está programada para su borrado.\nPor favor se paciente.",
        "delete-hook-aborted": "Una extensión ha evitado el borrado de la página. No hay explicación disponible.",
-       "no-null-revision": "No se pudo crear una nueva revisión nula para la página «$1»",
+       "no-null-revision": "No se pudo crear una nueva revisión nula en la página «$1»",
        "badtitle": "Título incorrecto",
        "badtitletext": "El título de la página solicitada no es válido, está vacío, o es un título entre idiomas o interwiki incorrectamente vinculado.\nPuede que contenga uno o más caracteres que no se pueden usar en los títulos.",
        "title-invalid-empty": "El título de la página solicitada está vacío o contiene solo el nombre de un espacio de nombres.",
        "protectedpagetext": "Esta página ha sido protegida para evitar su edición u otras acciones.",
        "viewsourcetext": "Puedes ver y copiar el código fuente de esta página.",
        "viewyourtext": "Puedes ver y copiar el código de <strong>tus ediciones</strong> en esta página.",
-       "protectedinterface": "Esta página proporciona el texto de la interfaz del software en este wiki, y está protegida para prevenir el abuso.\nPara agregar o cambiar las traducciones para todos los wikis, usa [https://translatewiki.net/ translatewiki.net], el proyecto de localización de MediaWiki.",
+       "protectedinterface": "Esta página proporciona el texto de la interfaz del software en este wiki y está protegido para evitar abusos.\nPara agregar o cambiar las traducciones para todos los wikis, usa [https://translatewiki.net/ translatewiki.net], el proyecto de localización de MediaWiki.",
        "editinginterface": "<strong>Advertencia:</strong> estás editando una página usada para proporcionar texto de la interfaz al software. \nLos cambios en esta página afectarán la apariencia de la interfaz de los demás usuarios de este wiki.",
        "translateinterface": "Para añadir o cambiar traducciones para todos los wikis, usa [https://translatewiki.net/ translatewiki.net], el proyecto de regionalización de MediaWiki.",
        "cascadeprotected": "Esta página ha sido protegida contra edición porque está transcluida en {{PLURAL:$1|la siguiente página protegida|las siguientes páginas protegidas}} con la opción de «cascada» activa:\n$2",
        "namespaceprotected": "No tienes permiso para editar las páginas del espacio de nombres <strong>$1</strong>.",
-       "customcssprotected": "No tienes permiso para editar esta página CSS, porque contiene configuraciones personales de otro usuario.",
+       "customcssprotected": "No tienes permiso para editar esta página CSS porque contiene configuraciones personales de otro usuario.",
        "customjsonprotected": "No tienes permiso para editar esta página JSON porque contiene configuraciones personales de otro usuario.",
-       "customjsprotected": "No tienes permiso para editar esta página JavaScript, porque contiene configuraciones personales de otro usuario.",
+       "customjsprotected": "No tienes permiso para editar esta página JavaScript porque contiene configuraciones personales de otro usuario.",
        "sitecssprotected": "No tienes permiso para editar esta página CSS porque puede afectar a todos los visitantes.",
        "sitejsonprotected": "No tienes permiso para editar esta página JSON porque puede afectar a todos los visitantes.",
        "sitejsprotected": "No tienes permiso para editar esta página de JavaScript porque puede afectar a todos los visitantes.",
        "userlogin-yourpassword": "Contraseña",
        "userlogin-yourpassword-ph": "Escribe tu contraseña",
        "createacct-yourpassword-ph": "Escribe una contraseña",
-       "yourpasswordagain": "Confirma la contraseña:",
+       "yourpasswordagain": "Repite la contraseña:",
        "createacct-yourpasswordagain": "Confirma la contraseña",
-       "createacct-yourpasswordagain-ph": "Repite la contraseña",
+       "createacct-yourpasswordagain-ph": "Introduce de nuevo la contraseña",
        "userlogin-remembermypassword": "Mantener mi sesión iniciada",
        "userlogin-signwithsecure": "Usar conexión segura",
        "cannotlogin-title": "No se puede iniciar sesión",
        "nocookiesnew": "Se ha creado la cuenta de usuario, pero aún no has iniciado sesión.\n{{SITENAME}} usa <em>cookies</em> para identificar a los usuarios registrados.\nTu navegador tiene desactivadas las cookies.\nPor favor, actívalas e inicia sesión con tu nuevo nombre de usuario y contraseña.",
        "nocookieslogin": "{{SITENAME}} utiliza <em>cookies</em> para la autenticación de usuarios. Las <em>cookies</em> están desactivadas en tu navegador. Por favor, actívalas e inténtalo de nuevo.",
        "nocookiesfornew": "No se pudo crear la cuenta de usuario, porque no pudimos confirmar su origen.\nAsegúrate de que tienes las cookies activadas, luego recarga esta página e inténtalo de nuevo.",
+       "nocookiesforlogin": "{{int:nocookieslogin}}",
        "createacct-loginerror": "La cuenta se ha creado correctamente, pero no se pudo ingresar automáticamente. Procede al [[Special:UserLogin|acceso manual]].",
        "noname": "No se ha especificado un nombre de usuario válido.",
        "loginsuccesstitle": "Has accedido",
        "passwordtooshort": "Las contraseñas deben tener al menos {{PLURAL:$1|1 carácter|$1 caracteres}}.",
        "passwordtoolong": "Las contraseñas no deben tener más de {{PLURAL:$1|1 carácter|$1 caracteres}}.",
        "passwordtoopopular": "No es posible utilizar las contraseñas más comunes. Elige una que sea más difícil de descifrar.",
-       "passwordinlargeblacklist": "La contraseña utilizada está en una lista de contraseñas usadas comúnmente. Por favor seleccione una contraseña más única.",
+       "passwordinlargeblacklist": "La contraseña usada está en la lista de contraseñas más usadas. Por favor selecciona una contraseña única.",
        "password-name-match": "Tu contraseña debe ser diferente de tu nombre de usuario.",
        "password-login-forbidden": "El uso de este nombre de usuario y contraseña han sido prohibidos.",
        "mailmypassword": "Restablecer la contraseña",
        "botpasswords-invalid-name": "El nombre de usuario especificado no contiene el separador de contraseña de bot («$1»).",
        "botpasswords-not-exist": "El usuario «$1» no tiene una contraseña de bot llamada «$2».",
        "botpasswords-needs-reset": "Se debe restablecer la contraseña del bot «$2», propiedad {{GENDER:$1|del usuario|de la usuaria}} «$1».",
+       "botpasswords-locked": "No puedes iniciar sesión con una contraseña de bot ya que tu cuenta está bloqueada.",
        "resetpass_forbidden": "No se pueden cambiar las contraseñas",
        "resetpass_forbidden-reason": "Las contraseñas no pueden cambiarse: $1",
        "resetpass-no-info": "Debes iniciar sesión para acceder directamente a esta página.",
        "resetpass-submit-loggedin": "Cambiar contraseña",
        "resetpass-submit-cancel": "Cancelar",
        "resetpass-wrong-oldpass": "La contraseña actual, o temporal, no es correcta.\nPuede que ya hayas cambiado tu contraseña o que hayas pedido una nueva contraseña temporal.",
-       "resetpass-recycled": "Cambia tu contraseña a algo distinto de tu contraseña actual.",
+       "resetpass-recycled": "Cambia tu contraseña por otra que no sea tu contraseña actual.",
        "resetpass-temp-emailed": "Has iniciado sesión con una contraseña temporal enviada por correo electrónico.\nPara continuar, debes establecer una nueva contraseña aquí:",
        "resetpass-temp-password": "Contraseña temporal:",
        "resetpass-abort-generic": "Una extensión ha cancelado el cambio de la contraseña.",
        "resetpass-expired": "Tu contraseña ha caducado. Por favor, establece una nueva contraseña para iniciar sesión.",
-       "resetpass-expired-soft": "Tu contraseña ha caducado, por lo que debes cambiarla. Elige ahora una contraseña nueva o pulsa en «{{int:authprovider-resetpass-skip-label}}» para cambiarla más tarde.",
+       "resetpass-expired-soft": "Tu contraseña ha caducado, por lo que debes cambiarla. Elige una contraseña nueva o pulsa en «{{int:authprovider-resetpass-skip-label}}» para cambiarla más tarde.",
        "resetpass-validity-soft": "La contraseña no es válida: $1\n\nCámbiala ahora por una nueva, o bien, pulsa en «{{int:authprovider-resetpass-skip-label}}» para cambiarla más tarde.",
        "passwordreset": "Restablecer contraseña",
        "passwordreset-text-one": "Completa este formulario para recibir una contraseña temporal por correo electrónico.",
        "passwordreset-emailelement": "Nombre de {{GENDER:$1|usuario|usuaria}}: \n$1\n\nContraseña temporal: \n$2",
        "passwordreset-emailsentemail": "Si esta dirección de correo electrónico está asociada a tu cuenta, entonces se enviará un correo electrónico para restablecer la contraseña.",
        "passwordreset-emailsentusername": "Si existe una dirección de correo electrónico asociada a este nombre de usuario, entonces se enviará un correo para restablecer la contraseña.",
-       "passwordreset-nocaller": "Debe de proporcionarse un interlocutor",
-       "passwordreset-nosuchcaller": "La persona que llama no existe: $1",
+       "passwordreset-nocaller": "Debes proporcionar un interlocutor",
+       "passwordreset-nosuchcaller": "El interlocutor no existe: $1",
        "passwordreset-ignored": "No se logró el reestablecimiento de la contraseña. ¿Tal vez no se configuró un proveedor?",
        "passwordreset-invalidemail": "Dirección de correo electrónico no válida.",
        "passwordreset-nodata": "No se ha proporcionado ni un nombre de usuario ni una dirección de correo electrónico",
        "resettokens-no-tokens": "No hay claves para restablecer.",
        "resettokens-tokens": "Claves:",
        "resettokens-token-label": "$1 (valor actual: $2)",
-       "resettokens-watchlist-token": "Clave para el canal (RSS/Atom) de los [[Special:Watchlist|cambios a las páginas en tu lista de seguimiento]]",
+       "resettokens-watchlist-token": "Clave del canal (Atom/RSS) de [[Special:Watchlist|cambios en las páginas de tu lista de seguimiento]]",
        "resettokens-done": "Restablecimiento de claves.",
        "resettokens-resetbutton": "Restablecer las claves",
        "bold_sample": "Texto en negrita",
        "subject-preview": "Previsualización del asunto:",
        "previewerrortext": "Se ha producido un error al intentar previsualizar tus cambios.",
        "blockedtitle": "El usuario está bloqueado",
-       "blockedtext": "<strong>Tu nombre de usuario o dirección IP ha sido bloqueada.</strong>\n\nEl bloqueo fue realizado por $1.\nEl motivo dado es el siguiente: <em>$2</em>.\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\nObserva que no puedes utilizar la función «{{int:emailuser}}» a menos que hayas registrado una dirección de correo electrónico válida en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\nTu dirección IP actual es $3, y el identificador del bloqueo es el n.º $5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
+       "blocked-email-user": "<strong>Tu usuario ha sido bloqueado para evitar el envío de correos electrónicos. Aún puedes editar otras páginas en este wiki.</strong> Puedes ver los detalles completos del bloqueo en [[Special:MyContributions|Contribuciones del usuario]].\n\nEl bloqueo fue realizado por $1.\n\nLa razón dada es <em>$2</em>.\n\n* Inicio de bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n* Id. del bloqueo n.º $5",
+       "blockedtext-partial": "<strong>Se ha bloqueado tu usuario o dirección IP para para evitar que realices cambios en esta página. Aún puedes editar otras páginas en este wiki.</strong> Puedes ver los detalles completos del bloqueo en [[Special:MyContributions|Contribuciones del usuario]].\n\nEl bloqueo fue realizado por $1.\n\nLa razón dada es <em>$2</em>.\n\n* Inicio de bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n* Id. del bloqueo n.º $5",
+       "blockedtext": "<strong>Se ha bloqueado tu nombre de usuario o dirección IP.</strong>\n\nEl bloqueo fue realizado por $1.\nEl motivo dado es el siguiente: <em>$2</em>.\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\nObserva que no puedes utilizar la función «{{int:emailuser}}» a menos que hayas registrado una dirección de correo electrónico válida en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\nTu dirección IP actual es $3, y el identificador del bloqueo es el n.º $5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
        "autoblockedtext": "Tu dirección IP ha sido bloqueada automáticamente porque fue utilizada por otro usuario, que resultó bloqueado por $1.\nEl motivo dado es el siguiente:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad del bloqueo: $6\n* Bloqueo destinado a: $7\n\nPuedes contactar con $1 o con otro de los [[{{MediaWiki:Grouppage-sysop}}|administradores]] para discutir el bloqueo.\n\nObserva que no puedes utilizar la función «{{int:emailuser}}» a menos que hayas registrado una dirección de correo electrónico válida en tus [[Special:Preferences|preferencias de usuario]] y la función no haya sido también bloqueada.\n\nTu dirección IP actual es $3, y el identificador del bloqueo es n.º $5.\nIncluye todos los datos aquí mostrados en cualquier consulta que hagas.",
        "systemblockedtext": "Tu nombre de usuario o dirección IP ha sido bloqueado automáticamente por el software MediaWiki.\nLa razón dada es:\n\n:<em>$2</em>\n\n* Inicio del bloqueo: $8\n* Caducidad de bloqueo: $6\n* Destinatario del bloqueo: $7\n\nTu dirección IP actual es $3.\nPor favor, incluye todos los datos aquí mostrados en cualquier consulta que hagas.",
        "blockednoreason": "no se ha especificado el motivo",
        "template-semiprotected": "(semiprotegida)",
        "hiddencategories": "Esta página pertenece a {{PLURAL:$1|1 categoría oculta|$1 categorías ocultas}}:",
        "edittools": "<!-- Este texto aparecerá bajo los formularios de edición y subida. -->",
+       "edittools-upload": "-",
        "nocreatetext": "{{SITENAME}} ha restringido la posibilidad de crear nuevas páginas.\nPuedes volver atrás y editar una página existente, [[Special:UserLogin|identificarte o crear una cuenta]].",
        "nocreate-loggedin": "No tienes permiso para crear páginas nuevas.",
        "sectioneditnotsupported-title": "Edición de sección no admitida",
        "content-model-text": "texto sin formato",
        "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
+       "content-model-json": "JSON",
        "content-json-empty-object": "Objeto vacío",
        "content-json-empty-array": "Matriz vacía",
        "deprecated-self-close-category": "Páginas que utilizan etiquetas HTML autocerradas no válidas",
        "cantcreateaccount-text": "[[User:$3|$3]] ha bloqueado la creación de cuentas desde esta dirección IP (<strong>$1</strong>).\n\nEl motivo dado por $3 es <em>$2</em>",
        "cantcreateaccount-range-text": "[[User:$3|$3]] ha bloqueado la creación de cuentas de usuario desde direcciones IP en el rango <strong>$1</strong>, en el que se encuentra tu dirección IP (<strong>$4</strong>).\n\nEl motivo dado por $3 es <em>$2</em>",
        "viewpagelogs": "Ver los registros de esta página",
-       "nohistory": "No hay historial de ediciones para esta página.",
+       "nohistory": "No hay historial de ediciones de esta página.",
        "currentrev": "Revisión actual",
        "currentrev-asof": "Revisión actual del $1",
        "revisionasof": "Revisión del $1",
        "historysize": "({{PLURAL:$1|1 byte|$1 bytes}})",
        "historyempty": "(vacío)",
        "history-feed-title": "Historial de revisiones",
-       "history-feed-description": "Historial de revisiones para esta página en el wiki",
+       "history-feed-description": "Historial de revisiones de esta página en el wiki",
        "history-feed-item-nocomment": "$1 en $2",
        "history-feed-empty": "La página solicitada no existe.\nPuede que haya sido renombrada o borrada del wiki.\nPrueba a [[Special:Search|buscar en el wiki]] otras páginas relacionadas.",
        "history-edit-tags": "Editar etiquetas de revisiones seleccionadas",
        "mergehistory-comment": "Se ha fusionado [[:$1]] en [[:$2]]: $3",
        "mergehistory-same-destination": "Las páginas origen y destino no pueden ser la misma",
        "mergehistory-reason": "Motivo:",
+       "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
        "mergelog": "Registro de fusiones",
        "revertmerge": "Deshacer fusión",
        "mergelogpagetext": "A continuación se muestra una lista de las fusiones de historiales más recientes.",
        "stub-threshold-disabled": "Desactivado",
        "recentchangesdays": "Días que mostrar en los cambios recientes:",
        "recentchangesdays-max": "Máximo {{PLURAL:$1|un día|$1 días}}",
-       "recentchangescount": "Número de ediciones que mostrar de manera predeterminada en Cambios recientes, los historiales de las páginas y en los registros:",
+       "recentchangescount": "Número de ediciones que mostrar de manera predeterminada en cambios recientes, en los historiales de las páginas y en los registros:",
        "prefs-help-recentchangescount": "Número máximo: 1000",
        "prefs-help-watchlist-token2": "Esta es la clave secreta del suministro web de tu lista de seguimiento.\nCualquiera que la conozca podrá consultar la lista, así que no la compartas.\n[[Special:ResetTokens|Puedes restablecerla si lo necesitas]].",
        "prefs-help-tokenmanagement": "Puedes ver y reiniciar la clave secreta que te permite ver tu lista de seguimiento vía Web. Cualquier persona que conozca dicha clave podrá ver tu lista de seguimiento. No la compartas.",
        "timezonelegend": "Huso horario:",
        "localtime": "Hora local:",
        "timezoneuseserverdefault": "Usar la hora del servidor ($1)",
-       "timezoneuseoffset": "Otro (especifica la diferencia horaria)",
+       "timezoneuseoffset": "Otro (especifica la diferencia horaria debajo)",
+       "timezone-useoffset-placeholder": "Valores de ejemplo: \"-07:00\" o \"01:00\"",
        "servertime": "Hora del servidor:",
        "guesstimezone": "Obtener del navegador",
        "timezoneregion-africa": "África",
        "youremail": "Correo electrónico:",
        "username": "{{GENDER:$1|Nombre de usuario|Nombre de usuaria}}:",
        "prefs-memberingroups": "{{GENDER:$2|Miembro}} {{PLURAL:$1|del grupo|de los grupos}}:",
+       "prefs-memberingroups-type": "$1",
        "group-membership-link-with-expiry": "$1 (hasta $2)",
        "prefs-registration": "Fecha y hora de registro:",
+       "prefs-registration-date-time": "$1",
        "yourrealname": "Nombre real:",
        "yourlanguage": "Idioma:",
        "yourvariant": "Variante lingüística del contenido:",
        "email": "Correo electrónico",
        "prefs-help-realname": "El nombre real es opcional.\nSi lo proporcionas, se usará para dar atribución a tu trabajo.",
        "prefs-help-email": "La dirección de correo electrónico es opcional, pero es necesaria para el restablecimiento de tu contraseña, en caso de que la olvides.",
-       "prefs-help-email-others": "También puedes permitir que otros usuarios te contacten por correo a través de un enlace en tus páginas de usuario y de discusión.\nTu dirección de correo no se revela cuando otros usuarios te contactan.",
+       "prefs-help-email-others": "También puedes permitir que otros usuarios contacten contigo por correo electrónico a través de un enlace en tu página de usuario o de discusión.\nTu dirección de correo no se muestra cuando otros usuarios se ponen en contacto contigo.",
        "prefs-help-email-required": "Es necesario proporcionar una dirección de correo electrónico.",
        "prefs-info": "Información básica",
        "prefs-i18n": "Internacionalización",
        "prefs-editor": "Editor",
        "prefs-preview": "Previsualización",
        "prefs-advancedrc": "Opciones avanzadas",
-       "prefs-opt-out": "Renunciar a las mejoras",
        "prefs-advancedrendering": "Opciones avanzadas",
        "prefs-advancedsearchoptions": "Opciones avanzadas",
        "prefs-advancedwatchlist": "Opciones avanzadas",
        "prefs-displayrc": "Opciones de visualización",
        "prefs-displaywatchlist": "Opciones de visualización",
+       "prefs-changesrc": "Cambios mostrados",
+       "prefs-changeswatchlist": "Cambios mostrados",
+       "prefs-pageswatchlist": "Páginas vistas",
        "prefs-tokenwatchlist": "Clave",
        "prefs-diffs": "Diferencias",
        "prefs-help-prefershttps": "Los cambios surtirán efecto en tu próximo inicio de sesión.",
        "saveusergroups": "Guardar grupos {{GENDER:$1|del usuario|de la usuaria}}",
        "userrights-groupsmember": "Miembro de:",
        "userrights-groupsmember-auto": "Miembro implícito de:",
+       "userrights-groupsmember-type": "$1",
        "userrights-groups-help": "Puedes modificar los grupos a los que pertenece {{GENDER:$1|este usuario|esta usuaria}}:\n* Una casilla marcada significa que {{GENDER:$1|el usuario|la usuaria}} está en ese grupo.\n* Una casilla sin marcar significa que {{GENDER:$1|el usuario|la usuaria}} no está en ese grupo.\n* Un * indica que no podrás eliminar el grupo una vez que lo añadas, o viceversa.\n* Un # indica que puedes únicamente postergar, y no adelantar, la fecha de caducidad de la membresía a este grupo.",
        "userrights-reason": "Motivo:",
        "userrights-no-interwiki": "No tienes permiso para editar permisos de usuario en otros wikis.",
        "userrights-nodatabase": "La base de datos $1 no existe o no es local.",
        "userrights-changeable-col": "Grupos que puedes cambiar",
        "userrights-unchangeable-col": "Grupos que no puedes cambiar",
+       "userrights-irreversible-marker": "$1*",
        "userrights-expiry-current": "Caduca el $1",
        "userrights-expiry-none": "No caduca",
        "userrights-expiry": "Caduca:",
        "grant-editprotected": "Editar páginas protegidas",
        "grant-highvolume": "Gran cantidad de ediciones",
        "grant-oversight": "Ocultar a los usuarios y suprimir las revisiones",
-       "grant-patrol": "Verificar cambios a páginas",
+       "grant-patrol": "Verificar cambios en páginas",
        "grant-privateinfo": "Acceder a información privada",
        "grant-protect": "Proteger y desproteger páginas",
-       "grant-rollback": "Revertir cambios a páginas",
+       "grant-rollback": "Revertir cambios en páginas",
        "grant-sendemail": "Enviar mensajes de correo a otros usuarios",
        "grant-uploadeditmovefile": "Subir, reemplazar y renombrar archivos",
        "grant-uploadfile": "Subir archivos nuevos",
        "action-suppressrevision": "revisar y restaurar revisiones ocultas",
        "action-suppressionlog": "ver este registro privado",
        "action-block": "bloquear a este usuario para que no edite",
-       "action-protect": "cambiar los niveles de protección para esta página",
+       "action-protect": "cambiar los niveles de protección en esta página",
        "action-rollback": "revertir rápidamente las ediciones del último usuario que modificó una página en particular",
        "action-import": "importar páginas desde otro wiki",
        "action-importupload": "importar páginas mediante la carga de un archivo",
        "rcfilters-liveupdates-button-title-off": "Mostar los cambios en tiempo real",
        "rcfilters-watchlist-markseen-button": "Marcar todos los cambios como vistos",
        "rcfilters-watchlist-edit-watchlist-button": "Edita tu lista de seguimiento",
-       "rcfilters-watchlist-showupdated": "Los cambios hechos a páginas que no has visitado desde que se efectuaron aparecen en <strong>negrita</strong>, acompañados de marcadores sólidos.",
-       "rcfilters-preference-label": "Ocultar la versión mejorada de cambios recientes",
-       "rcfilters-preference-help": "Revierte el rediseño de la interfaz de 2017 y desactiva todas las herramientas añadidas desde entonces.",
-       "rcfilters-watchlist-preference-label": "Ocultar la versión mejorada de la lista de seguimiento",
-       "rcfilters-watchlist-preference-help": "Revierte el rediseño de la interfaz de 2017 y desactiva todas las herramientas añadidas desde entonces.",
+       "rcfilters-watchlist-showupdated": "Los cambios hechos en páginas que no has visitado desde que se efectuaron aparecen en <strong>negrita</strong>, acompañados de marcadores sólidos.",
+       "rcfilters-preference-label": "Usar la interfaz sin JavaScript",
+       "rcfilters-preference-help": "Cargar cambios recientes sin filtros ni la funcionalidad de resaltado.",
+       "rcfilters-watchlist-preference-label": "Usar interfaz sin JavaScript",
+       "rcfilters-watchlist-preference-help": "Cargar la lista de seguimiento sin filtros ni la funcionalidad de resaltado.",
        "rcfilters-filter-showlinkedfrom-label": "Mostrar cambios en páginas enlazadas desde",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Páginas enlazadas desde</strong> la página seleccionada",
        "rcfilters-filter-showlinkedto-label": "Mostrar cambios en páginas que enlazan a",
        "fileexists-thumbnail-yes": "El archivo parece ser una imagen de tamaño reducido ''(thumbnail)''. [[$1|thumb]]\nPor favor comprueba el archivo <strong>[[:$1]]</strong>.\nSi el archivo comprobado es la misma imagen a tamaño original no es necesario subir un thumbnail más.",
        "file-thumbnail-no": "El nombre del archivo comienza con <strong>$1</strong>.\nParece ser una imagen de tamaño reducido ''(thumbnail)''.\nSi tiene esta imagen a toda resolución súbala, si no, por favor cambie el nombre del archivo.",
        "fileexists-forbidden": "Ya existe un archivo con este nombre, y no puede ser grabado encima de otro. Si quiere subir su archivo de todos modos, por favor vuelva atrás y utilice otro nombre. [[File:$1|thumb|center|$1]]",
-       "fileexists-shared-forbidden": "Ya existe un archivo con este nombre en el repositorio compartido.\nSi todavía quiere subir su archivo, por favor, regrese a la página anterior y use otro nombre. [[File:$1|thumb|center|$1]]",
+       "fileexists-shared-forbidden": "Ya existe un archivo con este nombre en el repositorio compartido.\nSi todavía quieres subir tu archivo, por favor, regresa a la página anterior y usa otro nombre. [[File:$1|thumb|center|$1]]",
        "fileexists-no-change": "Este es un duplicado exacto de la versión actual de <strong>[[:$1]]</strong>.",
        "fileexists-duplicate-version": "Este es un duplicado exacto de {{PLURAL:$2|una versión anterior|versiones anteriores}} de <strong>[[:$1]]</strong>.",
        "file-exists-duplicate": "Este archivo es un duplicado {{PLURAL:$1|del siguiente|de los siguientes}}:",
        "file-deleted-duplicate": "Un archivo idéntico a este ([[:$1]]) ha sido borrado con anterioridad. Debes comprobar el historial de borrado del archivo ante de volver a subirlo.",
-       "file-deleted-duplicate-notitle": "Un archivo idéntico a este ha sido borrado con anterioridad, y el título ha sido suprimido. Deberías contactar con alguien capaz de ver los datos de archivos borrados para que revise esta situación antes de proceder a subir de nuevo este archivo.",
+       "file-deleted-duplicate-notitle": "Un archivo idéntico a este ha sido borrado con anterioridad y el título ha sido suprimido. Deberías contactar con alguien capaz de ver los datos de archivos borrados para que revise esta situación antes de proceder a subir de nuevo este archivo.",
        "uploadwarning": "Alerta de carga",
        "uploadwarning-text": "Modifica la descripción del archivo abajo indicada e inténtalo de nuevo.",
        "uploadwarning-text-nostash": "Carga el archivo una vez más, modifica la descripción siguiente e inténtalo de nuevo.",
        "prefixindex": "Todas las páginas con prefijo",
        "prefixindex-namespace": "Todas las páginas con el prefijo (espacio de nombres $1)",
        "prefixindex-submit": "Mostrar",
-       "prefixindex-strip": "Quitar prefijos en la lista",
+       "prefixindex-strip": "Ocultar el prefijo en los resultados",
        "shortpages": "Páginas cortas",
        "longpages": "Páginas largas",
        "deadendpages": "Páginas sin salida",
        "apisandbox-dynamic-parameters-add-label": "Añadir parámetro:",
        "apisandbox-dynamic-parameters-add-placeholder": "Nombre del parámetro",
        "apisandbox-dynamic-error-exists": "Ya existe un parámetro llamado \"$1\".",
+       "apisandbox-templated-parameter-reason": "Esta [[Special:ApiHelp/main#main/templatedparams|plantilla de parámetros]] se ofrece en función {{PLURAL:$1|del valor|de los valores}} de $2.",
        "apisandbox-deprecated-parameters": "Parámetros en desuso",
        "apisandbox-fetch-token": "Rellenar la ficha automáticamente",
        "apisandbox-add-multi": "Añadir",
        "apisandbox-request-selectformat-label": "Mostrar los datos de la petición como:",
        "apisandbox-request-format-url-label": "Cadena de consulta de la URL",
        "apisandbox-request-url-label": "Petición URL:",
+       "apisandbox-request-format-json-label": "JSON",
        "apisandbox-request-json-label": "Petición JSON:",
        "apisandbox-request-time": "Tiempo de solicitud: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Corrige el token y vuelve a enviar",
        "enotif_lastvisited": "Consulta $1 para ver todos los cambios desde tu última visita",
        "enotif_lastdiff": "Consulta $1 para ver este cambio",
        "enotif_anon_editor": "usuario anónimo $1",
-       "enotif_body": "Hola, $WATCHINGUSERNAME:\n\n$PAGEINTRO $NEWPAGE\n\nResumen del editor: $PAGESUMMARY $PAGEMINOREDIT\n\nContacta con el editor:\ncorreo: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nNo enviaremos más notificaciones si ocurre más actividad, a menos que visites esta página con la sesión iniciada. También puedes restablecer los estados de notificación para todas las páginas en tu lista de seguimiento.\n\nAtentamente, el sistema de notificaciones de {{SITENAME}}\n\n--\nPara cambiar tus ajustes de notificación por correo, visita\n{{canonicalurl:{{#special:Preferences}}}}\n\nPara cambiar los ajustes de tu lista de seguimiento, visita\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPara quitar la página de tu lista de seguimiento, visita\n$UNWATCHURL\n\nPara ayuda y comentarios:\n$HELPPAGE",
+       "enotif_body": "Hola, $WATCHINGUSERNAME:\n\n$PAGEINTRO $NEWPAGE\n\nResumen del editor: $PAGESUMMARY $PAGEMINOREDIT\n\nContacta con el editor:\ncorreo: $PAGEEDITOR_EMAIL\nwiki: $PAGEEDITOR_WIKI\n\nNo enviaremos más notificaciones si ocurre más actividad, a menos que visites esta página con la sesión iniciada. También puedes restablecer los estados de notificación en todas las páginas de tu lista de seguimiento.\n\nAtentamente, el sistema de notificaciones de {{SITENAME}}\n\n--\nPara cambiar tus ajustes de notificación por correo, visita\n{{canonicalurl:{{#special:Preferences}}}}\n\nPara cambiar los ajustes de tu lista de seguimiento, visita\n{{canonicalurl:{{#special:EditWatchlist}}}}\n\nPara quitar la página de tu lista de seguimiento, visita\n$UNWATCHURL\n\nPara ayuda y comentarios:\n$HELPPAGE",
        "enotif_minoredit": "Esta es una edición menor",
        "created": "creada",
        "changed": "modificada",
        "ipaddressorusername": "Dirección IP o nombre de usuario:",
        "ipbexpiry": "Caducidad:",
        "ipbreason": "Motivo:",
-       "ipbreason-dropdown": "*Motivos comunes de bloqueo\n** Añadir información falsa\n** Eliminar contenido de las páginas\n** Publicitar enlaces a otras páginas web\n** Añadir basura a las páginas\n** Comportamiento intimidatorio u hostil\n** Abuso de múltiples cuentas\n** Nombre de usuario inaceptable",
+       "ipbreason-dropdown": "*Motivos comunes de bloqueo\n** Añadir información falsa\n** Eliminar contenido de las páginas\n** Publicitar enlaces a otras páginas web\n** Añadir basura en las páginas\n** Comportamiento intimidatorio u hostil\n** Abuso de múltiples cuentas\n** Nombre de usuario inaceptable",
        "ipb-hardblock": "Impedir que los usuarios identificados editen desde esta dirección IP",
        "ipbcreateaccount": "Prevenir la creación de cuentas de usuario",
        "ipbemailban": "Impedir que el usuario envíe correo electrónico",
        "ipb-disableusertalk": "Impedir que este usuario edite su propia página de discusión mientras esté bloqueado",
        "ipb-change-block": "Rebloquear al usuario con estos datos",
        "ipb-confirm": "Confirmar bloqueo",
+       "ipb-sitewide": "En todo el sitio",
+       "ipb-partial": "Parcial",
+       "ipb-type-label": "Tipo",
        "ipb-pages-label": "Páginas",
        "badipaddress": "La dirección IP no tiene el formato correcto.",
        "blockipsuccesssub": "Bloqueo realizado con éxito",
        "emailblock": "correo electrónico bloqueado",
        "blocklist-nousertalk": "no puede editar su propia página de discusión",
        "blocklist-editing": "editando",
+       "blocklist-editing-sitewide": "edición (en todo el sitio)",
        "ipblocklist-empty": "La lista de bloqueos está vacía.",
        "ipblocklist-no-results": "El nombre de usuario o IP indicado no está bloqueado.",
        "blocklink": "bloquear",
        "move-watch": "Vigilar páginas de origen y destino",
        "movepagebtn": "Trasladar la página",
        "pagemovedsub": "Traslado realizado con éxito",
+       "cannotmove": "La página podría no trasladarse por {{PLURAL:$1|el siguiente motivo|los siguientes motivos}}:",
        "movepage-moved": "<strong>«$1» ha sido trasladada a «$2»</strong>",
        "movepage-moved-redirect": "Se ha creado una redirección.",
        "movepage-moved-noredirect": "Se ha suprimido la creación de la redirección.",
+       "movepage-delete-first": "La página de destino tiene demasiadas revisiones a eliminar como parte de una página trasladada. Primero elimina la página de forma manual y a continuación inténtalo de nuevo.",
        "articleexists": "Ya existe una página con ese nombre o el nombre que elegiste no es válido.\nElige otro nombre.",
        "cantmove-titleprotected": "No puedes trasladar la página a esta ubicación, porque el nuevo título ha sido protegido para evitar su creación.",
        "movetalk": "Renombrar la página de discusión asociada",
        "import-interwiki-text": "Selecciona un wiki y un título de página para importar.\nLas fechas de revisiones y los nombres de editores se preservarán.\nTodas las importaciones de otros wikis se registran en el [[Special:Log/import|registro de importaciones]].",
        "import-interwiki-sourcewiki": "Wiki de origen:",
        "import-interwiki-sourcepage": "Página de origen:",
-       "import-interwiki-history": "Copiar todas las versiones históricas para esta página",
+       "import-interwiki-history": "Copiar todas las versiones históricas de esta página",
        "import-interwiki-templates": "Incluir todas las plantillas",
        "import-interwiki-submit": "Importar",
        "import-mapping-default": "Importar a ubicaciones predeterminadas",
        "tooltip-ca-protect": "Proteger esta página",
        "tooltip-ca-unprotect": "Cambiar protección de esta página",
        "tooltip-ca-delete": "Borrar esta página",
-       "tooltip-ca-undelete": "Restaurar las ediciones hechas a esta página antes de que fuese borrada",
+       "tooltip-ca-undelete": "Restaurar las ediciones hechas en esta página antes de que fuese borrada",
        "tooltip-ca-move": "Trasladar esta página",
        "tooltip-ca-watch": "Añadir esta página a tu lista de seguimiento",
        "tooltip-ca-unwatch": "Quitar esta página de tu lista de seguimiento",
        "siteusers": "{{PLURAL:$2|{{GENDER:$1|el usuario|la usuaria}}|los usuarios}} $1 de {{SITENAME}}",
        "anonusers": "{{PLURAL:$2|el usuario anónimo|los usuarios anónimos}} $1 de {{SITENAME}}",
        "creditspage": "Créditos de la página",
-       "nocredits": "No hay información de créditos para esta página.",
+       "nocredits": "No hay información de créditos en esta página.",
        "spamprotectiontitle": "Filtro de protección contra spam",
        "spamprotectiontext": "La página que quería guardar fue bloqueada por el filtro de spam.\nEsto podría estar causado por un enlace a un sitio externo incluido en la lista negra.",
        "spamprotectionmatch": "El siguiente texto es el que activó nuestro filtro de spam: $1",
        "previousdiff": "← Edición anterior",
        "nextdiff": "Edición siguiente →",
        "mediawarning": "<strong>Atención:</strong> este archivo puede contener código malicioso.\nEjecutarlo podría comprometer la seguridad de tu equipo.",
-       "imagemaxsize": "Límite de tamaño de imagen:<br />''(para páginas de descripción de archivo)''",
+       "imagemaxsize": "Límite de tamaño de imagen en páginas de descripción de archivo:",
        "thumbsize": "Tamaño de las vistas en miniatura:",
        "widthheight": "$1 × $2",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:|página|páginas}}",
        "confirm-unwatch-button": "Aceptar",
        "confirm-unwatch-top": "¿Quitar esta página de tu lista de seguimiento?",
        "confirm-rollback-button": "Aceptar",
-       "confirm-rollback-top": "¿Revertir las ediciones a esta página?",
+       "confirm-rollback-top": "¿Revertir las ediciones en esta página?",
        "confirm-mcrrestore-title": "Restaurar la revisión",
        "confirm-mcrundo-title": "Deshacer un cambio",
        "mcrundofailed": "Error al deshacer",
        "mcrundo-missingparam": "Faltan parámetros requeridos en la solicitud.",
        "mcrundo-changed": "La página ha sido cambiada desde que viste el diff. Por favor revisa el nuevo cambio.",
+       "mcrundo-parse-failed": "Error al analizar la nueva revisión: $1",
        "comma-separator": ",&#32;",
        "ellipsis": "…",
        "percent": "$1 %",
        "autosumm-changed-redirect-target": "Se cambió el destino de la redirección de [[$1]] a [[$2]]",
        "autosumm-new": "Página creada con «$1»",
        "autosumm-newblank": "Se creó una página vacía",
+       "size-pixel": "$1 {{PLURAL:$1|píxel|píxeles}}",
        "lag-warn-normal": "Los cambios realizados en {{PLURAL:$1|el último segundo|los últimos $1 segundos}} podrían no mostrarse en esta lista.",
        "lag-warn-high": "Debido a una alta latencia el servidor de base de datos, los cambios realizados en {{PLURAL:$1|el último segundo|los últimos $1 segundos}} podrían no mostrarse en esta lista.",
        "watchlistedit-normal-title": "Editar lista de seguimiento",
        "logentry-block-block": "$1 {{GENDER:$2|bloqueó}} a {{GENDER:$4|$3}} durante un plazo de $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|desbloqueó}} a {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 {{GENDER:$2|cambió}} la configuración del bloqueo de {{GENDER:$4|$3}} durante un plazo de $5 $6",
+       "logentry-partialblock-block": "$1 {{GENDER:$2|bloqueó}} a {{GENDER:$4|$3}} la edición en {{PLURAL:$8|la página|las páginas}} $7 por un tiempo de caducidad de $5 $6",
+       "logentry-partialblock-reblock": "$1 {{GENDER:$2|cambió}} la configuración del bloqueo a {{GENDER:$4|$3}} impidiendo la edición en {{PLURAL:$8|la página|las páginas}} $7 por un tiempo de caducidad de $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|bloqueó}} a {{GENDER:$4|$3}} durante un plazo de $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|cambió}} la configuración del bloqueo de {{GENDER:$4|$3}} durante un plazo de $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importó}} $3 subiendo un archivo",
        "feedback-close": "Hecho",
        "feedback-external-bug-report-button": "Enviar una tarea técnica",
        "feedback-dialog-title": "Enviar comentarios",
-       "feedback-dialog-intro": "Puedes usar el formulario sencillo debajo para enviar tus comentarios. Ellos se agregarán a la página \"$1\", junto con tu nombre de usuario.",
+       "feedback-dialog-intro": "Puedes usar el sencillo formulario a continuación para enviar tus comentarios. Tu comentario se añadirá a la página «$1», junto con tu nombre de usuario.",
        "feedback-error1": "Error: No se reconoce resultado de API",
        "feedback-error2": "Error: Falló la edición",
        "feedback-error3": "Error: No hay respuesta de la API",
        "special-characters-title-endash": "semirraya",
        "special-characters-title-emdash": "raya",
        "special-characters-title-minus": "signo de resta",
-       "mw-widgets-abandonedit": "¿Estás seguro de quieres salir del modo de edición sin guardar primero?",
+       "mw-widgets-abandonedit": "¿Seguro que deseas abandonar el modo de edición sin guardar primero?",
        "mw-widgets-abandonedit-discard": "Descartar ediciones",
        "mw-widgets-abandonedit-keep": "Continuar editando",
-       "mw-widgets-abandonedit-title": "¿Lo confirmas?",
+       "mw-widgets-abandonedit-title": "¿Seguro?",
        "mw-widgets-dateinput-no-date": "Ninguna fecha seleccionada",
        "mw-widgets-dateinput-placeholder-day": "AAAA-MM-DD",
        "mw-widgets-dateinput-placeholder-month": "AAAA-MM",
        "mw-widgets-titleinput-description-redirect": "redirigir a $1",
        "mw-widgets-categoryselector-add-category-placeholder": "Agregar una categoría...",
        "mw-widgets-usersmultiselect-placeholder": "Añadir más…",
+       "mw-widgets-titlesmultiselect-placeholder": "Añadir más...",
        "date-range-from": "Desde la fecha:",
        "date-range-to": "Hasta la fecha:",
        "sessionmanager-tie": "No se pueden combinar múltiples tipos de autenticación de solicitudes: $1.",
        "authmanager-provider-password-domain": "Autenticación basada en contraseña y dominio",
        "authmanager-provider-temporarypassword": "Contraseña temporal",
        "authprovider-confirmlink-message": "Basado en tus últimos intentos para iniciar sesión, las siguientes cuentas pueden vincularse a tu cuenta wiki. Vincularlas permite iniciar sesión a través de esas cuentas. Selecciona cuáles deben vincularse.",
+       "authprovider-confirmlink-option": "$1 ($2)",
        "authprovider-confirmlink-request-label": "Cuentas que deberían vincularse",
        "authprovider-confirmlink-success-line": "$1: vinculado exitosamente.",
+       "authprovider-confirmlink-failed-line": "$1: $2",
        "authprovider-confirmlink-failed": "La vinculación de cuentas no se ha realizado con éxito: $1",
        "authprovider-confirmlink-ok-help": "Continuar luego de mostrar los mensajes de error en la vinculación.",
        "authprovider-resetpass-skip-label": "Omitir",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "La contraseña no puede coincidir con la lista de contraseñas específicamente prohibidas",
        "passwordpolicies-policy-maximalpasswordlength": "La contraseña no puede tener más de $1 {{PLURAL:$1|caracter|caracteres}}",
        "passwordpolicies-policy-passwordcannotbepopular": "La contraseña no puede {{PLURAL:$1|ser la contraseña más popular|encontrarse en la lista de $1 contraseñas populares}}",
-       "passwordpolicies-policy-passwordnotinlargeblacklist": "La contraseña no puede estar en la lista de las 100.000 contraseñas utilizadas más comúnmente.",
-       "easydeflate-invaliddeflate": "El contenido proporcionado no esta comprimido correctamente"
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "La contraseña no puede estar en la lista de las 100.000 contraseñas más usadas.",
+       "easydeflate-invaliddeflate": "El contenido proporcionado no esta comprimido correctamente",
+       "unprotected-js": "Por razones de seguridad, JavaScript no se puede cargar desde páginas desprotegidas. Crea javascript solo en MediaWiki: espacio de nombres o como subpágina de usuario"
 }
index c16f510..2e20801 100644 (file)
        "passwordtooshort": "Parool peab koosnema vähemalt {{PLURAL:$1|ühest|$1}} tähemärgist.",
        "passwordtoolong": "Parool ei saa olla pikem kui {{PLURAL:$1|üks märk|$1 märk}}.",
        "passwordtoopopular": "Liiga levinud paroole ei saa kasutada. Palun vali parool, mida on keerulisem ära arvata.",
+       "passwordinlargeblacklist": "Sisestatud parool on väga sageli kasutatud paroolide loendis. Palun vali haruldasem parool.",
        "password-name-match": "Parool peab kasutajanimest erinema.",
        "password-login-forbidden": "Selle kasutajanime ja parooli kasutamine on keelatud.",
        "mailmypassword": "Lähtesta parool",
        "prefs-editor": "Toimeti",
        "prefs-preview": "Eelvaade",
        "prefs-advancedrc": "Täpsemad eelistused",
-       "prefs-opt-out": "Täiustustest äraütlemine",
        "prefs-advancedrendering": "Täpsemad eelistused",
        "prefs-advancedsearchoptions": "Täpsemad eelistused",
        "prefs-advancedwatchlist": "Täpsemad eelistused",
        "prefs-displayrc": "Kuvasätted",
        "prefs-displaywatchlist": "Kuvasätted",
+       "prefs-changesrc": "Näidatavad muudatused",
+       "prefs-changeswatchlist": "Näidatavad muudatused",
+       "prefs-pageswatchlist": "Jälgitavad leheküljed",
        "prefs-tokenwatchlist": "Luba",
        "prefs-diffs": "Erinevused",
        "prefs-help-prefershttps": "See eelistus jõustub pärast järgmist sisselogimist.",
        "rcfilters-watchlist-markseen-button": "Märgi kõik muudatused nähtuks",
        "rcfilters-watchlist-edit-watchlist-button": "Muuda jälgimisloendit",
        "rcfilters-watchlist-showupdated": "Muudatused lehekülgedel, mida sa pole pärast muudatuste tegemist külastanud, on <strong>rasvases</strong> kirjas ja tähistatud täidetud punktiga.",
-       "rcfilters-preference-label": "Peida viimaste muudatuste täiustatud versioon",
-       "rcfilters-preference-help": "Pöörab tagasi 2017. aastast alates tehtud muudatused kujunduses ja lisatud tööriistad.",
-       "rcfilters-watchlist-preference-label": "Peida jälgimisloendi täiustatud versioon",
-       "rcfilters-watchlist-preference-help": "Pöörab tagasi 2017. aastast alates tehtud muudatused kujunduses ja lisatud tööriistad.",
+       "rcfilters-preference-label": "Kasuta JavaScripti-vaba liidest",
+       "rcfilters-preference-help": "Laadib viimased muudatused ilma filtrite ja esiletõstmise võimaluseta.",
+       "rcfilters-watchlist-preference-label": "Kasuta JavaScripti-vaba liidest",
+       "rcfilters-watchlist-preference-help": "Laadib jälgimisloendi ilma filtrite ja esiletõstmise võimaluseta.",
        "rcfilters-filter-showlinkedfrom-label": "Näita muudatusi lehekülgedel, millele viidatakse leheküljelt:",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Leheküljed, millele viidatakse</strong> valitud leheküljel",
        "rcfilters-filter-showlinkedto-label": "Näita muudatusi lehekülgedel, millel viidatakse leheküljele",
        "move-watch": "Jälgi lähte- ja sihtlehekülge",
        "movepagebtn": "Teisalda lehekülg",
        "pagemovedsub": "Lehekülg on teisaldatud",
+       "cannotmove": "Lehekülge ei õnnestunud teisaldada {{PLURAL:$1|järgmisel põhjusel|järgmistel põhjustel}}:",
        "movepage-moved": "<strong>\"$1\" on teisaldatud pealkirja \"$2\" alla.</strong>",
        "movepage-moved-redirect": "Ümbersuunamisleht loodud.",
        "movepage-moved-noredirect": "Ümbersuunamist ei loodud.",
        "pageinfo-category-files": "Faile",
        "pageinfo-user-id": "Kasutaja identifikaator",
        "pageinfo-file-hash": "Räsiväärtus",
-       "pageinfo-view-protect-log": "Vaata selle lehekülje kaitsmislogi.",
+       "pageinfo-view-protect-log": "Vaata selle lehekülje kaitsmislogi",
        "markaspatrolleddiff": "Märgi kontrollituks",
        "markaspatrolledtext": "Märgi see leht kontrollituks",
        "markaspatrolledtext-file": "Märgi see failiversioon kontrollituks",
        "logentry-block-reblock": "$1 {{GENDER:$2|muutis}} kasutaja {{GENDER:$4|$3}} blokeeringut; aegumistähtaeg $5 $6",
        "logentry-partialblock-block": "$1 {{GENDER:$2|blokeeris}} kasutaja {{GENDER:$4|$3}} redigeerimast {{PLURAL:$8|lehekülge|lehekülgi}} $7; aegumistähtaeg $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|muutis}} kasutaja {{GENDER:$4|$3}} blokeeringut, mis takistab redigeerimist {{PLURAL:$8|leheküljel|lehekülgedel}} $7; aegumistähtaeg $5 $6",
-       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokeeris}} kasutaja {{GENDER:$4|$3}} tegemast teisi tegevusi peale redigeerimise; aegumistähtaeg $5 $6",
-       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|muutis}} kasutaja {{GENDER:$4|$3}} blokeeringut, mis takistab tegemast teisi tegevusi peale redigeerimise; aegumistähtaeg $5 $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokeeris}} kasutaja {{GENDER:$4|$3}} tegemast määratud tegevusi peale redigeerimise; aegumistähtaeg $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|muutis}} kasutaja {{GENDER:$4|$3}} blokeeringut, mis takistab tegemast määratud tegevusi peale redigeerimise; aegumistähtaeg $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blokeeris}} kasutaja {{GENDER:$4|$3}}; aegumistähtaeg $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|muutis}} kasutaja {{GENDER:$4|$3}} blokeeringut; aegumistähtaeg $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importis}} lehekülje $3 faili üleslaadimise teel",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Parool ei tohi olla kantud musta nimekirja.",
        "passwordpolicies-policy-maximalpasswordlength": "Parool peab olema $1 {{PLURAL:$1|märgist}} lühem.",
        "passwordpolicies-policy-passwordcannotbepopular": "Parool ei tohi olla {{PLURAL:$1|populaarne parool|$1 populaarse parooli loendis}}.",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Parool ei saa olla 100&nbsp;000 kõige levinuma parooli loendis.",
        "easydeflate-invaliddeflate": "Ette antud sisu ei ole õigesti vähendatud",
        "unprotected-js": "Turvalisuse huvides ei saa JavaScripti laadida kaitsmata lehekülgedelt. Palun koosta JavaScripti ainult nimeruumis MediaWiki või kasutajate nimeruumi alamleheküljel."
 }
index e69c96d..a9c05f6 100644 (file)
        "prefs-editor": "Editorea",
        "prefs-preview": "Aurreikusi",
        "prefs-advancedrc": "Aukera aurreratuak",
-       "prefs-opt-out": "Hobekuntzarik gabeko Opt",
        "prefs-advancedrendering": "Aukera aurreratuak",
        "prefs-advancedsearchoptions": "Aukera aurreratuak",
        "prefs-advancedwatchlist": "Aukera aurreratuak",
index 3871d18..590df32 100644 (file)
@@ -69,7 +69,8 @@
                        "Iriman",
                        "Matěj Suchánek",
                        "Amirsara",
-                       "Physicsch"
+                       "Physicsch",
+                       "Nbi"
                ]
        },
        "tog-underline": "خط کشیدن زیر پیوندها:",
        "badarticleerror": "نمی‌توان این عمل را بر این صفحه انجام داد.",
        "cannotdelete": "امکان حذف صفحه یا تصویر «$1» وجود ندارد.\nممکن است قبلاً فرد دیگری آن را حذف کرده باشد.",
        "cannotdelete-title": "نمی‌توان صفحهٔ «$1» را حذف کرد",
+       "delete-scheduled": "صفحه $1 برای حذف برنامه‌ریزی شده‌است. لطفاً صبور باشید.",
        "delete-hook-aborted": "حذف توسط قلاب لغو شد.\nتوضیحی در این مورد داده نشد.",
        "no-null-revision": "امکان ایجاد نسخهٔ پوچ تازه برای صفحهٔ «$1» وجود نداشت",
        "badtitle": "عنوان بد",
        "passwordtooshort": "گذرواژه باید دست‌کم {{PLURAL:$1|۱ حرف|$1 حرف}} داشته باشد.",
        "passwordtoolong": "گذرواژه نمی تواند حروفش بیشتر از {{PLURAL:$1|۱ حرف|$1 حرف}}  باشد.",
        "passwordtoopopular": "گذرواژه‌های متداول را نمی‌توانید استفاده کنید. لطفاً گذرواژه‌ای انتخاب کنید که حدس‌زدن آن سخت باشد.",
+       "passwordinlargeblacklist": "گذرواژه انتخابی در فهرست گذرواژه‌های معمول قرار دارد. لطفاً یک گذرواژه یکتاتر انتخاب کنید.",
        "password-name-match": "گذرواژهٔ شما باید با نام کاربری شما تفاوت داشته باشد.",
        "password-login-forbidden": "استفاده از این نام کاربری و گذرواژه ممنوع است.",
        "mailmypassword": "بازنشانی گذرواژه",
        "localtime": "زمان محلی:",
        "timezoneuseserverdefault": "استفاده از پیش‌فرض ویکی ($1)",
        "timezoneuseoffset": "دیگر (اختلاف را مشخص کنید)",
+       "timezone-useoffset-placeholder": "مثال مقادیر: \"-07:00\" یا \"01:00\"",
        "servertime": "زمان سرور:",
        "guesstimezone": "از مرورگر گرفته شود",
        "timezoneregion-africa": "آفریقا",
        "prefs-editor": "ویرایشگر",
        "prefs-preview": "پیش‌نمایش",
        "prefs-advancedrc": "گزینه‌های پیشرفته",
-       "prefs-opt-out": "گزینه برای بهبود",
        "prefs-advancedrendering": "گزینه‌های پیشرفته",
        "prefs-advancedsearchoptions": "گزینه‌های پیشرفته",
        "prefs-advancedwatchlist": "گزینه‌های پیشرفته",
        "redirect-file": "نام پرونده",
        "redirect-logid": "سیاهه شناسه",
        "redirect-not-exists": "مقدار پیدا نشد",
+       "redirect-not-numeric": "مقادیر غیر عددی",
        "fileduplicatesearch": "جستجو برای پرونده‌های تکراری",
        "fileduplicatesearch-summary": "جستجو برای پرونده‌های تکراری بر اساس مقدار درهم‌شدهٔ آن‌ها صورت می‌گیرد.",
        "fileduplicatesearch-filename": "نام پرونده:",
index c57c642..e54c2e1 100644 (file)
@@ -59,7 +59,8 @@
                        "Rueter",
                        "Kyykaarme",
                        "Surjection",
-                       "OneMember"
+                       "OneMember",
+                       "Valtlait"
                ]
        },
        "tog-underline": "Linkkien alleviivaus:",
        "versionrequiredtext": "MediaWikistä tarvitaan vähintään versio $1 tämän sivun käyttämiseen. Katso [[Special:Version|versio]].",
        "ok": "OK",
        "pagetitle": "$1 – {{SITENAME}}",
-       "retrievedfrom": "Noudettu kohteesta \"$1\"",
+       "retrievedfrom": "Noudettu kohteesta ”$1”",
        "youhavenewmessages": "Sinulle on $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Sinulle on}} $1 {{PLURAL:$3|toiselta käyttäjältä|$3 käyttäjältä}} ($2).",
        "youhavenewmessagesmanyusers": "Sinulle on $1 uusia viestejä useilta käyttäjiltä ($2).",
        "readonly": "Tietokanta on lukittu",
        "enterlockreason": "Anna lukituksen syy sekä sen arvioitu poistamisaika",
        "readonlytext": "Tietokanta on tällä hetkellä lukittu. Uusia sivuja ei voi luoda eikä muitakaan muutoksia tehdä. Syynä on todennäköisesti rutiininomainen tietokannan huoltaminen.\n\nTietokannan lukinneen palvelinjärjestelmän ylläpitäjän antama selitys on: $1",
-       "missing-article": "Sivun sisältöä ei löytynyt tietokannasta nimellä \"$1\" $2.\n\nYleensä tämä johtuu vanhentuneesta vertailu- tai historialinkistä sivulle, joka on poistettu.\n\nJos kyseessä ei ole poistettu sivu, olet ehkä löytänyt virheen ohjelmistossa.\nIlmoita tästä [[Special:ListUsers/sysop|ylläpitäjälle]] ja kerro viestissäsi sivun URL.",
+       "missing-article": "Sivun sisältöä ei löytynyt tietokannasta nimellä ”$1” $2.\n\nYleensä tämä johtuu vanhentuneesta vertailu- tai historialinkistä sivulle, joka on poistettu.\n\nJos kyseessä ei ole poistettu sivu, olet ehkä löytänyt virheen ohjelmistossa.\nIlmoita tästä [[Special:ListUsers/sysop|ylläpitäjälle]] ja kerro viestissäsi sivun URL.",
        "missingarticle-rev": "(versio nro: $1)",
        "missingarticle-diff": "(vertailu: $1, $2)",
        "readonly_lag": "Tietokanta on automaattisesti lukittu, jotta kaikki tietokantapalvelimet saisivat kaikki tuoreet muutokset",
        "nonwrite-api-promise-error": "HTTP-header 'Promise-Non-Write-API-Action' on lähetetty, mutta pyyntö oli kohdistettu API:n kirjoitusmoduuliin (API write module).",
        "internalerror": "Sisäinen virhe",
        "internalerror_info": "Sisäinen virhe: $1",
-       "internalerror-fatal-exception": "Vakava virhe, jonka tyyppi on \"$1\"",
+       "internalerror-fatal-exception": "Vakava virhe, jonka tyyppi on ”$1”",
        "filecopyerror": "Tiedostoa <b>$1</b> ei voitu kopioida tiedostoksi <b>$2</b>.",
        "filerenameerror": "Tiedostoa <b>$1</b> ei voitu nimetä uudelleen nimellä <b>$2</b>.",
        "filedeleteerror": "Tiedostoa <b>$1</b> ei voitu poistaa.",
        "formerror": "Lomakkeen tiedot eivät kelpaa",
        "badarticleerror": "Tätä toimintoa ei voi suorittaa tälle sivulle.",
        "cannotdelete": "Sivun tai tiedoston ”$1” poisto epäonnistui.\nJoku muu on saattanut poistaa sen.",
-       "cannotdelete-title": "Sivua \"$1\" ei voi poistaa",
-       "delete-scheduled": "Sivu \"$1\" on poistumassa piakkoin.\nOdota rauhassa.",
+       "cannotdelete-title": "Sivua ”$1” ei voi poistaa",
+       "delete-scheduled": "Sivu ”$1” on poistumassa piakkoin.\nOdota rauhassa.",
        "delete-hook-aborted": "Laajennuskoodi esti poiston antamatta syytä.",
-       "no-null-revision": "Nollamuokkausta sivulla \"$1\" ei voi tehdä",
+       "no-null-revision": "Nollamuokkausta sivulla ”$1” ei voi tehdä",
        "badtitle": "Kelvoton sivun nimi",
        "badtitletext": "Pyytämäsi sivunimi oli virheellinen, tyhjä tai väärin linkitetty kieltenvälinen tai wikienvälinen nimi.\nSiinä saattaa olla yksi tai useampi sellainen merkki, jota ei voi käyttää sivujen nimissä.",
        "title-invalid-empty": "Pyydetty sivunimi on tyhjä tai sisältää ainoastaan nimiavaruuden nimen.",
        "mypreferencesprotected": "Sinulla ei ole oikeutta muuttaa omia asetuksiasi.",
        "ns-specialprotected": "Toimintosivuja ei voi muokata.",
        "titleprotected": "Käyttäjä [[User:$1|$1]] on suojannut tämän sivunimen, ja sivua ei voi luoda.\nSuojauksen syy on: <em>$2</em>.",
-       "filereadonlyerror": "Tiedostoa \"$1\" ei voida muuttaa, koska jaettu mediavarasto \"$2\" on asetettu tilaan ''vain lukeminen sallittu''.\n\nTietokannan lukinneen palvelinjärjestelmän ylläpitäjän antama selitys on: $3.",
+       "filereadonlyerror": "Tiedostoa ”$1” ei voida muuttaa, koska jaettu mediavarasto \"$2\" on asetettu tilaan ''vain lukeminen sallittu''.\n\nTietokannan lukinneen palvelinjärjestelmän ylläpitäjän antama selitys on: $3.",
        "invalidtitle": "Virheellinen sivun nimi",
-       "invalidtitle-knownnamespace": "Virheellinen sivunimi, nimiavaruus \"$2\" ja teksti \"$3\"",
-       "invalidtitle-unknownnamespace": "Virheellinen sivunimi, tuntematon nimiavaruus numero $1 ja teksti \"$2\"",
+       "invalidtitle-knownnamespace": "Virheellinen sivunimi, nimiavaruus ”$2” ja teksti ”$3”",
+       "invalidtitle-unknownnamespace": "Virheellinen sivunimi, tuntematon nimiavaruus numero $1 ja teksti ”$2”",
        "exception-nologin": "Et ole kirjautunut sisään",
        "exception-nologin-text": "Ole hyvä ja kirjaudu sisään, niin pääset tälle sivulle tai tähän toimintoon.",
        "exception-nologin-text-manual": "Sinun pitää $1, jotta pääset tälle sivulle tai toimintoon.",
        "noname": "Et ole määritellyt kelvollista käyttäjänimeä.",
        "loginsuccesstitle": "Olet kirjautunut sisään",
        "loginsuccess": "'''Olet kirjautunut sivustolle {{SITENAME}} käyttäjänä $1.'''",
-       "nosuchuser": "Käyttäjää \"$1\" ei ole olemassa.\nNimet ovat kirjainkoosta riippuvaisia. \nTarkista kirjoititko nimen oikein, tai [[Special:CreateAccount|luo uusi käyttäjätunnus]].",
+       "nosuchuser": "Käyttäjää ”$1” ei ole olemassa.\nNimet ovat kirjainkoosta riippuvaisia. \nTarkista, kirjoititko nimen oikein, tai [[Special:CreateAccount|luo uusi käyttäjätunnus]].",
        "nosuchusershort": "Käyttäjää nimeltä ”$1” ei ole. Kirjoititko nimen oikein?",
        "nouserspecified": "Käyttäjätunnusta ei ole määritelty.",
        "login-userblocked": "Tämä käyttäjä on estetty. Kirjautuminen ei ole sallittua.",
        "passwordtooshort": "Salasanan täytyy olla vähintään {{PLURAL:$1|yhden merkin pituinen|$1 merkkiä pitkä}}.",
        "passwordtoolong": "Salasanat saavat olla enintään $1 {{PLURAL:$1|merkin}} pituisia.",
        "passwordtoopopular": "Tavanomaisen kaltaisia salasanoja ei saa käyttää. Valitse salasana, joka on vaikeampi arvata.",
+       "passwordinlargeblacklist": "Annettu salasana on erittäin yleisesti käytettyjen salasanojen listalla. Valitse yksilöllisempi salasana.",
        "password-name-match": "Salasanasi täytyy olla eri kuin käyttäjätunnuksesi.",
        "password-login-forbidden": "Tämän käyttäjänimen ja salasanan käyttö on estetty.",
        "mailmypassword": "Hanki uusi salasana",
        "accountcreated": "Käyttäjätunnus luotiin",
        "accountcreatedtext": "Käyttäjätunnus [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|keskustelu]]) luotiin.",
        "createaccount-title": "Tunnuksen luominen {{GRAMMAR:illative|{{SITENAME}}}}",
-       "createaccount-text": "Joku on luonut tunnuksen $2 {{GRAMMAR:illative|{{SITENAME}}}} ($4).\nTunnus on \"$2\" ja sen salasana on \"$3\". Sinun on syytä kirjautua sisään ja vaihtaa salasanasi heti.\n\nSinun ei tarvitse välittää tästä viestistä, jos tämä tunnus on luotu virheellisesti.",
+       "createaccount-text": "Joku on luonut tunnuksen $2 {{GRAMMAR:illative|{{SITENAME}}}} ($4).\nTunnus on ”$2” ja sen salasana on ”$3”. Sinun on syytä kirjautua sisään ja vaihtaa salasanasi heti.\n\nSinun ei tarvitse välittää tästä viestistä, jos tämä tunnus on luotu virheellisesti.",
        "login-throttled": "Olet tehnyt liian monta kirjautumisyritystä.\nOdota $1 ennen kuin yrität uudelleen.",
        "login-abort-generic": "Kirjautuminen epäonnistui – keskeytetty",
        "login-migrated-generic": "Tunnuksesi on siirretty, ja käyttäjänimeäsi ei löydy enää tästä wikistä.",
        "botpasswords-label-grants": "Valittavissa olevat toimintaoikeudet:",
        "botpasswords-help-grants": "Toimintaoikeudet sallivat pääsyn oikeuksiin, joita käyttäjätililläsi jo on. Toimintaoikeuden käyttöönotto täällä ei lisää käyttäjätilillesi oikeuksia, joita sillä ei jo ole. Lisätietoja löytyy [[Special:ListGrants|toimintaoikeuksien luettelosta]].",
        "botpasswords-label-grants-column": "Myönnetään",
-       "botpasswords-bad-appid": "Botin nimi \"$1\" ei kelpaa.",
-       "botpasswords-insert-failed": "Botin nimen \"$1\" lisääminen epäonnsitui. Onko se jo lisätty?",
-       "botpasswords-update-failed": "Botin nimen \"$1\" päivittäminen epäonnistui. Onko se poistettu?",
+       "botpasswords-bad-appid": "Botin nimi ”$1” ei kelpaa.",
+       "botpasswords-insert-failed": "Botin nimen ”$1” lisääminen epäonnistui. Onko se jo lisätty?",
+       "botpasswords-update-failed": "Botin nimen ”$1” päivittäminen epäonnistui. Onko se poistettu?",
        "botpasswords-created-title": "Bottisalasana luotu",
-       "botpasswords-created-body": "Bottisalasana {{GENDER:$2|käyttäjän}} \"$2\" bottinimelle \"$1\" luotiin.",
+       "botpasswords-created-body": "Bottisalasana {{GENDER:$2|käyttäjän}} ”$2” bottinimelle ”$1” luotiin.",
        "botpasswords-updated-title": "Bottisalasana päivitetty",
-       "botpasswords-updated-body": "Bottisalasana {{GENDER:$2|käyttäjän}} \"$2\" bottinimelle \"$1\" päivitettiin.",
+       "botpasswords-updated-body": "Bottisalasana {{GENDER:$2|käyttäjän}} ”$2” bottinimelle ”$1” päivitettiin.",
        "botpasswords-deleted-title": "Bottisalasana poistettu",
-       "botpasswords-deleted-body": "Bottisalasana {{GENDER:$2|käyttäjän}} \"$2\" bottinimelle \"$1\" poistettiin.",
+       "botpasswords-deleted-body": "Bottisalasana {{GENDER:$2|käyttäjän}} ”$2” bottinimelle ”$1” poistettiin.",
        "botpasswords-newpassword": "Uusi salasana kirjautumiseen käyttäjällä <strong>$1</strong> on <strong>$2</strong>. <em>Säilytä tämä myöhempää käyttöä varten.</em> <br> (Vanhoilla boteilla, jotka vaativat kirjautumisnimen olevan sama kuin lopullinen käyttäjänimi, voit myös käyttää nimeä <strong>$3</strong> ja salasanaa <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider ei ole saatavilla.",
        "botpasswords-restriction-failed": "Bottisalasanan rajoitukset estävät tämän sisäänkirjautumisen.",
-       "botpasswords-invalid-name": "Annetussa käyttäjätunnuksessa ei ole bottisalasanan erotinta (\"$1\").",
-       "botpasswords-not-exist": "Käyttäjällä \"$1\" ei ole bottisalasanaa nimellä \"$2\".",
-       "botpasswords-needs-reset": "Bottisalasana {{GENDER:$1|käyttäjän}} \"$1\" bottinimelle \"$2\" täytyy nollata.",
+       "botpasswords-invalid-name": "Annetussa käyttäjätunnuksessa ei ole bottisalasanan erotinta (”$1”).",
+       "botpasswords-not-exist": "Käyttäjällä ”$1” ei ole bottisalasanaa nimellä ”$2”.",
+       "botpasswords-needs-reset": "Bottisalasana {{GENDER:$1|käyttäjän}} ”$1” bottinimelle ”$2” täytyy nollata.",
        "botpasswords-locked": "Et voi kirjautua sisään bottisalasanalla, koska tunnuksesi on lukittu.",
        "resetpass_forbidden": "Salasanoja ei voi vaihtaa.",
        "resetpass_forbidden-reason": "Salasanoja ei voi muuttaa: $1",
        "resetpass-temp-password": "Väliaikainen salasana:",
        "resetpass-abort-generic": "Laajennus keskeytti salasanan vaihdon.",
        "resetpass-expired": "Salasanasi on vanhentunut. Valitse uusi salasana, jotta pääset kirjautumaan sisään.",
-       "resetpass-expired-soft": "Salasanasi on vanhentunut ja se pitää vaihtaa. Valitse uusi salasana nyt tai paina \"{{int:authprovider-resetpass-skip-label}}\", niin voit vaihtaa salasanan myöhemmin.",
-       "resetpass-validity-soft": "Salasanasi ei ole kelvollinen: $1\n\nValitse nyt uusi salasana tai paina \"{{int:authprovider-resetpass-skip-label}}\", niin voit vaihtaa sen myöhemmin.",
+       "resetpass-expired-soft": "Salasanasi on vanhentunut ja se pitää vaihtaa. Valitse uusi salasana nyt tai paina ”{{int:authprovider-resetpass-skip-label}}”, niin voit vaihtaa salasanan myöhemmin.",
+       "resetpass-validity-soft": "Salasanasi ei ole kelvollinen: $1\n\nValitse nyt uusi salasana tai paina ”{{int:authprovider-resetpass-skip-label}}”, niin voit vaihtaa sen myöhemmin.",
        "passwordreset": "Salasanan uusiminen",
        "passwordreset-text-one": "Täytä tämä lomake uudistaaksesi salasanasi.",
        "passwordreset-text-many": "{{PLURAL:$1|Täytä yksi seuraavista kentistä, jolloin saat väliaikaisen salasanan sähköpostitse.}}",
        "preview": "Esikatselu",
        "showpreview": "Esikatsele",
        "showdiff": "Näytä muutokset",
-       "blankarticle": "<strong>Varoitus:</strong> Sivu, jota olet luomassa on tyhjä.\nJos napsautat \"$1\" uudelleen, sivu luodaan ilman sisältöä.",
+       "blankarticle": "<strong>Varoitus:</strong> Sivu, jota olet luomassa on tyhjä.\nJos napsautat ”$1” uudelleen, sivu luodaan ilman sisältöä.",
        "anoneditwarning": "<strong>Varoitus:</strong> Et ole kirjautunut sisään. IP-osoitteesi näkyy julkisesti kaikille, jos muokkaat. Jos <strong>[$1 kirjaudut sisään]</strong> tai <strong>[$2 luot tunnuksen]</strong>, muokkauksesi kirjataan käyttäjätunnuksesi tekemiksi ja samalla saat käyttöösi hyödyllisiä välineitä.",
        "anonpreviewwarning": "''Et ole kirjautunut sisään. Tallentaminen kirjaa IP-osoitteesi tämän sivun muutoshistoriaan.''",
        "missingsummary": "Et ole antanut yhteenvetoa. Jos valitset Tallenna uudelleen, niin muokkauksesi tallennetaan ilman yhteenvetoa.",
-       "selfredirect": "<strong>Varoitus:</strong> Olet tekemässä uudelleenohjausta, joka johtaa tästä sivusta tähän samaan sivuun. \n\nOlet ehkä määrittänyt ohjauksen kohteen väärin tai kenties muokkaat parhaillaan väärää sivua.\n\nJos painat toimintoa \"$1\" uudestaan, tämä ohjaussivu luodaan joka tapauksessa.",
+       "selfredirect": "<strong>Varoitus:</strong> Olet tekemässä uudelleenohjausta, joka johtaa tästä sivusta tähän samaan sivuun. \n\nOlet ehkä määrittänyt ohjauksen kohteen väärin tai kenties muokkaat parhaillaan väärää sivua.\n\nJos painat toimintoa ”$1” uudestaan, tämä ohjaussivu luodaan joka tapauksessa.",
        "missingcommenttext": "Kirjoita kommentti.",
        "missingcommentheader": "<strong>Muistutus:</strong> Et ole antanut aiheotsikkoa tälle kommentille. Napsauta ”$1”, jos haluat tallentaa kommenttisi ilman sellaista.",
        "summary-preview": "Yhteenvedon esikatselu:",
        "anontalkpagetext": "----''Tämä on nimettömän käyttäjän keskustelusivu. Hän ei ole joko luonut itselleen käyttäjätunnusta tai ei käytä sitä, jonka vuoksi hänet tunnistetaan nyt numeerisella IP-osoitteella. Kyseinen IP-osoite voi olla useamman henkilön käytössä. Jos olet nimetön käyttäjä ja sinusta tuntuu, että aiheettomia kommentteja on ohjattu sinulle, [[Special:CreateAccount|luo itsellesi käyttäjätunnus]] tai [[Special:UserLogin|kirjaudu sisään]] välttääksesi jatkossa sekaannukset muiden nimettömien käyttäjien kanssa.''",
        "noarticletext": "Tällä hetkellä tällä sivulla ei ole tekstiä.\nVoit [[Special:Search/{{PAGENAME}}|etsiä sivun nimellä]] muilta sivuilta,\n<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hakea aiheeseen liittyviä lokeja]\ntai [{{fullurl:{{FULLPAGENAME}}|action=edit}} luoda tämän sivun]</span>.",
        "noarticletext-nopermission": "Tällä hetkellä tällä sivulla ei ole tekstiä.\nVoit [[Special:Search/{{PAGENAME}}|etsiä sivun nimellä]] muilta sivuilta tai <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} hakea aiheeseen liittyviä lokeja]</span>, mutta sinulla ei ole oikeutta luoda tätä sivua.",
-       "missing-revision": "Sivusta \"{{FULLPAGENAME}}\" ei ole olemassa versiota $1.\n\nYleensä tämä johtuu vanhentuneesta historialinkistä sivulle, joka on poistettu.\nTarkempia tietoja löytyy [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} poistolokista].",
-       "userpage-userdoesnotexist": "Käyttäjätunnusta \"$1\" ei ole rekisteröity. \nVarmista, haluatko luoda tämän sivun tai muokata sitä.",
+       "missing-revision": "Sivusta ”{{FULLPAGENAME}}” ei ole olemassa versiota $1.\n\nYleensä tämä johtuu vanhentuneesta historialinkistä sivulle, joka on poistettu.\nTarkempia tietoja löytyy [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} poistolokista].",
+       "userpage-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity. \nVarmista, haluatko luoda tämän sivun tai muokata sitä.",
        "userpage-userdoesnotexist-view": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
        "blocked-notice-logextract": "Tämä käyttäjä on tällä hetkellä estetty.\nAlla on viimeisin estolokin tapahtuma:",
        "clearyourcache": "<strong>Huomautus:</strong> Selaimen välimuisti pitää tyhjentää asetusten tallentamisen jälkeen, jotta muutokset tulisivat voimaan.\n* <strong>Firefox ja Safari:</strong> Napsauta <em>Shift</em>-näppäin pohjassa <em>Päivitä</em>, tai paina <em>Ctrl-F5</em> tai <em>Ctrl-R</em> (<em>⌘-R</em> Macilla)\n* <strong>Google Chrome:</strong> Paina <em>Ctrl-Shift-R</em> (<em>⌘-Shift-R</em> Macilla)\n* <strong>Internet Explorer:</strong> Napsauta <em>Ctrl</em>-näppäin pohjassa <em>Päivitä</em> tai paina <em>Ctrl-F5</em>\n* <strong>Opera:</strong> <em>Menu → Settings</em> (<em>Opera → Preferences</em> Macilla) ja sitten <em>Privacy & security → Clear browsing data → Cached images and files</em>.",
        "usercssyoucanpreview": "Voit testata uutta CSS:ää ennen tallennusta käyttämällä painiketta ”{{int:showpreview}}”.",
-       "userjsonyoucanpreview": "<strong>Vihje:</strong> Käytä \"{{int:showpreview}}\" painiketta testataksesi uutta JSON:iasi ennen tallentamista.",
+       "userjsonyoucanpreview": "<strong>Vihje:</strong> Voit testata uutta JSONia ennen tallennusta käyttämällä painiketta ”{{int:showpreview}}”.",
        "userjsyoucanpreview": "Voit testata uutta JavaScriptiä ennen tallennusta käyttämällä painiketta ”{{int:showpreview}}”.",
        "usercsspreview": "'''Tämä on CSS:n esikatselu. Muutoksia ei ole vielä tallennettu.'''",
        "userjsonpreview": "<strong>Huomaa, että tämä on vasta JSON-käyttäjäasetusten esikatselu.\nMuutoksia ei ole vielä tallennettu!</strong>",
        "sitecsspreview": "'''Huomaa, että tämä on vasta CSS:n esikatselu.''' \n'''Muutoksia ei ole vielä tallennettu.'''",
        "sitejsonpreview": "<strong>Huomaa, että tämä on vasta JSON-asetusten esikatselu.\nMuutoksia ei ole vielä tallennettu!</strong>",
        "sitejspreview": "'''Huomaa, että tämä on vasta JavaScript-koodin esikatselu.'''\n'''Muutoksia ei ole vielä tallennettu.'''",
-       "userinvalidconfigtitle": "<strong>Varoitus:</strong> Tyyliä nimeltä ”$1” ei ole olemassa. Muista, että käyttäjän määrittelemät .css-, -json- ja .js-sivut alkavat pienellä alkukirjaimella, esim. {{ns:user}}:Matti Meikäläinen/vector.css eikä {{ns:user}}:Matti Meikäläinen/Vector.css.",
+       "userinvalidconfigtitle": "<strong>Varoitus:</strong> Tyyliä nimeltä ”$1” ei ole olemassa. Muista, että käyttäjän määrittelemät .css-, -.json- ja .js-sivut alkavat pienellä alkukirjaimella, esim. {{ns:user}}:Matti Meikäläinen/vector.css eikä {{ns:user}}:Matti Meikäläinen/Vector.css.",
        "updated": "(Päivitetty)",
        "note": "'''Huomautus:'''",
        "previewnote": "'''Tämä on vasta sivun esikatselu.'''\nTekemiäsi muutoksia ei ole vielä tallennettu.",
        "editingsection": "Muokataan osiota sivusta $1",
        "editingcomment": "Muokataan uutta osiota sivulla $1",
        "editconflict": "Päällekkäinen muokkaus: $1",
-       "explainconflict": "Joku muu on muuttanut tätä sivua sen jälkeen, kun aloit muokata sitä.\nYlempi tekstialue sisältää tämänhetkisen tekstin.\nTekemäsi muutokset näkyvät alemmassa ikkunassa.\nSinun täytyy yhdistää muutoksesi olemassa olevaan tekstiin.\n<strong>Vain</strong> ylemmässä alueessa oleva teksti tallentuu, kun napsautat \"$1\".",
+       "explainconflict": "Joku muu on muuttanut tätä sivua sen jälkeen, kun aloit muokata sitä.\nYlempi tekstialue sisältää tämänhetkisen tekstin.\nTekemäsi muutokset näkyvät alemmassa ikkunassa.\nSinun täytyy yhdistää muutoksesi olemassa olevaan tekstiin.\n<strong>Vain</strong> ylemmässä alueessa oleva teksti tallentuu, kun napsautat ”$1”.",
        "yourtext": "Oma tekstisi",
        "storedversion": "Tallennettu versio",
        "editingold": "'''Varoitus: Olet muokkaamassa vanhaa versiota tämän sivun tekstistä. Jos tallennat sen, kaikki tämän version jälkeen tehdyt muutokset katoavat.'''",
        "content-failed-to-parse": "Sisältö tyypiltään $2 ei jäsenny tyypiksi $1: $3",
        "invalid-content-data": "Virheellinen sisältö",
        "content-not-allowed-here": "Sivun [[$2]] sisältö ei voi olla tyyppiä $1.",
-       "editwarning-warning": "Tältä sivulta poistuminen saattaa aiheuttaa kaikkien tekemiesi muutosten katoamisen.\nJos olet kirjautunut sisään, voit poistaa tämän varoituksen käytöstä omien asetuksien osiossa \"{{int:prefs-editing}}\".",
+       "editwarning-warning": "Tältä sivulta poistuminen saattaa aiheuttaa kaikkien tekemiesi muutosten katoamisen.\nJos olet kirjautunut sisään, voit poistaa tämän varoituksen käytöstä omien asetuksien osiossa ”{{int:prefs-editing}}”.",
        "editpage-invalidcontentmodel-title": "Sisältömalli ei ole tuettu",
-       "editpage-invalidcontentmodel-text": "Sisältömalli \"$1\" ei ole tuettu.",
+       "editpage-invalidcontentmodel-text": "Sisältömalli ”$1” ei ole tuettu.",
        "editpage-notsupportedcontentformat-title": "Sisällön muotoa ei tueta",
        "editpage-notsupportedcontentformat-text": "Sisällön muotoa $1 ei tueta sisältömallilla $2.",
        "content-model-wikitext": "wikiteksti",
        "content-json-empty-array": "Tyhjä array",
        "deprecated-self-close-category": "Sivut, joissa on virheellisiä itsensäsulkevia HTML-tageja",
        "deprecated-self-close-category-desc": "Sivulla on virheellisiä itsensäsulkevia HTML-tageja, kuten <code>&lt;b/></code> tai <code>&lt;span/></code>. Niiden käyttäytyminen muuttuu pian HTLM5:n määritysten mukaiseksi, joten niiden käyttö wikitekstissä on vanhentunut.",
-       "duplicate-args-warning": "<strong>Varoitus:</strong> [[:$1]] kutsuu mallinetta [[:$2]] niin, että parametrille \"$3\" on annettu enemmän kuin yksi arvo. Ainoastaan viimeksi annettu arvo otetaan huomioon.",
+       "duplicate-args-warning": "<strong>Varoitus:</strong> [[:$1]] kutsuu mallinetta [[:$2]] niin, että parametrille ”$3” on annettu enemmän kuin yksi arvo. Ainoastaan viimeksi annettu arvo otetaan huomioon.",
        "duplicate-args-category": "Sivut, jotka käyttävät kaksinkertaisia argumentteja mallinekutsuissa",
        "duplicate-args-category-desc": "Tämä sivu sisältää sellaisia mallinekutsuja, jotka käyttävät kaksi kertaa samaa argumenttia kuten <nowiki>{{foo|bar=1|bar=2}}</nowiki></code> taikka <code><nowiki>{{foo|bar|1=baz}}</nowiki></code>.",
        "expensive-parserfunction-warning": "Tällä sivulla on liian monta hitaiden laajennusfunktioiden kutsua.\nKutsuja pitäisi olla alle $2 {{PLURAL:$2|kappale|kappaletta}}, mutta nyt niitä on $1 {{PLURAL:$1|kappale|kappaletta}}.",
        "deletedhist": "Poistettujen versioiden historia",
        "revdelete-hide-current": "Virhe piilotettaessa kohdetta päivämäärällä $1 kello $2: Tämä on uusin versio.\nSitä ei voi piilottaa.",
        "revdelete-show-no-access": "Virhe näyttäessä kohtaa $2 kello $1: kohta on merkitty ”rajoitetuksi”.\nSinulla ei ole oikeutta siihen.",
-       "revdelete-modify-no-access": "Virhe kohteen päivämäärällä $1 kello $2 muutoksessa: tämä kohde on merkitty \"rajoitetuksi\". \nSinulla ei ole oikeutta muuttaa kohdetta.",
+       "revdelete-modify-no-access": "Virhe kohteen päivämäärällä $1 kello $2 muutoksessa: tämä kohde on merkitty ”rajoitetuksi”. \nSinulla ei ole oikeutta muuttaa kohdetta.",
        "revdelete-modify-missing": "Virhe muuttaessa kohdetta, jonka tunniste on $1: Se puuttuu tietokannasta.",
        "revdelete-no-change": "'''Varoitus.''' Kohteessa päivämäärällä $1 kello $2 on jo valmiiksi haluamasi näkyvyysasetukset.",
        "revdelete-concurrent-change": "Virhe kohteen päivämäärällä $1 kello $2 muutoksessa: sen näkyvyysasetuksia on ilmeisesti joku muuttanut sillä aikaa kun yritit muuttaa sitä.\nOle hyvä ja tarkista lokit.",
        "diff-paragraph-moved-toold": "Kappale siirrettiin. Klikkaa hypätäksesi vanhaan sijaintiin.",
        "difference-missing-revision": "{{PLURAL:$2|Yhtä versiota|$2 versiota}} tästä vertailusta ($1) {{PLURAL:$2|ei}} löytynyt.\n\nUseimmiten tämä johtuu vanhentuneesta vertailulinkistä poistettuun sivuun.\nLisätietoja löytyy [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} poistolokista].",
        "searchresults": "Hakutulokset",
-       "search-filter-title-prefix": "Haetaan vain sivuista, joiden otsikko alkaa \"$1\"",
+       "search-filter-title-prefix": "Haetaan vain sivuista, joiden otsikko alkaa ”$1”",
        "search-filter-title-prefix-reset": "Hae kaikista sivuista",
        "searchresults-title": "Haun tulokset hakusanalle ”$1”",
        "titlematches": "Osumat sivujen otsikoissa",
        "shown-title": "Näytä $1 {{PLURAL:$1|osuma|osumaa}} sivulla",
        "viewprevnext": "Näytä [$3] kerralla.\n\n$1 {{int:pipe-separator}} $2",
        "searchmenu-exists": "'''Tässä wikissä on sivu nimellä [[:$1]].'''",
-       "searchmenu-new": "<strong>Luo sivu \"[[:$1]]\" tähän wikiin.</strong> {{PLURAL:$2|0=|Katso myös sivua, joka löytyi hakutoiminnolla.\n|Katso myös hakutuloksia.}}",
+       "searchmenu-new": "<strong>Luo sivu ”[[:$1]]” tähän wikiin.</strong> {{PLURAL:$2|0=|Katso myös sivua, joka löytyi hakutoiminnolla.\n|Katso myös hakutuloksia.}}",
        "searchprofile-articles": "Sisältösivut",
        "searchprofile-images": "Kuvat ja tiedostot",
        "searchprofile-everything": "Kaikki",
        "localtime": "Paikallinen aika",
        "timezoneuseserverdefault": "Käytä oletusta ($1)",
        "timezoneuseoffset": "Muu (määritä aikaero)",
+       "timezone-useoffset-placeholder": "Esimerkkiarvoja: \"-07:00\" tai \"01:00\"",
        "servertime": "Palvelimen aika",
        "guesstimezone": "Utele selaimelta",
        "timezoneregion-africa": "Afrikka",
        "prefs-editor": "Muokkain",
        "prefs-preview": "Esikatselu",
        "prefs-advancedrc": "Lisäasetukset",
-       "prefs-opt-out": "Jättäydy pois uudistuksista",
        "prefs-advancedrendering": "Lisäasetukset",
        "prefs-advancedsearchoptions": "Lisäasetukset",
        "prefs-advancedwatchlist": "Lisäasetukset",
        "prefs-displayrc": "Perusasetukset",
        "prefs-displaywatchlist": "Näyttöasetukset",
+       "prefs-changesrc": "Näytettävät muutokset",
+       "prefs-changeswatchlist": "Näytettävät muutokset",
+       "prefs-pageswatchlist": "Tarkkaillut sivut",
        "prefs-tokenwatchlist": "Avain",
        "prefs-diffs": "Eroavaisuudet",
        "prefs-help-prefershttps": "Tämä asetus tulee voimaan seuraavan sisäänkirjautumisesi yhteydessä.",
-       "prefswarning-warning": "Olet tehnyt asetuksiisi muutoksia, joita ei ole vielä tallennettu.\nJos poistut sivulta klikkaamatta \"$1\", asetuksiasi ei päivitetä.",
+       "prefswarning-warning": "Olet tehnyt asetuksiisi muutoksia, joita ei ole vielä tallennettu.\nJos poistut sivulta klikkaamatta ”$1”, asetuksiasi ei päivitetä.",
        "prefs-tabs-navigation-hint": "Vihje: Voit käyttää vasenta ja oikeata nuolinäppäintä liikkumiseen välilehtien välillä.",
        "userrights": "Käyttäjän oikeudet",
        "userrights-lookup-user": "Valitse käyttäjä",
        "userrights-expiry-existing": "Nykyinen vanhentumisaika: $2 kello $3",
        "userrights-expiry-othertime": "Muu aika:",
        "userrights-expiry-options": "1 päivä:1 day,1 viikko:1 week,1 kuukausi:1 month,3 kuukautta:3 months,6 kuukautta:6 months,1 vuosi:1 year",
-       "userrights-invalid-expiry": "Ryhmän \"$1\" vanhentumisaika on virheellinen.",
-       "userrights-expiry-in-past": "Ryhmän \"$1\" vanhentumisaika on mennyt.",
-       "userrights-cannot-shorten-expiry": "Et voi aikaistaa ryhmän \"$1\" jäsenyyden erääntymisaikoja. Vain käyttäjät, joilla on oikeus lisätä ja poistaa ryhmiä, voivat aikaistaa erääntymisaikoja.",
+       "userrights-invalid-expiry": "Ryhmän ”$1” vanhentumisaika on virheellinen.",
+       "userrights-expiry-in-past": "Ryhmän ”$1” vanhentumisaika on mennyt.",
+       "userrights-cannot-shorten-expiry": "Et voi aikaistaa ryhmän ”$1” jäsenyyden erääntymisaikoja. Vain käyttäjät, joilla on oikeus lisätä ja poistaa ryhmiä, voivat aikaistaa erääntymisaikoja.",
        "userrights-conflict": "Päällekkäinen käyttöoikeuksien muutos! Tarkista tekemäsi muutokset ja vahvista ne.",
        "group": "Ryhmä",
        "group-user": "käyttäjät",
        "right-ipblock-exempt": "Ohittaa IP-, automaattiset ja osoitealue-estot",
        "right-unblockself": "Poistaa esto itseltään",
        "right-protect": "Muuttaa suojaustasoja ja muokata tarttuvasti suojattuja sivuja",
-       "right-editprotected": "Muokata sivuja, jotka on suojattu tasolle \"{{int:protect-level-sysop}}\"",
-       "right-editsemiprotected": "Muokata sivuja, jotka on suojattu tasolle \"{{int:protect-level-autoconfirmed}}\"",
+       "right-editprotected": "Muokata sivuja, jotka on suojattu tasolle ”{{int:protect-level-sysop}}”",
+       "right-editsemiprotected": "Muokata sivuja, jotka on suojattu tasolle ”{{int:protect-level-autoconfirmed}}”",
        "right-editcontentmodel": "Muokata sivun sisältömallia (content model)",
        "right-editinterface": "Muokata käyttöliittymätekstejä",
        "right-editusercss": "Muokata toisten käyttäjien CSS-tiedostoja",
        "right-applychangetags": "Asettaa [[Special:Tags|merkkauksia]] omien muutosten yhteyteen",
        "right-changetags": "Lisätä ja poistaa satunnaisia [[Special:Tags|merkkauksia]] yksittäisissä sivuversioissa tai lokimerkinnöissä",
        "right-deletechangetags": "Poistaa [[Special:Tags|merkkauksia]] tietokannasta",
-       "grant-generic": "\"$1\" oikeuksien joukko",
+       "grant-generic": "”$1” oikeuksien joukko",
        "grant-group-page-interaction": "Käsitellä sivuja",
        "grant-group-file-interaction": "Käsitellä mediatiedostoja",
        "grant-group-watchlist-interaction": "Käsitellä tarkkailulistaasi",
        "rcfilters-filter-user-experience-level-newcomer-label": "Tulokkaat",
        "rcfilters-filter-user-experience-level-newcomer-description": "Rekisteröityneet muokkaajat, joilla vähemmän kuin 10 muokkausta tai 4 päivää aktiivisuutta.",
        "rcfilters-filter-user-experience-level-learner-label": "Oppijat",
-       "rcfilters-filter-user-experience-level-learner-description": "Rekisteröityneet muokkaajat, joiden kokemus on välillä \"tulokas\" ja \"kokenut käyttäjä\".",
+       "rcfilters-filter-user-experience-level-learner-description": "Rekisteröityneet muokkaajat, joiden kokemus on välillä ”tulokas” ja ”kokenut käyttäjä”.",
        "rcfilters-filter-user-experience-level-experienced-label": "Kokeneet käyttäjät",
        "rcfilters-filter-user-experience-level-experienced-description": "Rekisteröityneet muokkaajat, joilla enemmän kuin 500 muokkausta ja 30 päivää aktiivisuutta.",
        "rcfilters-filtergroup-automated": "Automatisoidut muutokset",
        "rcfilters-filter-categorization-description": "Tulokset sivuista, joita on lisätty luokkiin tai poistettu luokista.",
        "rcfilters-filter-logactions-label": "Lokitoiminnot",
        "rcfilters-filter-logactions-description": "Ylläpidolliset toimet, tunnusten luonnit, sivujen poistot, tiedostolataukset…",
-       "rcfilters-hideminor-conflicts-typeofchange-global": "\"Pienet muutokset\" -suodatin on ristiriidassa yhden tai useamman Muutoksen tyyppi suodattimen kanssa, koska joitain muutostyyppejä ei voida pitää \"pieninä\". Ristiriidassa oleva suodatin on merkittynä Aktiivisissa suodattimissa, yläpuolella.",
-       "rcfilters-hideminor-conflicts-typeofchange": "Joitain muutostyyppejä ei voida määrittää \"pieneksi\", joten tämä suodatin on ristiriidassa seuraavien Muutoksen tyyppi suodattimien kanssa: $1",
-       "rcfilters-typeofchange-conflicts-hideminor": "\"Muutoksen tyyppi\" on ristiriidassa \"Pienet muutokset\" -suodattimen kanssa. Joitain muutostyyppejä ei voida merkitä \"pieniksi\".",
+       "rcfilters-hideminor-conflicts-typeofchange-global": "”Pienet muutokset” -suodatin on ristiriidassa yhden tai useamman Muutoksen tyyppi -suodattimen kanssa, koska joitain muutostyyppejä ei voida pitää ”pieninä”. Ristiriidassa oleva suodatin on merkittynä Aktiivisissa suodattimissa, yläpuolella.",
+       "rcfilters-hideminor-conflicts-typeofchange": "Joitain muutostyyppejä ei voida määrittää ”pieneksi”, joten tämä suodatin on ristiriidassa seuraavien Muutoksen tyyppi suodattimien kanssa: $1",
+       "rcfilters-typeofchange-conflicts-hideminor": "”Muutoksen tyyppi” on ristiriidassa ”Pienet muutokset” -suodattimen kanssa. Joitain muutostyyppejä ei voida merkitä ”pieniksi”.",
        "rcfilters-filtergroup-lastRevision": "Viimeisimmät versiot",
        "rcfilters-filter-lastrevision-label": "Viimeisin versio",
        "rcfilters-filter-lastrevision-description": "Vain viimeisin muutos sivuun.",
        "rcfilters-filter-previousrevision-label": "Ei viimeisin muutos",
-       "rcfilters-filter-previousrevision-description": "Kaikki muutokset, jotka eivät ole \"viimeisin versio\".",
+       "rcfilters-filter-previousrevision-description": "Kaikki muutokset, jotka eivät ole ”viimeisin versio”.",
        "rcfilters-filter-excluded": "Poissuljettu",
        "rcfilters-tag-prefix-namespace-inverted": "<strong>:ei</strong> $1",
        "rcfilters-exclude-button-off": "Poissulje valitut",
        "rcfilters-watchlist-markseen-button": "Merkitse kaikki muutokset nähdyiksi",
        "rcfilters-watchlist-edit-watchlist-button": "Muokkaa tarkkailemiasi sivuja",
        "rcfilters-watchlist-showupdated": "Muutokset sivuihin, joilla et ole vieraillut sen jälkeen kun muutokset on tehty, on <strong>lihavoitu</strong> ja värimerkitty.",
-       "rcfilters-preference-label": "Piilota tuoreiden muutosten parannettu versio",
-       "rcfilters-preference-help": "Peruuttaa vuoden 2017 käyttöliittymän uudistuksen ja kaikki sen jälkeen lisätyt työkalut.",
-       "rcfilters-watchlist-preference-label": "Piilota tarkkailulistan parannettu versio",
-       "rcfilters-watchlist-preference-help": "Poistaa käytöstä vuoden 2017 ulkoasun uudistuksen ja kaikki sen jälkeen lisätyt työkalut.",
+       "rcfilters-preference-label": "Käytä ilman JavaScriptiä toimivaa käyttöliittymää",
+       "rcfilters-preference-help": "Lataa tuoreimmat muutokset -näkymän ilman suodattimia tai korostustoimintoa.",
+       "rcfilters-watchlist-preference-label": "Käytä ilman JavaScriptiä toimivaa käyttöliittymää",
+       "rcfilters-watchlist-preference-help": "Lataa tarkkailulistan ilman suodattimia tai korostustoimintoa.",
        "rcfilters-filter-showlinkedfrom-label": "Näytä muutokset sivuilla, jonne on linkki sivulta",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sivut, joihin linkitetään</strong> valitulta sivulta",
        "rcfilters-filter-showlinkedto-label": "Näytä muutokset sivuilla, joista on linkki sivulle",
        "newsectionsummary": "/* $1 */ uusi osio",
        "rc-enhanced-expand": "Näytä yksityiskohdat",
        "rc-enhanced-hide": "Piilota yksityiskohdat",
-       "rc-old-title": "alun perin luotu nimellä \"$1\"",
+       "rc-old-title": "alun perin luotu nimellä ”$1”",
        "recentchangeslinked": "Linkitettyjen sivujen muutokset",
        "recentchangeslinked-feed": "Linkitettyjen sivujen muutokset",
        "recentchangeslinked-toolbox": "Linkitettyjen sivujen muutokset",
        "upload_directory_read_only": "Palvelimella ei ole kirjoitusoikeuksia tallennushakemistoon $1.",
        "uploaderror": "Tallennusvirhe",
        "upload-recreate-warning": "<strong>Varoitus: Tiedosto tällä nimellä on poistettu tai siirretty.</strong>\n\nPoisto- ja siirtoloki tälle sivulle näkyy alla:",
-       "uploadtext": "Käytä tätä alla olevaa lomaketta tiedostojen tallentamiseen.\nVoit katsella luetteloa aiemmin tallennetuista tiedostoista sivulla [[Special:FileList|tiedostoluettelo]]. Kaikki tallennukset kirjataan myös [[Special:Log/upload|tallennuslokiin]] ja tiedostojen poistot [[Special:Log/delete|poistolokiin]].\n\nJotta saat tiedoston näkymään sivulla, käytä jotakin seuraavista muotoiluista linkkinä siihen:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Tiedosto.jpg]]</nowiki></code></strong> käyttääksesi tiedoston kokonaista versiota.\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Tiedosto.png|200px|thumb|left|teksti tähän]]</nowiki></code></strong> käyttääksesi tiedostoa sovitettuna 200 kuvapistettä leveään laatikkoon kuvatekstillä \"teksti tähän\".\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Tiedosto.ogg]]</nowiki></code></strong>, jos haluat suoran linkin tiedostoon ilman että tiedostoa näytetään.",
+       "uploadtext": "Käytä tätä alla olevaa lomaketta tiedostojen tallentamiseen.\nVoit katsella luetteloa aiemmin tallennetuista tiedostoista sivulla [[Special:FileList|tiedostoluettelo]]. Kaikki tallennukset kirjataan myös [[Special:Log/upload|tallennuslokiin]] ja tiedostojen poistot [[Special:Log/delete|poistolokiin]].\n\nJotta saat tiedoston näkymään sivulla, käytä jotakin seuraavista muotoiluista linkkinä siihen:\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Tiedosto.jpg]]</nowiki></code></strong> käyttääksesi tiedoston kokonaista versiota.\n* <strong><code><nowiki>[[</nowiki>{{ns:file}}<nowiki>:Tiedosto.png|200px|thumb|left|teksti tähän]]</nowiki></code></strong> käyttääksesi tiedostoa sovitettuna 200 kuvapistettä leveään laatikkoon kuvatekstillä ”teksti tähän”.\n* <strong><code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:Tiedosto.ogg]]</nowiki></code></strong>, jos haluat suoran linkin tiedostoon ilman että tiedostoa näytetään.",
        "upload-permitted": "{{PLURAL:$2|Sallittu tiedostomuoto|Sallitut tiedostomuodot}}: $1.",
        "upload-preferred": "{{PLURAL:$2|Suositeltu tiedostomuoto|Suositellut tiedostomuodot}}: $1.",
        "upload-prohibited": "{{PLURAL:$2|Kielletty tiedostomuoto|Kielletyt tiedostomuodot}}: $1.",
        "backend-fail-read": "Tiedostoa $1 ei voitu lukea.",
        "backend-fail-create": "Tiedostoa $1 ei voitu luoda.",
        "backend-fail-maxsize": "Tiedostoa $1 ei voitu luoda, koska se on suurempi kuin {{PLURAL:$2|yksi tavu|$2 tavua}}.",
-       "backend-fail-readonly": "Taustajärjestelmä \"$1\" on tällä hetkellä vain lukutilassa. Syy tähän on: \"''$2''\"",
-       "backend-fail-synced": "Tiedoston \"$1\" tila ei vastaa tiedoston tilaa sisäisissä taustajärjestelmissä.",
-       "backend-fail-connect": "Varastojärjestelmään \"$1\" ei saada yhteyttä.",
-       "backend-fail-internal": "Tuntematon virhe taustajärjestelmässä \"$1\".",
+       "backend-fail-readonly": "Taustajärjestelmä ”$1” on tällä hetkellä vain luku -tilassa. Syy tähän on: ”''$2''”",
+       "backend-fail-synced": "Tiedoston ”$1” tila ei vastaa tiedoston tilaa sisäisissä taustajärjestelmissä.",
+       "backend-fail-connect": "Varastojärjestelmään ”$1” ei saada yhteyttä.",
+       "backend-fail-internal": "Tuntematon virhe taustajärjestelmässä ”$1”.",
        "backend-fail-contenttype": "Tiedostoa ei voitu tallentaa kohteeseen $1, koska tiedostomuotoa ei voitu määrittää.",
        "backend-fail-batchsize": "Taustajärjestelmälle on annettu $1 {{PLURAL:$1|tiedostotoiminto|toimintoa}}; enimmäismäärä on $2 {{PLURAL:$2|tiedostotoiminto|toimintoa}}.",
        "backend-fail-usable": "Tiedostoa $1 ei voitu lukea tai luoda, koska käyttöoikeudet eivät riittäneet tai hakemisto puuttuu.",
-       "filejournal-fail-dbconnect": "Ei voitu yhdistää kohteeseen journal database for storage backend \"$1\".",
-       "filejournal-fail-dbquery": "Ei voitu päivittää kohdetta journal database for storage backend \"$1\".",
+       "filejournal-fail-dbconnect": "Ei voitu yhdistää kohteeseen journal database for storage backend ”$1”.",
+       "filejournal-fail-dbquery": "Ei voitu päivittää kohdetta journal database for storage backend ”$1”.",
        "lockmanager-notlocked": "Kohteen $1 lukitusta ei voitu poistaa, koska se ei ole lukittu.",
        "lockmanager-fail-closelock": "Tiedoston $1 lukkotiedostoa ei voitu sulkea.",
        "lockmanager-fail-deletelock": "Tiedoston $1 lukkotiedostoa ei voitu poistaa.",
-       "lockmanager-fail-acquirelock": "Tiedostopolulle \"$1\" ei voitu luoda suojausta.",
+       "lockmanager-fail-acquirelock": "Tiedostopolulle ”$1” ei voitu luoda suojausta.",
        "lockmanager-fail-openlock": "Tiedoston $1 lukkotiedostoa ei voitu avata. Varmista että latauskansiosi on määritetty oikein ja verkkopalvelimellasi on oikeudet kirjoittaa tähän kansioon. Katso https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgUploadDirectory saadaksesi lisätietoja.",
        "lockmanager-fail-releaselock": "Tiedoston $1 lukituksen avaaminen epäonnistui.",
        "lockmanager-fail-db-bucket": "Ei voitu yhdistää riittävästi tietokantoja kohdassa $1.",
        "uploadstash-errclear": "Tiedostojen tyhjentäminen epäonnistui.",
        "uploadstash-refresh": "Päivitä tiedostoluettelo",
        "uploadstash-thumbnail": "näytä pienoiskuva",
-       "uploadstash-exception": "Tiedostoa ei kyetty säilömään latausmuistiin ($1): \"$2\"",
+       "uploadstash-exception": "Tiedostoa ei kyetty säilömään latausmuistiin ($1): ”$2”.",
        "uploadstash-bad-path": "\nPolkua ei ole.",
        "uploadstash-bad-path-invalid": "Polku ei kelpaa.",
-       "uploadstash-bad-path-unknown-type": "Tuntematon tyyppi \"$1\".",
+       "uploadstash-bad-path-unknown-type": "Tuntematon tyyppi ”$1”.",
        "uploadstash-bad-path-unrecognized-thumb-name": "Tunnistamaton pienoiskuvan nimi.",
        "uploadstash-bad-path-no-handler": "Tiedoston $2 MIME-tyypille $1 ei löytynyt käsittelijää.",
-       "uploadstash-bad-path-bad-format": "Avain \"$1\" ei ole sopivassa muodossa.",
-       "uploadstash-file-not-found": "Avainta \"$1\" ei löytynyt kätköstä.",
+       "uploadstash-bad-path-bad-format": "Avain ”$1” ei ole sopivassa muodossa.",
+       "uploadstash-file-not-found": "Avainta ”$1” ei löytynyt kätköstä.",
        "uploadstash-file-not-found-no-thumb": "Pienoiskuvaa ei voitu saada.",
        "uploadstash-file-not-found-no-local-path": "Skaalatulla kohteella ei ole paikallista polkua.",
        "uploadstash-file-not-found-no-object": "Ei voitu luoda paikallista tiedostokohdetta pienoiskuvalle.",
        "img-auth-public": "Img_auth.php:n tarkoitus on näyttää tiedostoja yksityisessä wikissä.\nTämä wiki on asennettu julkiseksi wikiksi.\nParhaan turvallisuuden vuoksi img_auth.php on poissa käytöstä.",
        "img-auth-noread": "Käyttäjillä ei ole oikeutta lukea tiedostoa ”$1”.",
        "http-invalid-url": "Kelpaamaton URL: $1",
-       "http-invalid-scheme": "Verkko-osoitteita kaavalla \"$1\" ei tueta",
+       "http-invalid-scheme": "Verkko-osoitteita kaavalla ”$1” ei tueta.",
        "http-request-error": "HTTP-pyyntö epäonnistui tuntemattoman virheen takia.",
        "http-read-error": "HTTP-lukuvirhe.",
        "http-timed-out": "HTTP-pyyntö aikakatkaistiin.",
        "listfiles-delete": "poista",
        "listfiles-summary": "Tämä toimintosivu näyttää kaikki tallennetut tiedostot.",
        "listfiles_search_for": "Etsi tiedoston nimellä:",
-       "listfiles-userdoesnotexist": "Käyttäntunnusta \"$1\" ei ole rekisteröity.",
+       "listfiles-userdoesnotexist": "Käyttäjätunnusta ”$1” ei ole rekisteröity.",
        "imgfile": "tiedosto",
        "listfiles": "Tiedostoluettelo",
        "listfiles_thumb": "Pienoiskuva",
        "uncategorizedcategories": "Luokittelemattomat luokat",
        "uncategorizedimages": "Luokittelemattomat tiedostot",
        "uncategorizedtemplates": "Luokittelemattomat mallineet",
-       "uncategorized-categories-exceptionlist": "# Sisältää luettelon luokkia, joita ei tulisi mainita Special:UncategorizedCategories-sivulla. Yksi riviä kohden, alkaen \"*\"-merkillä. Muilla merkeillä alkavat rivit jätetään huomiotta. Käytä \"#\"-merkkiä kommenttien kirjoittamiseen.",
+       "uncategorized-categories-exceptionlist": "# Sisältää luettelon luokkia, joita ei tulisi mainita Special:UncategorizedCategories-sivulla. Yksi riviä kohden, alkaen ”*”-merkillä. Muilla merkeillä alkavat rivit jätetään huomiotta. Käytä ”#”-merkkiä kommenttien kirjoittamiseen.",
        "unusedcategories": "Käyttämättömät luokat",
        "unusedimages": "Käyttämättömät tiedostot",
        "wantedcategories": "Halutut luokat",
        "apisandbox-submit": "Tee pyyntö",
        "apisandbox-reset": "Tyhjennä",
        "apisandbox-retry": "Yritä uudestaan",
-       "apisandbox-loading": "Ladataan tietoja API-moduulista \"$1\"...",
-       "apisandbox-load-error": "Tapahtui virhe ladattaessa tietoja API-moduulista \"$1\": $2",
+       "apisandbox-loading": "Ladataan tietoja API-moduulista ”$1”…",
+       "apisandbox-load-error": "Tapahtui virhe ladattaessa tietoja API-moduulista ”$1”: $2",
        "apisandbox-no-parameters": "Tässä API-moduulissa ei ole parametreja.",
        "apisandbox-helpurls": "Linkit ohjeisiin",
        "apisandbox-examples": "Esimerkit",
        "apisandbox-request-url-label": "Pyynnön URL",
        "apisandbox-request-json-label": "Pyydetty JSON:",
        "apisandbox-request-time": "Pyyntöön kulunut aika: {{PLURAL:$1|$1 ms}}",
-       "apisandbox-results-fixtoken": "Korjaa \"token\" ja lähetä uudelleen",
-       "apisandbox-results-fixtoken-fail": "\"$1\"-avaimen haku epäonnistui.",
+       "apisandbox-results-fixtoken": "Korjaa ”token” ja lähetä uudelleen",
+       "apisandbox-results-fixtoken-fail": "”$1”-avaimen haku epäonnistui.",
        "apisandbox-alert-page": "Tällä sivulla olevat kentät eivät ole kelvollisia.",
        "apisandbox-alert-field": "Tässä kentässä oleva arvo ei ole kelvollinen.",
        "apisandbox-continue": "Jatka",
        "linksearch-pat": "Hakuehto:",
        "linksearch-ns": "Nimiavaruus:",
        "linksearch-ok": "Hae",
-       "linksearch-text": "Jokerimerkkejä, kuten \"*.wikipedia.org\", voidaan käyttää.\nVaaditaan vähintään ylätason verkkotunnus, esimerkiksi \"*.org\".<br />\n{{PLURAL:$2|Tuettu protokolla|Tuetut protokollat}}: $1 (oletuksena on <code>http://</code>, jos protokollaa ei määritetä).",
+       "linksearch-text": "Jokerimerkkejä, kuten ”*.wikipedia.org”, voidaan käyttää.\nVaaditaan vähintään ylätason verkkotunnus, esimerkiksi ”*.org”.<br />\n{{PLURAL:$2|Tuettu protokolla|Tuetut protokollat}}: $1 (oletuksena on <code>http://</code>, jos protokollaa ei määritetä).",
        "linksearch-line": "$1 on linkitetty sivulta $2",
        "linksearch-error": "Jokerimerkkiä voi käyttää ainoastaan osoitteen alussa.",
        "listusersfrom": "Käyttäjien tunnukset alkavat kirjaimilla:",
        "watchlistanontext": "Sinun täytyy kirjautua sisään, jos haluat nähdä oman tarkkailulistasi.",
        "watchnologin": "Et ole kirjautunut sisään",
        "addwatch": "Lisää tarkkailulistalle",
-       "addedwatchtext": "\"[[:$1]]\" ja sen keskustelusivu on lisätty [[Special:Watchlist|tarkkailulistallesi]].",
-       "addedwatchtext-talk": "\"[[:$1]]\" ja siihen liittyvä sivu on lisätty [[Special:Watchlist|tarkkailulistallesi]].",
-       "addedwatchtext-short": "Sivu \"$1\" on lisätty tarkkailulistallesi.",
+       "addedwatchtext": "”[[:$1]]” ja sen keskustelusivu on lisätty [[Special:Watchlist|tarkkailulistallesi]].",
+       "addedwatchtext-talk": "”[[:$1]]” ja siihen liittyvä sivu on lisätty [[Special:Watchlist|tarkkailulistallesi]].",
+       "addedwatchtext-short": "Sivu ”$1” on lisätty tarkkailulistallesi.",
        "removewatch": "Poista tarkkailulistalta",
-       "removedwatchtext": "\"[[:$1]]\" ja sen keskustelusivu on poistettu [[Special:Watchlist|tarkkailulistaltasi]].",
-       "removedwatchtext-talk": "\"[[:$1]]\" ja siihen liittyvä sivu on poistettu [[Special:Watchlist|tarkkailulistaltasi]].",
+       "removedwatchtext": "”[[:$1]]” ja sen keskustelusivu on poistettu [[Special:Watchlist|tarkkailulistaltasi]].",
+       "removedwatchtext-talk": "”[[:$1]]” ja siihen liittyvä sivu on poistettu [[Special:Watchlist|tarkkailulistaltasi]].",
        "removedwatchtext-short": "Sivu ”$1” on poistettu tarkkailulistaltasi.",
        "watch": "Tarkkaile",
        "watchthispage": "Tarkkaile tätä sivua",
        "deletepage": "Poista sivu",
        "confirm": "Toteuta",
        "excontent": "sisälsi: ”$1”",
-       "excontentauthor": "sisältö oli: \"$1\", ja ainoa muokkaaja oli \"[[Special:Contributions/$2|$2]]\" ([[User talk:$2|keskustelu]])",
+       "excontentauthor": "sisältö oli: ”$1”, ja ainoa muokkaaja oli ”[[Special:Contributions/$2|$2]]” ([[User talk:$2|keskustelu]])",
        "exbeforeblank": "ennen tyhjentämistä sisälsi: ”$1”",
        "delete-confirm": "Poista ”$1”",
        "delete-legend": "Sivun poisto",
        "changecontentmodel-emptymodels-text": "Sisältöä sivulla [[:$1]] ei voida muuntaa mihinkään muotoon.",
        "log-name-contentmodel": "Sisältömallin muutosten loki",
        "log-description-contentmodel": "Tällä sivulla on lueteltu muutokset sivujen sisältömalliin, ja sivut, jotka on luotu muulla kuin oletussisältömallilla.",
-       "logentry-contentmodel-new": "$1 {{GENDER:$2|loi}} sivun $3 käyttäen normaalista poikkeavaa sisältömallia \"$5\"",
-       "logentry-contentmodel-change": "$1 {{GENDER:$2|muutti}} sivun $3 sisältömallia muodosta \"$4\" muotoon \"$5\"",
+       "logentry-contentmodel-new": "$1 {{GENDER:$2|loi}} sivun $3 käyttäen normaalista poikkeavaa sisältömallia ”$5”",
+       "logentry-contentmodel-change": "$1 {{GENDER:$2|muutti}} sivun $3 sisältömallia muodosta ”$4” muotoon ”$5”",
        "logentry-contentmodel-change-revertlink": "kumoa",
        "logentry-contentmodel-change-revert": "kumottu",
        "protectlogpage": "Suojausloki",
        "modifiedarticleprotection": "muutti sivun [[$1]] suojausasetuksia",
        "unprotectedarticle": "poisti suojauksen sivulta [[$1]]",
        "movedarticleprotection": "siirsi suojausasetukset sivulta [[$2]] sivulle [[$1]]",
-       "protectedarticle-comment": "{{GENDER:$2|Suojasi}} sivun \"[[$1]]\"",
-       "modifiedarticleprotection-comment": "{{GENDER:$2|Muutti suojaustasoa}} sivulla \"[[$1]]\"",
-       "unprotectedarticle-comment": "{{GENDER:$2|Otti pois suojauksen}} sivulta \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Suojasi}} sivun ”[[$1]]”",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Muutti suojaustasoa}} sivulla ”[[$1]]”",
+       "unprotectedarticle-comment": "{{GENDER:$2|Otti pois suojauksen}} sivulta ”[[$1]]”",
        "protect-title": "Muuta suojausta sivulla ”$1”",
        "protect-title-notallowed": "Katsele kohteen $1 suojauksen tasoa",
        "prot_1movedto2": "siirsi sivun [[$1]] uudelle nimelle [[$2]]",
        "blockipsuccesssub": "Esto onnistui",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] on estetty.<br />\nVoimassa olevat estot näkyvät [[Special:BlockList|estolistasta]].",
        "ipb-blockingself": "Olet estämässä itseäsi. Oletko varma, että haluat tehdä niin?",
-       "ipb-confirmhideuser": "Olet estämässä käyttäjää ”piilota käyttäjä” -toiminnon kanssa.  Tämä piilottaa käyttäjän nimen kaikissa luetteloissa ja lokitapahtumissa.  Oletko varma, että haluat tehdä näin?",
-       "ipb-confirmaction": "Jos olet varma että haluat todella tehdä tämän, tarkista kentän \"{{int:ipb-confirm}}\" sisältö alhaalta.",
+       "ipb-confirmhideuser": "Olet estämässä käyttäjää ”piilota käyttäjä” -toiminnon kanssa. Tämä piilottaa käyttäjän nimen kaikissa luetteloissa ja lokitapahtumissa. Oletko varma, että haluat tehdä näin?",
+       "ipb-confirmaction": "Jos olet varma että haluat todella tehdä tämän, tarkista kentän ”{{int:ipb-confirm}}” sisältö alhaalta.",
        "ipb-edit-dropdown": "Muokkaa estosyitä",
        "ipb-unblock-addr": "Poista käyttäjän $1 esto",
        "ipb-unblock": "Poista käyttäjän tai IP-osoitteen muokkausesto",
        "change-blocklink": "muuta estoa",
        "contribslink": "muokkaukset",
        "emaillink": "lähetä sähköpostia",
-       "autoblocker": "Olet automaattisesti estetty, koska jaat IP-osoitteen käyttäjän [[User:$1|$1]] kanssa. \nKäyttäjän $1 saaman eston syy on: \"$2\".",
+       "autoblocker": "Olet automaattisesti estetty, koska jaat IP-osoitteen käyttäjän [[User:$1|$1]] kanssa. \nKäyttäjän $1 saaman eston syy on: ”$2”.",
        "blocklogpage": "Estoloki",
        "blocklog-showlog": "Tämä käyttäjä on ollut aiemmin estettynä.\nAlla on ote estolokista.",
        "blocklog-showsuppresslog": "Tämä käyttäjä on ollut estettynä ja häivytettynä.\nAlla on ote häivytyslokista.",
        "cant-move-category-page": "Sinulla ei ole oikeutta siirtää luokkien sivuja.",
        "cant-move-to-category-page": "Sinulla ei ole oikeutta siirtää sivua luokkasivuksi.",
        "cant-move-subpages": "Sivulla ei ole oikeutta siirtää alasivuja.",
-       "namespace-nosubpages": "Nimiavaruus \"$1\" ei hyväksy alasivuja.",
+       "namespace-nosubpages": "Nimiavaruus ”$1” ei hyväksy alasivuja.",
        "newtitle": "Uusi nimi sivulle:",
        "move-watch": "Tarkkaile tätä sivua",
        "movepagebtn": "Siirrä sivu",
        "pagemovedsub": "Siirto onnistui",
+       "cannotmove": "Sivua ei voi siirtää {{PLURAL:$1|seuraavasta syystä|seuraavista syistä}}:",
        "movepage-moved": "'''$1 on siirretty nimelle $2'''",
        "movepage-moved-redirect": "Ohjaus luotiin.",
        "movepage-moved-noredirect": "Ohjausta ei luotu.",
        "delete_and_move_confirm": "Kyllä, poista kohdesivu",
        "delete_and_move_reason": "Sivu on sivun [[$1]] siirron tiellä.",
        "selfmove": "Nimi on sama;\nSivua ei voi siirtää itsensä päälle.",
-       "immobile-source-namespace": "Sivuja ei voi siirtää nimiavaruudessa ”$1”",
-       "immobile-target-namespace": "Sivuja ei voi siirtää nimiavaruuteen ”$1”",
+       "immobile-source-namespace": "Sivuja ei voi siirtää nimiavaruudessa ”$1”.",
+       "immobile-target-namespace": "Sivuja ei voi siirtää nimiavaruuteen ”$1”.",
        "immobile-target-namespace-iw": "Kielilinkki ei ole kelvollinen kohde sivun siirrolle.",
        "immobile-source-page": "Tämä sivu ei ole siirrettävissä.",
        "immobile-target-page": "Kyseiselle kohdenimelle ei voi siirtää.",
        "import-error-special": "Sivua $1 ei tuotu, koska se kuuluu erityiseen nimiavaruuteen, joka ei salli sivuja.",
        "import-error-invalid": "Sivua $1 ei tuotu, koska se nimi, jolle se tuotaisiin, ei ole kelvollinen tässä wikissä.",
        "import-error-unserialize": "Versiota $2 sivusta $1 ei voida jakaa osiin. Version ilmoitettiin käyttävän sisältömallia $3 ja sarjoitusmuotoilua $4.",
-       "import-error-bad-location": "Sivun versiota $2, joka käyttää sisällön mallia $3, ei voi tallettaa kohteeseen \"$1\" tässä wikissä, koska tuota mallia ei tueta kyseisellä sivulla.",
+       "import-error-bad-location": "Sivun versiota $2, joka käyttää sisällön mallia $3, ei voi tallettaa kohteeseen ”$1” tässä wikissä, koska tuota mallia ei tueta kyseisellä sivulla.",
        "import-options-wrong": "{{PLURAL:$2|Väärä asetus|Väärät asetukset}}: <nowiki>$1</nowiki>",
        "import-rootpage-invalid": "Annettu perussivun nimi ei kelpaa.",
-       "import-rootpage-nosubpage": "Annetun perussivun nimiavaruus \"$1\" ei salli alasivuja.",
+       "import-rootpage-nosubpage": "Annetun perussivun nimiavaruus ”$1” ei salli alasivuja.",
        "importlogpage": "Tuontiloki",
        "importlogpagetext": "Loki ylläpitäjien toisista wikeistä tuomista sivuista, joissa on muokkaushistoriaa.",
        "import-logentry-upload-detail": "$1 {{PLURAL:$1|versio|versiota}} tuotiin",
        "import-logentry-interwiki-detail": "$1 {{PLURAL:$1|versio|versiota}} tuotiin wikistä $2",
        "javascripttest": "JavaScriptin testaus",
-       "javascripttest-pagetext-unknownaction": "Tuntematon toiminto \"$1\".",
+       "javascripttest-pagetext-unknownaction": "Tuntematon toiminto ”$1”.",
        "javascripttest-qunit-intro": "Katso [$1 testausohjeet] mediawiki.orgissa.",
        "tooltip-pt-userpage": "{{GENDER:|Oma käyttäjäsivusi}}",
        "tooltip-pt-anonuserpage": "IP-osoitteesi käyttäjäsivu",
        "invalidateemail": "Sähköpostiosoitteen varmennuksen peruuttaminen",
        "notificationemail_subject_changed": "Sivuston {{SITENAME}} rekisteröity sähköpostiosoite on vaihdettu",
        "notificationemail_subject_removed": "Sivuston {{SITENAME}} rekisteröity sähköpostiosoite on poistettu",
-       "notificationemail_body_changed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on vaihtanut tunnuksen \"$2\" sähköpostiosoitteeksi \"$3\" sivustolla {{SITENAME}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
-       "notificationemail_body_removed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on poistanut tunnuksen \"$2\" sähköpostiosoitteen sivustolla {{SITENAME}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
+       "notificationemail_body_changed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on vaihtanut tunnuksen ”$2” sähköpostiosoitteeksi ”$3” sivustolla {{SITENAME}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
+       "notificationemail_body_removed": "Joku, todennäköisesti sinä, IP-osoitteesta $1 on poistanut tunnuksen ”$2” sähköpostiosoitteen sivustolla {{SITENAME}}.\n\nJos se et ollut sinä, ota yhteyttä sivuston ylläpitäjään välittömästi.",
        "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]",
        "mcrundo-changed": "Sivu on muuttunut siitä lähtien, kun katsoit tätä muokkausta. Arvioi uusi muokkaus.",
        "mcrundo-parse-failed": "Uuden version jäsentäminen epäonnistui: $1",
        "percent": "$1&#160;%",
-       "quotation-marks": "\"$1\"",
+       "quotation-marks": "”$1”",
        "imgmultipageprev": "← edellinen sivu",
        "imgmultipagenext": "seuraava sivu →",
        "imgmultigo": "Siirry",
        "watchlisttools-raw": "Muokkaa listaa raakamuodossa",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|keskustelu]])",
        "timezone-local": "Paikallinen",
-       "duplicate-defaultsort": "'''Varoitus:''' Oletuslajitteluavain ”$2” korvaa aiemman oletuslajitteluavaimen ”$1”.",
-       "duplicate-displaytitle": "<strong>Varoitus:</strong> Näytettävä otsikko \"$2\" päällekirjoittaa edellisen otsikon \"$1\".",
-       "restricted-displaytitle": "<strong>Varoitus:</strong> Näytettävää otsikkoa \"$1\" ei huomioitu, koska se ei vastaa sivun oikeaa nimeä.",
+       "duplicate-defaultsort": "<strong>Varoitus:</strong> Oletuslajitteluavain ”$2” korvaa aiemman oletuslajitteluavaimen ”$1”.",
+       "duplicate-displaytitle": "<strong>Varoitus:</strong> Näytettävä otsikko ”$2” korvaa edellisen otsikon ”$1”.",
+       "restricted-displaytitle": "<strong>Varoitus:</strong> Näytettävää otsikkoa ”$1” ei huomioitu, koska se ei vastaa sivun oikeaa nimeä.",
        "invalid-indicator-name": "<strong>Virhe:</strong> Sivun tilan osoittimien attribuutti <code>name</code> ei saa olla tyhjä.",
        "version": "Versio",
        "version-extensions": "Asennetut laajennukset",
        "tags-create-no-name": "Sinun täytyy antaa merkkaukselle nimi.",
        "tags-create-invalid-chars": "Merkkausten nimissä ei saa olla pilkkuja (<code>,</code>), putkia (<code>|</code>) tai kauttaviivoja (<code>/</code>).",
        "tags-create-invalid-title-chars": "Merkkausten nimissä ei saa olla sellaisia merkkejä, joita ei voida käyttää sivujen nimissä.",
-       "tags-create-already-exists": "Merkkaus \"$1\" on jo olemassa.",
-       "tags-create-warnings-above": "{{PLURAL:$2|Seuraava varoitus|Seuraavat varoitukset}} ilmenivät, kun yritettiin luoda merkkausta \"$1\":",
+       "tags-create-already-exists": "Merkkaus ”$1” on jo olemassa.",
+       "tags-create-warnings-above": "{{PLURAL:$2|Seuraava varoitus|Seuraavat varoitukset}} ilmenivät, kun yritettiin luoda merkkausta ”$1”:",
        "tags-create-warnings-below": "Haluatko jatkaa merkkauksen luomista?",
        "tags-delete-title": "Hävitä merkkaus pysyvästi",
-       "tags-delete-explanation-initial": "Olet parhaillaan poistamassa (eli tuhoamassa pysyvästi) merkkauksen \"$1\" tietokannasta.",
+       "tags-delete-explanation-initial": "Olet parhaillaan poistamassa (eli tuhoamassa pysyvästi) merkkauksen ”$1” tietokannasta.",
        "tags-delete-explanation-in-use": "Se poistuu {{PLURAL:$2|$2 sivun versiosta tai lokimerkinnästä|kaikista $2 sivuversiosta tai lokimerkinnöistä}}, joissa se tällä hetkellä on käytössä.",
        "tags-delete-explanation-warning": "Tämä toimenpide on <strong>peruuttamaton</strong> ja <strong>poistettua merkkausta ei voi palauttaa takaisin</strong>. Siihen ei pysty edes tietokannan ylläpitohenkilöstö. Sinun pitää olla täysin varma, että haluat poistettavaksi juuri tämän merkkauksen.",
-       "tags-delete-explanation-active": "<stron>Merkkaus \"$1\" on edelleen käytössä ja sitä käytetään myös jatkossa.</strong>. Jos haluat merkkauksen pois käytöstä, mene sinne missä merkkaus on asetettu ja ota se pois siellä.",
+       "tags-delete-explanation-active": "<strong>Merkkaus ”$1” on edelleen käytössä ja sitä käytetään myös jatkossa.</strong>. Jos haluat merkkauksen pois käytöstä, mene sinne missä merkkaus on asetettu ja ota se pois siellä.",
        "tags-delete-reason": "Syy:",
        "tags-delete-submit": "Tuhoa tämä merkkaus peruuttamattomasti ja pysyvästi",
        "tags-delete-not-allowed": "Sellaisia merkkauksia, jotka tulevat erityisestä ohjelmistolaajennuksesta, ei voi poistaa ennen kuin tämä laajennus erityisesti sallii sen.",
-       "tags-delete-not-found": "Merkkausta \"$1\" ei ole olemassa.",
-       "tags-delete-too-many-uses": "Tämä merkkaus \"$1\" on käytössä useammassa kuin $2 sivuversiossa, joten sitä ei voi poistaa.",
-       "tags-delete-warnings-after-delete": "Merkkaus \"$1\" poistettiin, mutta toimenpide sai aikaan {{PLURAL:$2|seuraavan varoituksen|seuraavat varoitukset}}:",
+       "tags-delete-not-found": "Merkkausta ”$1” ei ole olemassa.",
+       "tags-delete-too-many-uses": "Tämä merkkaus ”$1” on käytössä useammassa kuin $2 sivuversiossa, joten sitä ei voi poistaa.",
+       "tags-delete-warnings-after-delete": "Merkkaus ”$1” poistettiin, mutta toimi sai aikaan {{PLURAL:$2|seuraavan varoituksen|seuraavat varoitukset}}:",
        "tags-delete-no-permission": "Sinulla ei ole oikeutta poistaa muutoksien yhteydessä olevia merkkauksia.",
        "tags-activate-title": "Aktivoi merkkaus",
-       "tags-activate-question": "Olet nyt aktivoimassa merkkausta \"$1\".",
+       "tags-activate-question": "Olet nyt aktivoimassa merkkausta ”$1”.",
        "tags-activate-reason": "Syy:",
-       "tags-activate-not-allowed": "Ei ole mahdollista aktivoida merkkausta \"$1\".",
-       "tags-activate-not-found": "Merkkausta \"$1\" ei ole olemassa.",
+       "tags-activate-not-allowed": "Ei ole mahdollista aktivoida merkkausta ”$1”.",
+       "tags-activate-not-found": "Merkkausta ”$1” ei ole olemassa.",
        "tags-activate-submit": "Aktivoi",
        "tags-deactivate-title": "Ota merkkaus pois käytöstä",
-       "tags-deactivate-question": "Olet parhaillaan poistamassa käytöstä (eli deaktivoimassa) merkkausta \"$1\".",
+       "tags-deactivate-question": "Olet parhaillaan poistamassa käytöstä (eli deaktivoimassa) merkkausta ”$1”.",
        "tags-deactivate-reason": "Syy:",
-       "tags-deactivate-not-allowed": "Ei ole mahdollista poistaa käytöstä merkkausta \"$1\".",
+       "tags-deactivate-not-allowed": "Ei ole mahdollista poistaa käytöstä merkkausta ”$1”.",
        "tags-deactivate-submit": "Poista käytöstä",
        "tags-apply-no-permission": "Sinulla ei ole oikeutta käyttää merkkauksia muutostesi yhteydessä.",
        "tags-apply-blocked": "Et voi asettaa merkkauksia muutostesi yhteyteen, kun {{GENDER:$1|olet}} estettynä.",
-       "tags-apply-not-allowed-one": "Merkkausta \"$1\" ei ole sallittua asettaa käsin.",
+       "tags-apply-not-allowed-one": "Merkkausta ”$1” ei ole sallittua asettaa käsin.",
        "tags-apply-not-allowed-multi": "Seuraavia {{PLURAL:$2|merkkauksia}} ei ole sallittua asettaa käsin: $1",
        "tags-update-no-permission": "Sinulla ei ole oikeutta lisätä tai poistaa merkkauksia yksittäisissä sivuversioissa tai lokimerkinnöissä.",
        "tags-update-blocked": "Et voi lisätä tai poistaa merkkauksia, kun {{GENDER:$1|olet}} estettynä.",
-       "tags-update-add-not-allowed-one": "Merkkausta \"$1\" ei ole sallittua asettaa käsin.",
+       "tags-update-add-not-allowed-one": "Merkkausta ”$1” ei ole sallittua asettaa käsin.",
        "tags-update-add-not-allowed-multi": "Seuraavia {{PLURAL:$2|merkkauksia}} ei ole sallittua asettaa käsin: $1",
-       "tags-update-remove-not-allowed-one": "Merkkausta \"$1\" ei ole sallittua poistaa.",
+       "tags-update-remove-not-allowed-one": "Merkkausta ”$1” ei ole sallittua poistaa.",
        "tags-update-remove-not-allowed-multi": "Seuraavia {{PLURAL:$2|merkkauksia}} ei ole sallittua poistaa käsin: $1",
        "tags-edit-title": "Muokkaa merkkauksia",
        "tags-edit-manage-link": "Hallinnoi merkkauksia",
        "logentry-upload-revert": "$1 {{GENDER:$2|tallensi}} tiedoston $3",
        "log-name-managetags": "Merkkausten hallinnan loki",
        "log-description-managetags": "Tällä sivulla on luettelo tehtävistä, jotka koskevat [[Special:Tags|merkkauksia]]. Lokissa ovat vain ne toimenpiteet, jotka ylläpitäjä on suorittanut käsin. Merkkauksia voi syntyä ja poistua myös wikin ohjelmiston kautta eivätkä ne näy tässä lokissa.",
-       "logentry-managetags-create": "$1 {{GENDER:$2|on luonut}} merkkauksen \"$4\"",
-       "logentry-managetags-delete": "$1 {{GENDER:$2|tuhosi}} merkkauksen \"$4\" (poistettu $5 {{PLURAL:$5|sivuversiosta tai lokimerkinnästä}})",
-       "logentry-managetags-activate": "$1 {{GENDER:$2|aktivoi}} merkkauksen \"$4\" käyttäjien ja bottien käytettäväksi",
-       "logentry-managetags-deactivate": "$1 {{GENDER:$2|otti pois käytöstä}} merkkauksen \"$4\" käyttäjiltä ja boteilta",
+       "logentry-managetags-create": "$1 {{GENDER:$2|on luonut}} merkkauksen ”$4”",
+       "logentry-managetags-delete": "$1 {{GENDER:$2|tuhosi}} merkkauksen ”$4” (poistettu $5 {{PLURAL:$5|sivuversiosta tai lokimerkinnästä}})",
+       "logentry-managetags-activate": "$1 {{GENDER:$2|aktivoi}} merkkauksen ”$4” käyttäjien ja bottien käytettäväksi",
+       "logentry-managetags-deactivate": "$1 {{GENDER:$2|otti pois käytöstä}} merkkauksen ”$4” käyttäjiltä ja boteilta",
        "log-name-tag": "Merkkausloki",
        "log-description-tag": "Tällä sivulla näytetään käyttäjien lisäämät tai poistamat [[Special:Tags|merkkaukset]] yksittäisissä sivuversioissa tai lokimerkinnöissä. Lokiin eivät kirjaudu merkkaukset silloin, kun ne tulevat muokkaamisen, poistamisen tai muun vastaavan toimenpiteen yhteydessä.",
        "logentry-tag-update-add-revision": "$1 {{GENDER:$2|lisäsi}} {{PLURAL:$7|merkkauksen|merkkaukset}} $6 kohdeversioon $4 sivulla $3",
        "feedback-back": "Takaisin",
        "feedback-bugcheck": "Hyvä! Varmista vielä, että ohjelmointivirhettä ei löydy [$1 tunnettujen virheiden luettelosta].",
        "feedback-bugnew": "Olen varmistanut. Ilmoitan uuden ohjelmointivirheen",
-       "feedback-bugornote": "Jos voit kuvailla teknisen ongelman tarkasti – [$1 ilmoita ohjelmointivirheestä].\nMuussa tapauksessa voit käyttää alla olevaa helpompaa lomaketta. Kommenttisi lisätään sivulle [$3 $2], ja siinä on mukana käyttäjätunnuksesi.",
+       "feedback-bugornote": "Jos voit kuvailla teknisen ongelman tarkasti, [$1 ilmoita ohjelmointivirheestä].\nMuussa tapauksessa voit käyttää alla olevaa helpompaa lomaketta. Kommenttisi lisätään sivulle [$3 $2], ja siinä on mukana käyttäjätunnuksesi.",
        "feedback-cancel": "Peruuta",
        "feedback-close": "Valmis",
        "feedback-external-bug-report-button": "Lähetä tekninen tehtävä",
        "feedback-dialog-title": "Lähetä palautetta",
-       "feedback-dialog-intro": "Voit käyttää tätä helppoa lomaketta palautteesi lähettämiseen. Kommenttisi lisätään sivulle \"$1\" käyttäjätunnuksesi kera.",
+       "feedback-dialog-intro": "Voit käyttää tätä helppoa lomaketta palautteesi lähettämiseen. Kommenttisi lisätään sivulle ”$1” käyttäjätunnuksesi kera.",
        "feedback-error1": "Virhe: Ohjelmointirajapinnan vastausta ei tunnistettu",
        "feedback-error2": "Virhe: Muokkaus epäonnistui",
        "feedback-error3": "Virhe: Ohjelmointirajapinta ei vastaa",
        "api-error-emptypage": "Ei ole sallittua luoda uutta, tyhjää sivua.",
        "api-error-publishfailed": "Sisäinen virhe: Väliaikaisen tiedoston julkaiseminen epäonnistui.",
        "api-error-stashfailed": "Sisäinen virhe: Väliaikaisen tiedoston tallentaminen epäonnistui.",
-       "api-error-unknown-warning": "Tuntematon varoitus: \"$1\".",
+       "api-error-unknown-warning": "Tuntematon varoitus: ”$1”.",
        "api-error-unknownerror": "Tuntematon virhe: $1.",
        "duration-seconds": "$1 {{PLURAL:$1|sekunti|sekuntia}}",
        "duration-minutes": "$1 {{PLURAL:$1|minuutti|minuuttia}}",
        "authprovider-confirmlink-ok-help": "Jatka yhteydenottohäiriöilmoitusten näyttämisen jälkeen.",
        "authprovider-resetpass-skip-label": "Ohita",
        "authprovider-resetpass-skip-help": "Ohita salasanan palautus.",
-       "authform-nosession-login": "Varmennus onnistui, mutta selaimesi ei pysty \"muistamaan\" sisäänkirjautumista.\n\n$1",
-       "authform-nosession-signup": "Tunnus luotiin, mutta selaimesi ei pysty \"muistamaan\" sisäänkirjautumista.\n\n$1",
-       "authform-newtoken": "Puuttuva \"token\". $1",
-       "authform-notoken": "Puuttuva \"token\"",
-       "authform-wrongtoken": "Väärä \"token\"",
+       "authform-nosession-login": "Varmennus onnistui, mutta selaimesi ei pysty ”muistamaan” sisäänkirjautumista.\n\n$1",
+       "authform-nosession-signup": "Tunnus luotiin, mutta selaimesi ei pysty ”muistamaan” sisäänkirjautumista.\n\n$1",
+       "authform-newtoken": "Puuttuva ”token”. $1",
+       "authform-notoken": "Puuttuva ”token”",
+       "authform-wrongtoken": "Väärä ”token”",
        "specialpage-securitylevel-not-allowed-title": "Ei sallittu",
        "specialpage-securitylevel-not-allowed": "Valitettavasti sinulla ei ole oikeutta muokata tätä sivua, koska henkilöllisyyttäsi ei voitu varmentaa.",
        "authpage-cannot-login": "Kirjautumista ei voitu aloittaa.",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Salasana ei saa olla mustalla listalla",
        "passwordpolicies-policy-maximalpasswordlength": "Salasanan tulee olla lyhyempi kuin $1 {{PLURAL:$1|merkki|merkkiä}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Salasana ei saa olla {{PLURAL:$1|suosittu salasana|$1 suosituimman salasanan listalla}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Salasana ei voi olla 100&nbsp;000 yleisimmin käytetyn joukossa.",
        "unprotected-js": "Turvallisuussyistä JavaScriptiä ei voi ladata suojaamattomilta sivuilta. Luo JavaScript-sivuja vain MediaWiki-nimiavaruuteen tai käyttäjän alasivulle."
 }
index 1b5fe10..821f4da 100644 (file)
        "timezonelegend": "Fuseau horaire :",
        "localtime": "Heure locale :",
        "timezoneuseserverdefault": "Utiliser la valeur par défaut du wiki ($1)",
-       "timezoneuseoffset": "Autre (spécifier le décalage)",
+       "timezoneuseoffset": "Autre (spécifier le décalage ci-dessous)",
+       "timezone-useoffset-placeholder": "Exemple de valeurs: « -07:00 » ou « 01:00 »",
        "servertime": "Heure du serveur :",
        "guesstimezone": "Utiliser la valeur du navigateur",
        "timezoneregion-africa": "Afrique",
        "prefs-editor": "Éditeur",
        "prefs-preview": "Aperçu",
        "prefs-advancedrc": "Options avancées",
-       "prefs-opt-out": "Refuser les améliorations",
        "prefs-advancedrendering": "Options avancées",
        "prefs-advancedsearchoptions": "Options avancées",
        "prefs-advancedwatchlist": "Options avancées",
        "exif-compression": "Type de compression",
        "exif-photometricinterpretation": "Modèle colorimétrique",
        "exif-orientation": "Orientation",
-       "exif-samplesperpixel": "Composantes par pixel",
+       "exif-samplesperpixel": "Nombre de composants",
        "exif-planarconfiguration": "Arrangement des données",
        "exif-ycbcrsubsampling": "Taux de sous-échantillonnage de Y à C",
        "exif-ycbcrpositioning": "Positionnement YCbCr",
index e00f3d7..4f467dc 100644 (file)
        "prefs-editor": "Skriiwer",
        "prefs-preview": "Föörskau",
        "prefs-advancedrc": "Ütjwidjet mögelkhaiden",
-       "prefs-opt-out": "Faan ferbeedrangen ufmelde",
        "prefs-advancedrendering": "Ütjwidjet mögelkhaiden",
        "prefs-advancedsearchoptions": "Ütjwidjet mögelkhaiden",
        "prefs-advancedwatchlist": "Ütjwidjet mögelkhaiden",
index 505bc0d..54bcd18 100644 (file)
        "passwordtooshort": "Os contrasinais deben conter, como mínimo, {{PLURAL:$1|1 carácter|$1 caracteres}}.",
        "passwordtoolong": "Os contrasinais non poden ser máis longo de {{PLURAL:$1|1 carácter|$1 caracteres}}.",
        "passwordtoopopular": "Non pode utilizar un contrasinal dos habitualmente elixidos pola xente. Por favor, escolla un contrasinal que sexa máis complicada de adiviñar.",
+       "passwordinlargeblacklist": "O contrasinal usado está na lista de contrasinais máis usados. Por favor seleccione un contrasinal menos común.",
        "password-name-match": "O seu contrasinal debe ser diferente do seu nome de usuario.",
        "password-login-forbidden": "O uso deste nome de usuario e contrasinal foi prohibido.",
        "mailmypassword": "Restablecer o contrasinal",
        "timezonelegend": "Fuso horario:",
        "localtime": "Hora local:",
        "timezoneuseserverdefault": "Usar a hora do servidor por defecto ($1)",
-       "timezoneuseoffset": "Outro (especifique o desprazamento)",
+       "timezoneuseoffset": "Outro (especifique o desprazamento debaixo)",
+       "timezone-useoffset-placeholder": "Valores de exemplo: \"-07:00\" ou \"01:00\"",
        "servertime": "Hora do servidor:",
        "guesstimezone": "Encher desde o navegador",
        "timezoneregion-africa": "África",
        "prefs-editor": "Editor",
        "prefs-preview": "Vista previa",
        "prefs-advancedrc": "Opcións avanzadas",
-       "prefs-opt-out": "Excluír de melloras",
        "prefs-advancedrendering": "Opcións avanzadas",
        "prefs-advancedsearchoptions": "Opcións avanzadas",
        "prefs-advancedwatchlist": "Opcións avanzadas",
        "rcfilters-watchlist-markseen-button": "Marcar tódolos cambios como xa vistos",
        "rcfilters-watchlist-edit-watchlist-button": "Editar a súa lista de páxinas vixiadas",
        "rcfilters-watchlist-showupdated": "Os cambios feitos en páxinas que non visitou dende que se efectuaron aparecen en <strong>grosas</strong>, acompañados de marcadores sólidos.",
-       "rcfilters-preference-label": "Ocultar a versión mellorada de cambios recentes",
-       "rcfilters-preference-help": "Reverte o redeseño da interface de 2017 e tódalas ferramentas engadidas dende entón.",
-       "rcfilters-watchlist-preference-label": "Agochar a versión mellorada da lista de vixiancia",
-       "rcfilters-watchlist-preference-help": "Revirte o redeseño da interface de 2017 e tódalas ferramentas engadidas dende entón.",
+       "rcfilters-preference-label": "Usar a interface sen JavaScript",
+       "rcfilters-preference-help": "Cargar cambios recentes sen filtros nin a funcionalidade de resaltado.",
+       "rcfilters-watchlist-preference-label": "Usar interface sen JavaScript",
+       "rcfilters-watchlist-preference-help": "Cargar a lista de vixilancia sen filtros nin a funcionalidade de resaltado.",
        "rcfilters-filter-showlinkedfrom-label": "Amosar os cambios en páxinas ligadas desde",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Páxinas ligadas desde</strong> a páxina seleccionada",
        "rcfilters-filter-showlinkedto-label": "Amosar os cambios en páxinas que ligan con",
        "logentry-block-reblock": "$1 {{GENDER:$2|cambiou}} as configuracións do bloqueo de {{GENDER:$4|$3}} cunha caducidade de $5 $6",
        "logentry-partialblock-block": "$1 {{GENDER:$2|bloqueou}} a {{GENDER:$4|$3}} impedíndolle editar {{PLURAL:$8|a páxina|as páxinas}} $7 cun tempo de expiración de $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|bloqueou}} as definicións do bloqueo de {{GENDER:$4|$3}} impedíndolle a edición  {{PLURAL:$8|da páxina|das páxinas}} $7 cun tempo de expiración de $5 $6",
-       "logentry-non-editing-block-block": "$1 {{GENDER:$2|bloqueou}} a {{GENDER:$4|$3}} impedíndolle realizar accións que non sexan edicións cun tempo de expiración de $5 $6",
-       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|cambiou}} as definicións do bloqueo de {{GENDER:$4|$3}} para as accións que non sexan edicións cun tempo de expiración de $5 $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|bloqueou}} a {{GENDER:$4|$3}} impedíndolle realizar accións especificadas que non sexan edicións cun tempo de expiración de $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|cambiou}} as definicións do bloqueo de {{GENDER:$4|$3}} para as accións especificadas que non sexan edicións cun tempo de expiración de $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|bloqueou}} a {{GENDER:$4|$3}} cun tempo de duración de $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|cambiou}} as configuracións do bloqueo de {{GENDER:$4|$3}} cunha caducidade de $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importou}} $3 por medio da carga de ficheiros",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "O contrasinal non pode coincidir con contrasinais incluidos na lista negra",
        "passwordpolicies-policy-maximalpasswordlength": "O contrasinal debe conter menos de $1 {{PLURAL:$1|carácter|caracteres}}",
        "passwordpolicies-policy-passwordcannotbepopular": "O contrasinal non pode {{PLURAL:$1|ser o contrasinal máis habitual|estar na lista dos $1 máis habituais}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "O contrasinal non pode estar na lista dos 100.000 contrasinais máis usados.",
        "easydeflate-invaliddeflate": "O contido fornecido non está debidamente comprimido",
        "unprotected-js": "Por motivos de seguridade non se pode cargar JavaScript desde páxinas non protexidas. Por favor, cree só JavaScript no espazo de nomes MediaWiki ou como subpáxina de usuario"
 }
index cd70fb7..75d725c 100644 (file)
        "timezonelegend": "אזור זמן:",
        "localtime": "שעה מקומית:",
        "timezoneuseserverdefault": "ברירת המחדל של האתר ($1)",
-       "timezoneuseoffset": "אחר (יש לציין את ההפרש)",
+       "timezoneuseoffset": "אחר (יש לכתוב למטה את ההפרש)",
+       "timezone-useoffset-placeholder": "ערכים לדוגמה: \"-07:00\" או \"01:00\"",
        "servertime": "השעה הנוכחית בשרת:",
        "guesstimezone": "קבלה מהדפדפן",
        "timezoneregion-africa": "אפריקה",
        "prefs-editor": "חלון העריכה",
        "prefs-preview": "תצוגה מקדימה",
        "prefs-advancedrc": "אפשרויות מתקדמות",
-       "prefs-opt-out": "ביטול שיפורים",
        "prefs-advancedrendering": "אפשרויות מתקדמות",
        "prefs-advancedsearchoptions": "אפשרויות מתקדמות",
        "prefs-advancedwatchlist": "אפשרויות מתקדמות",
index 26b3f17..0488f2c 100644 (file)
        "prefs-editor": "सम्पादक",
        "prefs-preview": "पूर्वावलोकन",
        "prefs-advancedrc": "उन्नत विकल्प",
-       "prefs-opt-out": "बदलावों के बहार का विकल्प",
        "prefs-advancedrendering": "उन्नत विकल्प",
        "prefs-advancedsearchoptions": "उन्नत विकल्प",
        "prefs-advancedwatchlist": "उन्नत विकल्प",
index 69a6d28..0abf3a2 100644 (file)
        "prefs-editor": "Uređivač",
        "prefs-preview": "Prikaži kako će izgledati",
        "prefs-advancedrc": "Napredne mogućnosti",
-       "prefs-opt-out": "Izuzimanje od poboljšanja",
        "prefs-advancedrendering": "Napredne mogućnosti",
        "prefs-advancedsearchoptions": "Napredne mogućnosti",
        "prefs-advancedwatchlist": "Napredne mogućnosti",
index 641c395..7f9c58e 100644 (file)
@@ -87,7 +87,7 @@
        "tog-watchlisthideminor": "Apró változtatások elrejtése",
        "tog-watchlisthideliu": "Bejelentkezett szerkesztők módosításainak elrejtése a figyelőlistáról",
        "tog-watchlistreloadautomatically": "A figyelőlista automatikus újratöltése bármelyik szűrő megváltoztatása esetén (JavaScript szükséges)",
-       "tog-watchlistunwatchlinks": "Figyelőlista elemeinek eltávolítására szolgáló közvetlen link hozzáadása (JavaScript szükséges)",
+       "tog-watchlistunwatchlinks": "Figyelőlista elemeinek eltávolítására szolgáló közvetlen link ({{int:Watchlist-unwatch}}/{{int:Watchlist-unwatch-undo}}) hozzáadása (JavaScript szükséges)",
        "tog-watchlisthideanons": "Névtelen szerkesztések elrejtése",
        "tog-watchlisthidepatrolled": "Az ellenőrzött szerkesztések elrejtése",
        "tog-watchlisthidecategorization": "Lapok kategorizálásának elrejtése",
        "passwordtooshort": "A jelszónak legalább $1 karakterből kell állnia.",
        "passwordtoolong": "A jelszó nem lehet hosszabb $1 karakternél.",
        "passwordtoopopular": "A gyakran használt jelszavak nem használhatók. Válassz olyan jelszót, amit nehezebb kitalálni.",
+       "passwordinlargeblacklist": "A megadott jelszó szerepel a gyakran használt jelszavak listáján. Kérlek, válassz egyedibb jelszót.",
        "password-name-match": "A jelszavadnak különböznie kell a szerkesztőnevedtől.",
        "password-login-forbidden": "Ezen felhasználónév és jelszó használata tiltott.",
        "mailmypassword": "Jelszó alaphelyzetbe állítása",
        "subject-preview": "Tárgy előnézete:",
        "previewerrortext": "Hiba történt a változások előnézetének megjelenítése során.",
        "blockedtitle": "A szerkesztő blokkolva van",
+       "blocked-email-user": "<strong>Szerkesztőneved számára az e-mail küldési lehetőséget blokkoltuk. Továbbra is szerkeszthetsz egyéb lapokat.</strong> A blokkolás további részleteit a [[Special:MyContributions|fiók közreműködéseinél]] találod.\n\nA blokkolást $1 hajtotta végre.\n\nAz általa megadott indok: <em>$2.</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n* A blokkolás azonosítószáma: $5",
+       "blockedtext-partial": "<strong>Szerkesztőneved vagy IP-címed számára az oldal szerkesztését blokkoltuk. Továbbra is szerkeszthetsz egyéb lapokat.</strong> A blokkolás további részleteit a [[Special:MyContributions|fiók közreműködéseinél]] találod.\n\nA blokkolást $1 hajtotta végre.\n\nAz általa megadott indok: <em>$2.</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n* A blokkolás azonosítószáma: $5",
        "blockedtext": "<strong>A szerkesztőnevedet vagy az IP-címedet blokkoltuk.</strong>\n\nA blokkolást $1 végezte el.\nAz általa felhozott indok: <em>$2.</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nKapcsolatba léphetsz $1 szerkesztőnkkel vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\nAz „{{int:emailuser}}” funkciót csak akkor használhatod, ha érvényes e-mail-címet adtál meg [[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
        "autoblockedtext": "Az IP-címed automatikusan blokkolva lett, mert korábban egy olyan szerkesztő használta, akit $1 blokkolt, az alábbi indoklással:\n\n:''$2''\n\n*A blokk kezdete: '''$8'''\n*A blokk lejárata: '''$6'''\n*Blokkolt szerkesztő: '''$7'''\n\nKapcsolatba léphetsz $1 szerkesztőnkkel, vagy egy másik [[{{MediaWiki:Grouppage-sysop}}|adminisztrátorral]], és megbeszélheted vele a blokkolást.\n\nAz „{{int:emailuser}}” funkciót csak akkor használhatod, ha érvényes e-mail címet adtál meg\n[[Special:Preferences|fiókbeállításaidban]], és nem blokkolták a használatát.\n\nJelenlegi IP-címed: $3, a blokkolás azonosítószáma: #$5.\nKérjük, hogy érdeklődés esetén mindkettőt add meg.",
        "systemblockedtext": "A felhasználónevedet vagy IP-címedet automatikusan blokkolta a MediaWiki.\nA blokkolás indoka:\n\n:<em>$2</em>\n\n* A blokk kezdete: $8\n* A blokk lejárata: $6\n* Blokkolt szerkesztő: $7\n\nA jelenlegi IP-címed: $3.\nKérjük, hogy érdeklődés esetén minden fenti részletet adj meg.",
        "converter-manual-rule-error": "Hiba van a kézi nyelvi konverziós szabályban",
        "undo-success": "A szerkesztés visszavonható. Kérlek ellenőrizd alább a változásokat, hogy valóban ezt szeretnéd-e tenni, majd kattints a lap mentése gombra a visszavonás véglegesítéséhez.",
        "undo-failure": "A szerkesztést nem lehet automatikusan visszavonni vele ütköző későbbi szerkesztések miatt.",
+       "undo-main-slot-only": "A szerkesztést nem lehet automatikusan visszavonni, mert érinti a tartalom más részét is.",
        "undo-norev": "A szerkesztés nem állítható vissza, mert nem létezik vagy törölve lett.",
        "undo-nochange": "A szerkesztés már vissza lett állítva.",
        "undo-summary": "Visszavontam [[Special:Contributions/$2|$2]] ([[User talk:$2|vita]]) szerkesztését (oldid: $1)",
        "recentchangescount": "Az alapértelmezettként mutatott szerkesztések száma a friss változtatásoknál, laptörténetekben és naplókban:",
        "prefs-help-recentchangescount": "Legfeljebb 1000",
        "prefs-help-watchlist-token2": "Ez a titkos kulcs a figyelőlistádhoz.\nAki ismeri, meg tudja nézni, milyen lapokat figyelsz, úgyhogy ne oszd meg másokkal.\nHa meg szeretnéd változtatni, [[Special:ResetTokens|kattints ide]].",
+       "prefs-help-tokenmanagement": "Megtekintheted és új titkos kulcsot generálhatsz, amivel a webes feedek hozzáférhetnek a figyelőlistádhoz. Bárki, aki ismeri ezt a kulcsot képes olvasni a figyelőlistád tartalmát, ezért ne oszd meg mással.",
        "savedprefs": "Az új beállításaid érvénybe léptek.",
        "savedrights": "{{GENDER:$1|$1}} felhasználói csoportjai el lettek mentve.",
        "timezonelegend": "Időzóna:",
        "localtime": "Helyi idő:",
        "timezoneuseserverdefault": "Az alapértelmezett beállítás használata ($1)",
        "timezoneuseoffset": "Egyéb (eltérés megadása)",
+       "timezone-useoffset-placeholder": "Példaértékek: „-07:00” vagy „01:00”",
        "servertime": "A kiszolgáló ideje:",
        "guesstimezone": "Töltse ki a böngésző",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Szerkesztő",
        "prefs-preview": "Előnézet",
        "prefs-advancedrc": "Haladó beállítások",
-       "prefs-opt-out": "Fejlesztések kikapcsolása",
        "prefs-advancedrendering": "Haladó beállítások",
        "prefs-advancedsearchoptions": "Haladó beállítások",
        "prefs-advancedwatchlist": "Haladó beállítások",
        "rcfilters-watchlist-markseen-button": "Összes változtatás megjelölése olvasottként",
        "rcfilters-watchlist-edit-watchlist-button": "A figyelőlistád szerkesztése",
        "rcfilters-watchlist-showupdated": "Az újabb változtatások, amiket még nem néztél meg, <strong>vastagítva</strong> láthatók, kitöltött jelzőkkel.",
-       "rcfilters-preference-label": "A friss változtatások fejlesztett változatának elrejtése",
-       "rcfilters-preference-help": "A 2017-es felületátdolgozás és minden azóta hozzáadott eszköz visszaállítása.",
-       "rcfilters-watchlist-preference-label": "A Figyelőlista fejlesztett változatának elrejtése",
-       "rcfilters-watchlist-preference-help": "A 2017-es felületátdolgozás és minden azóta hozzáadott eszköz visszaállítása.",
+       "rcfilters-preference-label": "JavaScript-nélküli felület használata",
+       "rcfilters-preference-help": "Friss változtatások betöltése szűrők és kiemelések nélkül.",
+       "rcfilters-watchlist-preference-label": "JavaScript-nélküli felület használata",
+       "rcfilters-watchlist-preference-help": "Friss változtatások betöltése szűrők és kiemelések nélkül.",
        "rcfilters-filter-showlinkedfrom-label": "A következő lapra hivatkozó lapok változtatásainak megjelenítése",
        "rcfilters-filter-showlinkedfrom-option-label": "A kiválasztott <strong>lapról</strong> hivatkozott lapok",
        "rcfilters-filter-showlinkedto-label": "A következő lapról hivatkozott lapok változtatásainak megjelenítése",
        "ipb-disableusertalk": "Megakadályozza, hogy a felhasználó szerkeszthesse a saját vitalapját, miközben blokkolva van",
        "ipb-change-block": "Blokk beállításainak megváltoztatása",
        "ipb-confirm": "Blokk megerősítése",
+       "ipb-sitewide": "Teljes körű",
+       "ipb-partial": "Részleges",
        "ipb-type-label": "Típus",
        "ipb-pages-label": "Lapok",
        "badipaddress": "Érvénytelen IP-cím",
        "createaccountblock": "új felhasználó létrehozása blokkolva",
        "emailblock": "e-mail-cím blokkolva",
        "blocklist-nousertalk": "nem szerkesztheti a vitalapját",
+       "blocklist-editing": "szerkesztés",
+       "blocklist-editing-sitewide": "szerkesztés (teljes körű)",
        "ipblocklist-empty": "A blokkoltak listája üres.",
        "ipblocklist-no-results": "A kért IP-cím vagy felhasználónév nem blokkolt.",
        "blocklink": "blokkolás",
        "move-watch": "Figyeld a lapot",
        "movepagebtn": "Lap átnevezése",
        "pagemovedsub": "Az átnevezés sikerült",
+       "cannotmove": "A lapot nem sikerült átnevezni a következő {{PLURAL:$1|ok|okok}} miatt:",
        "movepage-moved": "'''„$1” átnevezve „$2” névre'''",
        "movepage-moved-redirect": "Átirányítás létrehozva.",
        "movepage-moved-noredirect": "A régi címről nem készült átirányítás.",
+       "movepage-delete-first": "A céloldal túl sok változattal rendelkezik ahhoz, ezért az átnevezés részeként nem törölhető. Kérlek, előbb töröld a lapot kézzel, aztán próbáld újra.",
        "articleexists": "Ilyen névvel már létezik lap, vagy az általad választott név érvénytelen.\nKérlek, válassz egy másik nevet.",
        "cantmove-titleprotected": "Nem nevezheted át a lapot, mert az új cím le van védve a létrehozás ellen.",
        "movetalk": "Nevezd át a vitalapot is, ha lehetséges",
        "confirm-mcrundo-title": "Egy változtatás visszavonva",
        "mcrundofailed": "A visszavonás nem sikerült",
        "mcrundo-missingparam": "Kötelező paraméterek hiányoznak a kérésből.",
+       "mcrundo-changed": "A változtatások megtekintése óta az oldal megváltozott. Kérlek, tekintsd meg az új változtatásokat.",
        "ellipsis": "…",
        "quotation-marks": "„$1”",
        "imgmultipageprev": "← előző oldal",
        "logentry-block-block": "$1 {{GENDER:$2|blokkolta}} „{{GENDER:$4|$3}}”-t $5 időtartamra $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|feloldotta}} {{GENDER:$4|$3}} blokkolását",
        "logentry-block-reblock": "$1 {{GENDER:$2|módosította}} a blokk beállításokat „{{GENDER:$4|$3}}” szerkesztőnél $5 időtartamra $6",
+       "logentry-partialblock-block": "$1 {{GENDER:$2|blokkolta}} „{{GENDER:$4|$3}}”-t $5 időtartamra $6 a következő {{PLURAL:$8|lap|lapok}} szerkesztésétől: $7",
+       "logentry-partialblock-reblock": "$1 {{GENDER:$2|módosította}} a(z) $7 {{PLURAL:$8|lap|lapok}} szerkesztését megakadályozó blokk beállítását „{{GENDER:$4|$3}}” szerkesztőnél $5 időtartamra $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokkolta}} „{{GENDER:$4|$3}}”-t nem-szerkesztési műveletektől $5 időtartamra $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|módosította}} a nem-szerkesztési műveletekre vonatkozó blokk beállításait „{{GENDER:$4|$3}}” szerkesztőnél $5 időtartamra $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blokkolta}} „{{GENDER:$4|$3}}”-t $5 időtartamra $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|módosította}} a blokk beállításokat „{{GENDER:$4|$3}}” szerkesztőnél $5 időtartamra $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importálta}} $3 lapot fájl feltöltéssel",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "A jelszó nem lehet azonos a feketelistán szereplő jelszavakkal.",
        "passwordpolicies-policy-maximalpasswordlength": "A jelszó legfeljebb $1 karakter hosszú lehet",
        "passwordpolicies-policy-passwordcannotbepopular": "A jelszó nem {{PLURAL:$1|lehet a gyakran használt jelszó|szerepelhet a(z) $1 leggyakrabban használt jelszó listáján}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "A jelszó nem szerepelhet a 100 000 leggyakrabban használt jelszó listáján .",
        "unprotected-js": "Biztonsági okokból JavaScript nem tölthető be védtelen lapokról. Kérlek egyedül a MediaWiki névtérben készíts JavaScriptet, vagy szerkesztői allapként."
 }
index a49a433..bdad332 100644 (file)
        "noarticletext": "Ներկայումս այս էջում որևէ տեքստ չկա։\nԴուք կարող եք [[Special:Search/{{PAGENAME}}|որոնել այս անվանումը]] այլ էջերում, <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} որոնել համապատասխան տեղեկամատյանները] կամ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ստեղծել նոր էջ այս անվանմամբ]</span>։",
        "noarticletext-nopermission": "Ներկայումս այս էջում որևէ տեքստ չկա։\nԴուք կարող եք [[Special:Search/{{PAGENAME}}|որոնել այս անվանունը]] այլ էջերում կամ <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} որոնել այն տեղեկամատյաններում]</span>։ Դուք չունեք թույլտվություն ստեղծել այս էջը։",
        "userpage-userdoesnotexist": "«<nowiki>$1</nowiki>» անվանմամբ մասնակից գոյություն չունի։\nԽնդրում ենք հավաստիանալ նրանում, թե արդյոք ուզում եք ստեղծել/խմբագրել այս էջը։",
-       "userpage-userdoesnotexist-view": "«$1» Õ¡Õ¶Õ¾Õ¡Õ¶Õ´Õ¡Õ´Õ¢ Õ£Ö\80Õ¡Õ¶Ö\81Õ¾Õ¡Õ® Õ´Õ¡Õ½Õ¶Õ¡Õ¯Õ«Ö\81 Õ¹Õ¯Õ¡Ö\89",
+       "userpage-userdoesnotexist-view": "«$1» անվամբ գրանցված մասնակից չկա։",
        "blocked-notice-logextract": "Այս մասնակիցը ներկա պահին արգելափակված է։\nՍտորև ներկայացված է արգելափակման տեղեկամատյանի վերջին գրառումը.",
        "clearyourcache": "'''Ծանուցում. Հիշելուց հետո կատարված փոփոխությունները տեսնելու համար մաքրեք ձեր զննարկիչի հիշապահեստը. '''\n'''Mozilla / Firefox / Safari'''՝ ''Ctrl+Shift+R''  (''Cmd+Shift+R'' Mac OS X-ում)\n'''Konqueror'''՝ ''F5''\n'''Opera'''՝ ''Tools→Preferences'' ընտրացանկից։\n'''Internet Explorer'''՝ ''Ctrl+F5''",
        "usercssyoucanpreview": "'''Հուշում.''' Էջը հիշելուց առաջ օգտվեք «{{int:showpreview}}» կոճակից՝ ձեր նոր CSS-նիշքը ստուգելու համար։",
        "prefs-signature": "Ստորագրություն",
        "prefs-dateformat": "Ամսաթվի ձևաչափ",
        "prefs-timeoffset": "Ժամային տարբերություն",
-       "prefs-advancedediting": "Ընդլայնված ընրանքներ",
+       "prefs-advancedediting": "Ընդլայնված ընտրանքներ",
        "prefs-editor": "Խմբագիր",
        "prefs-preview": "Նախադիտել",
-       "prefs-advancedrc": "Ընդլայնված ընրանքներ",
-       "prefs-advancedrendering": "Ընդլայնված ընրանքներ",
-       "prefs-advancedsearchoptions": "Ընդլայնված ընրանքներ",
-       "prefs-advancedwatchlist": "Ընդլայնված ընրանքներ",
+       "prefs-advancedrc": "Ընդլայնված ընտրանքներ",
+       "prefs-advancedrendering": "Ընդլայնված ընտրանքներ",
+       "prefs-advancedsearchoptions": "Ընդլայնված ընտրանքներ",
+       "prefs-advancedwatchlist": "Ընդլայնված ընտրանքներ",
        "prefs-displayrc": "Ցուցադրման ընտրանքներ",
        "prefs-displaywatchlist": "Ցուցադրման ընտրանքներ",
        "prefs-diffs": "Տարբերություններ",
        "license-nopreview": "(Նախադիտումը մատչելի չէ)",
        "upload_source_url": " (գործուն, հանրամատչելի URL-հասցե)",
        "upload_source_file": " (նիշք ձեր համակարգչի վրա)",
-       "listfiles_search_for": "Õ\88Ö\80Õ¸Õ¶Õ¥Õ¬ ÕºÕ¡Õ¿Õ¯Õ¥Ö\80Õ« Õ¡Õ¶Õ¾Õ¡Õ¶Õ´Õ¡Õ´Õ¢.",
+       "listfiles_search_for": "Որոնել պատկերի անվամբ.",
        "imgfile": "նիշք",
        "listfiles": "Նիշքերի ցանկ",
        "listfiles_date": "Օր/Ժամ",
index f3b1683..2205e10 100644 (file)
        "timezonelegend": "Fuso horari:",
        "localtime": "Hora local:",
        "timezoneuseserverdefault": "Usar le valor predefinite del wiki ($1)",
-       "timezoneuseoffset": "Altere (specifica le differentia)",
+       "timezoneuseoffset": "Altere (specifica le differentia hic infra)",
+       "timezone-useoffset-placeholder": "Exemplo de valores: \"-07:00\" or \"01:00\"",
        "servertime": "Hora del servitor:",
        "guesstimezone": "Obtener del navigator",
        "timezoneregion-africa": "Africa",
        "prefs-editor": "Editor",
        "prefs-preview": "Previsualisation",
        "prefs-advancedrc": "Optiones avantiate",
-       "prefs-opt-out": "Non incorporar meliorationes",
        "prefs-advancedrendering": "Optiones avantiate",
        "prefs-advancedsearchoptions": "Optiones avantiate",
        "prefs-advancedwatchlist": "Optiones avantiate",
index 0bc134c..786339e 100644 (file)
        "prefs-editor": "Penyunting",
        "prefs-preview": "Pratayang",
        "prefs-advancedrc": "Opsi lanjutan",
-       "prefs-opt-out": "Memilih keluar dari perbaikan",
        "prefs-advancedrendering": "Opsi lanjutan",
        "prefs-advancedsearchoptions": "Opsi lanjutan",
        "prefs-advancedwatchlist": "Opsi lanjutan",
index 058bcbe..b13c7c1 100644 (file)
        "prefs-developertools": "Кийчдархочун кечалаш",
        "prefs-preview": "Хьалххе бIаргтохар",
        "prefs-advancedrc": "Кхыдола шердаь оттамаш",
-       "prefs-opt-out": "Алсамдалар тӀацаэцар",
        "prefs-advancedrendering": "Кхыдола шердаь оттамаш",
        "prefs-advancedsearchoptions": "Шердаь оттамаш",
        "prefs-advancedwatchlist": "Кхыдола шердаь оттамаш",
index 8940fb6..03ba77d 100644 (file)
        "prefs-editor": "Ritsjóri",
        "prefs-preview": "Forskoðun",
        "prefs-advancedrc": "Háþróaðir möguleikar",
-       "prefs-opt-out": "Hafna endurbótum",
        "prefs-advancedrendering": "Háþróaðir möguleikar",
        "prefs-advancedsearchoptions": "Háþróaðir möguleikar",
        "prefs-advancedwatchlist": "Háþróaðir möguleikar",
index 34ff7dc..1b4220b 100644 (file)
        "passwordtooshort": "Le password devono contenere almeno {{PLURAL:$1|1 carattere|$1 caratteri}}.",
        "passwordtoolong": "La password non può contenere più di {{PLURAL:$1|1 carattere|$1 caratteri}}.",
        "passwordtoopopular": "Password comuni non possono essere usate. Scegli una password più difficile da indovinare.",
+       "passwordinlargeblacklist": "La password inserita è nell'elenco delle password utilizzate più comunemente. Si prega di scegliere una password più unica.",
        "password-name-match": "La password deve essere diversa dal nome utente.",
        "password-login-forbidden": "L'uso di questo nome utente e password è stato proibito.",
        "mailmypassword": "Reimposta password",
        "timezonelegend": "Fuso orario:",
        "localtime": "Ora locale:",
        "timezoneuseserverdefault": "Usa ora predefinita del wiki ($1)",
-       "timezoneuseoffset": "Altro (specificare differenza)",
+       "timezoneuseoffset": "Altro (specifica differenza sotto)",
+       "timezone-useoffset-placeholder": "Valori di esempio: \"-07:00\" o \"01:00\"",
        "servertime": "Ora del server:",
        "guesstimezone": "Usa l'ora del browser",
        "timezoneregion-africa": "Africa",
        "prefs-editor": "Editore",
        "prefs-preview": "Anteprima",
        "prefs-advancedrc": "Opzioni avanzate",
-       "prefs-opt-out": "Disattivazione dei miglioramenti",
        "prefs-advancedrendering": "Opzioni avanzate",
        "prefs-advancedsearchoptions": "Opzioni avanzate",
        "prefs-advancedwatchlist": "Opzioni avanzate",
        "tooltip-ca-move": "Sposta questa pagina (cambia titolo)",
        "tooltip-ca-watch": "Aggiungi questa pagina alla tua lista degli osservati speciali",
        "tooltip-ca-unwatch": "Rimuovi questa pagina dalla tua lista degli osservati speciali",
-       "tooltip-search": "Cerca all'interno di {{SITENAME}}",
+       "tooltip-search": "Cerca in {{SITENAME}}",
        "tooltip-search-go": "Vai a una pagina con il titolo indicato, se esiste",
        "tooltip-search-fulltext": "Cerca il testo indicato nelle pagine",
        "tooltip-p-logo": "Visita la pagina principale",
        "feedback-thanks": "Grazie! Il tuo feedback è stato pubblicato alla pagina \"[$2 $1]\".",
        "feedback-thanks-title": "Grazie!",
        "feedback-useragent": "User agent:",
-       "searchsuggest-search": "Cerca all'interno di {{SITENAME}}",
+       "searchsuggest-search": "Cerca in {{SITENAME}}",
        "searchsuggest-containing": "contenente...",
        "api-error-badtoken": "Errore interno: token errato.",
        "api-error-emptypage": "La creazione di nuove pagine vuote non è consentita.",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "La password non può corrispondere a password specificate nell'elenco delle password proibite",
        "passwordpolicies-policy-maximalpasswordlength": "La password deve essere lunga meno di $1 {{PLURAL:$1|carattere|caratteri}}",
        "passwordpolicies-policy-passwordcannotbepopular": "La password non può essere {{PLURAL:$1|la password più popolare|nell'elenco delle $1 password più popolari}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "La password non può essere nell'elenco delle 100 000 password utilizzate più comunemente.",
        "unprotected-js": "Per motivi di sicurezza, non è possibile caricare JavaScript da pagine non protette. Crea javascript solo nel namespace MediaWiki o come sottopagina Utente"
 }
index ca3f978..ab933ca 100644 (file)
        "prefs-editor": "エディター",
        "prefs-preview": "プレビュー",
        "prefs-advancedrc": "詳細の設定",
-       "prefs-opt-out": "改善の使用を断る",
        "prefs-advancedrendering": "詳細の設定",
        "prefs-advancedsearchoptions": "詳細設定",
        "prefs-advancedwatchlist": "詳細の設定",
index fdbe738..f50fe7c 100644 (file)
        "newsectionsummary": "/* $1 */ pérangan anyar",
        "rc-enhanced-expand": "Tuduhaké princèn",
        "rc-enhanced-hide": "Dhelikaké princèn",
-       "rc-old-title": "kawitané digawé minangka \"$1\"",
+       "rc-old-title": "kawitané kagawé minangka \"$1\"",
        "recentchangeslinked": "Owahan magepokan",
        "recentchangeslinked-feed": "Owah-owahan kang magepokan",
        "recentchangeslinked-toolbox": "Owahan magepokan",
index 0a454f9..15a7a4f 100644 (file)
        "prefs-editor": "რედაქტორი",
        "prefs-preview": "წინასწარი გადახედვა",
        "prefs-advancedrc": "გაფართოებული პარამეტრები",
-       "prefs-opt-out": "გაუმჯობესების გამორიცხვა",
        "prefs-advancedrendering": "გაფართოებული პარამეტრები",
        "prefs-advancedsearchoptions": "გაფართოებული პარამეტრები",
        "prefs-advancedwatchlist": "გაფართოებული კონფიგურაციები",
index ad8495c..81ff335 100644 (file)
        "preferences": "ဆ်ုလုဲႋလ်ုဖး",
        "mypreferences": "မ်ုလုဲႋၯံင်လ်ုဖး",
        "prefs-user-pages": "ဆ်ုသုံႋဏင့်ဆာႋ လိက်မေံၜၠါ်လ်ုဖး",
+       "prefs-watchlist": "ခိုဝ်ယောဝ်ႋစ်ုရင့်",
        "username": "{{GENDER:$1|ဆ်ုသုံႋဆာႋမိင်}}:",
        "editusergroup": "မ်ုၮဲဖှ်ေ ဆ်ုသုံႋဆာႋကုံရွာဲ",
        "group-user": "ဆ်ုသုံႋဆာႋလ်ုဖး",
        "upload": "မ်ုပ္တုံင်ထါင်ဖိုင်ႋ",
        "uploadlogpage": "ဖိုင်ႋတုံထါင်း ဆ်ုမာၮါင်း",
        "filedesc": "အ်ုအိင်း",
+       "upload-form-label-infoform-description": "ဆ်ုဏဲဖၠဟ်",
        "license": "လိုင်စင်ပၞံင့်ပ္တုံ",
        "license-header": "လိုင်စင်ပၞံင့်ပ္တုံ",
        "imgfile": "ဖိုင်ႋ",
        "listfiles": "ဖိုင်ႋစ်ုရင့်",
+       "listfiles_description": "ဆ်ုဏဲဖၠဟ်",
        "listfiles-latestversion-yes": "မွာဲ",
        "file-anchor-link": "ဖိုင်",
        "filehist": "ဃွှာန့်မေင်ႋစိင်",
        "nmembers": "ကုံလွာဲဆာ $1 {{PLURAL:$1|ၮါင်း|ၮါင်းလ်ုဖး}}",
        "prefixindex": "အ်ုမေံယာ့ prefix အှ် လိက်မေံၜၠါ်လုက်ဆိင့်",
        "listusers": "ဆ်ုအင်းသုံ့ဆာစ်ုရင့်",
+       "usercreated": "$1 $2 အ်ုခါ့ဏှ် {{GENDER:$3|ပ္တံင်ထ​ဝေ့လှ်}}",
        "newpages": "လိက်မေံသင့်",
        "newpages-username": "ဏင့်ဆာႋမိင်:",
        "move": "မ်ုသုဂ်",
        "namespace_association": "ထိုဝ်ၜိုဒ်ၜးဍံင်အှ် ၮဲဖှ်ေမိင်ႋ",
        "tooltip-namespace_association": "လုဲႋထ အ်ုမၠိင်က္ဍာထါင်လ်ု ၜးထိုဝ်ၜုဂ်လိက်လ်ုဖး အှ်ကုံဆ်ုခၠါင် လ်ုမွာဲၜး အ်ုၯာင်းအ်ုကျံင် အ်ုမိင်ထါင်ၮဲထါင် မ်ုပါ့ၯင်း လိက်လင်ခွင်ဝယ်ယိုဝ် ဆူ့လင်ဆ်ုၜးကီလာဆှ်",
        "blanknamespace": "(ခေါဟ်)",
-       "contributions": "{{GENDER:$1|á\80\86á\80ºá\80¯á\80\9eá\80¯á\80¶á\82\8bá\80\86á\80¬á\82\8b}}á\80\81á\80\9dá\80·á\80º á\80\86á\80ºá\80¯á\80\9eá\80¯á\80\82á\80ºá\80\80á\81 á\80\9aá\80ºလ်ုဖး",
+       "contributions": "{{GENDER:$1|á\80\86á\80ºá\80¯á\80\9eá\80¯á\80¶á\82\8bá\80\8fá\80\84á\80·á\80ºá\80\86á\80¬á\82\8b}}á\80\81á\80\9dá\80·á\80º á\80\86á\80ºá\80¯á\80¡á\80\84á\80ºá\80¸á\80\99á\80¬လ်ုဖး",
        "contributions-title": "$1 ၯင်း ဆ်ုအင်းသုံ့က်ုဆာ ဆ်ုဍုဂ်ဆ်ုကၠယ် $1",
        "mycontris": "ဆ်ုမာဖှ်ေထဆာႋလ်ုဖး",
        "anoncontribs": "ဆ်ုမာဖှ်ေထဆာႋလ်ုဖး",
        "tooltip-t-whatlinkshere": "အ်ုလင်ယိုဝ် ဆ်ုၮဲလင်လင့်ထ ဝီကီလိက်မေံစ်ုရင့်",
        "tooltip-t-recentchangeslinked": "လိက်မေံယိုဝ်ခဝ့် ၮဲဖှ်ေထါင်ထဝေ့ လိက်မေံသယ်လ်ုဖး အ်ုခါ့ ဆ်ုအင်းလဲါသာ့လ်ုဖး",
        "tooltip-feed-atom": "လိက်မေံယိုဝ်ၯင်း Atom feed",
-       "tooltip-t-contributions": "{{GENDER:$1|á\80\86á\80ºá\80¯á\80\9eá\80¯á\80¶á\80·á\80\80á\80ºá\80¯á\80\86á\80¬á\80\9aá\80­á\80¯á\80\9dá\80º}}á\80\81á\80\9dá\80·á\80º á\80\86á\80ºá\80¯á\80\90á\80¯á\80\82á\80ºá\80\80á\81 á\80\9aá\80º စ်ုရင့်",
+       "tooltip-t-contributions": "{{GENDER:$1|á\80\86á\80ºá\80¯á\80\9eá\80¯á\80¶á\80·á\80\8fá\80\84á\80·á\80ºá\80\86á\80¬á\82\8bá\80\9aá\80­á\80¯á\80\9dá\80º}}á\80\81á\80\9dá\80·á\80º á\80\86á\80ºá\80¯á\80¡á\80\84á\80ºá\80¸á\80\99á\80¬á\80\9cá\80ºá\80¯á\80\96á\80¸ စ်ုရင့်",
        "tooltip-t-emailuser": "{{GENDER:$1|ဆ်ုသုံ့ဆာအိုဝ်}} မ်ုသုံ့အီးမေး",
        "tooltip-t-upload": "မ်ုပ္တုံင်ထါင်ဖိုင်ႋ",
        "tooltip-t-specialpages": "လိက်မေံ ခေါဟ် လုက်ဆိင့်",
        "watchlisttools-raw": "ခိုဝ်ယောဝ်ႋစ်ုရင့် လိက်ခၠံင့်သယ် မ်ုအင်းတင်",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|လေဝ်ထါင်ဆ်ုခၠါင်]])",
        "version-specialpages": "လိက်မေံၜၠါ်ခေါဟ်လ်ုဖး",
+       "version-ext-colheader-description": "ဆ်ုဏဲဖၠဟ်",
+       "version-libraries-description": "ဆ်ုဏဲဖၠဟ်",
        "redirect": "ဖိုင်ႋ၊ သုံ့က်ုဆာ၊ လိက်မေံၜၠါ်၊ ဆ်ုအင်းတင်၊ လ်ုမွာဲၜး မာၮါင်းအိုင်ဒီ ခဝ့် ထါင်ၮဲထါင်ဖှ်ေ",
        "redirect-summary": "လိက်မေံခေါဟ်ယိုဝ် ဖိုင်ႋလ်ုၮါင်း (ဖှ်ေထ ဖိုင်ႋအ်ုမိင်)၊ လိက်မေံလ်ုၮါင်း (ဖှ်ေထ ဆ်ုအင်းတင် အိုင်ဒီ လ်ု လိက်မေံၜၠါ်အိုင်ဒီ)၊ ဆ်ုသုံ့ဆာမိင် (ဖှ်ေထ ဆ်ုသုံ့ဆာမိင်ဝီႋဖၠုံးအိုင်ဒီ)၊ လ်ုမွာဲၜး မာၮါင်းလ်ုၮါင်း (ဖှ်ေထ ဆ်ုမာၮါင်းအိုင်ဒီ) ခဝ့်အိုဝ် ထါင်ၮဲထါင်ဆေဝ်ႋလှ်။ ၜးသုံ့ပ်ုဍံင် - [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/page/64308]], [[{{#Special:Redirect}}/revision/328429]], [[{{#Special:Redirect}}/user/101]], လ်ုမွာဲၜး [[{{#Special:Redirect}}/logid/186]].",
        "redirect-submit": "လေဝ်",
index d78e8a2..ab618c0 100644 (file)
        "prefs-editor": "ឧបករណ៍កែប្រែ",
        "prefs-preview": "ឧបករណ៍មើលជាមុន",
        "prefs-advancedrc": "ជម្រើសថ្នាក់ខ្ពស់",
-       "prefs-opt-out": "ជម្រើសមិនប្រើមុខងារជឿនលឿន",
        "prefs-advancedrendering": "ជម្រើសថ្នាក់ខ្ពស់",
        "prefs-advancedsearchoptions": "ជម្រើសថ្នាក់ខ្ពស់",
        "prefs-advancedwatchlist": "ជម្រើសថ្នាក់ខ្ពស់",
index c4e4798..7f9b5d1 100644 (file)
        "userlogin-reauth": "당신이 {{GENDER:$1|$1}}임을 검증하려면 다시 로그인해야 합니다.",
        "userlogin-createanother": "다른 계정 만들기",
        "createacct-emailrequired": "이메일 주소",
-       "createacct-emailoptional": "이메일 주소 (선택 사항)",
+       "createacct-emailoptional": "이메일 주소(선택 사항)",
        "createacct-email-ph": "이메일 주소를 입력하세요",
        "createacct-another-email-ph": "이메일 주소를 입력하세요",
        "createaccountmail": "임의의 임시 비밀번호를 이메일로 보내기",
        "createaccountmail-help": "비밀번호를 기억하지 않고도 다른 사용자를 위한 계정을 만들 수 있습니다.",
        "createacct-realname": "실명 (선택 사항)",
        "createacct-reason": "이유",
-       "createacct-reason-ph": "왜 다른 계정을 또 만들어야 합니까",
+       "createacct-reason-ph": "다른 계정을 만들어야 하는 이유가 있나요",
        "createacct-reason-help": "계정 생성 로그에 표시되는 메시지",
        "createacct-submit": "계정 만들기",
        "createacct-another-submit": "계정 만들기",
        "localtime": "현지 시각:",
        "timezoneuseserverdefault": "위키 기본값 사용 ($1)",
        "timezoneuseoffset": "기타 (시차를 입력해주세요)",
+       "timezone-useoffset-placeholder": "예시 값: \"-07:00\" 또는 \"01:00\"",
        "servertime": "서버 시각:",
        "guesstimezone": "웹 브라우저 설정에서 가져오기",
        "timezoneregion-africa": "아프리카",
        "prefs-editor": "편집기",
        "prefs-preview": "미리 보기",
        "prefs-advancedrc": "고급 옵션",
-       "prefs-opt-out": "개선 기능에 참여하지 않음",
        "prefs-advancedrendering": "고급 옵션",
        "prefs-advancedsearchoptions": "고급 옵션",
        "prefs-advancedwatchlist": "고급 옵션",
        "prefs-displayrc": "표시 설정",
        "prefs-displaywatchlist": "표시 설정",
+       "prefs-changesrc": "표시되는 변경사항",
+       "prefs-changeswatchlist": "표시되는 변경사항",
        "prefs-pageswatchlist": "주시 중인 문서",
        "prefs-tokenwatchlist": "토큰",
        "prefs-diffs": "차이",
        "enotif_impersonal_salutation": "{{SITENAME}} 사용자",
        "enotif_subject_deleted": "{{SITENAME}} $1 문서를 $2님이 {{GENDER:$2|삭제했습니다}}",
        "enotif_subject_created": "{{SITENAME}} $1 문서를 $2님이 {{GENDER:$2|만들었습니다}}",
-       "enotif_subject_moved": "{{SITENAME}} $1 ë¬¸ì\84\9c를 $2ë\8b\98ì\9d´ {{GENDER:$2|ì\9d´ë\8f\99í\8c¼습니다}}",
+       "enotif_subject_moved": "{{SITENAME}} $1 ë¬¸ì\84\9c를 $2ë\8b\98ì\9d´ {{GENDER:$2|ì\9d´ë\8f\99í\96\88습니다}}",
        "enotif_subject_restored": "{{SITENAME}} $1 문서를 $2님이 {{GENDER:$2|복구했습니다}}",
        "enotif_subject_changed": "{{SITENAME}} $1 문서를 $2님이 {{GENDER:$2|바꾸었습니다}}",
        "enotif_body_intro_deleted": "{{SITENAME}} $1 문서를 $PAGEEDITDATE에 $2님이 {{GENDER:$2|삭제했으며}} $3 에서 볼 수 있습니다.",
index 8dcda29..880416a 100644 (file)
        "updated": "(Novata)",
        "note": "'''Nota:'''",
        "previewnote": "<strong>Memento istud nihil esse nisi prospectum!</strong>\nMutationes tuae nondum servatae sunt!",
-       "editing": "Recensio paginae \"$1\"",
-       "creating": "Creans $1",
-       "editingsection": "Recensens $1 (partem)",
-       "editingcomment": "Recensens $1 (nova pars)",
+       "editing": "Recensetur $1",
+       "creating": "Creabitur $1",
+       "editingsection": "Recensetur $1 (partim)",
+       "editingcomment": "Recensetur $1 (nova pars)",
        "editconflict": "Contentio recensionis: $1",
        "explainconflict": "Alius hanc paginam mutavit postquam eadem recensere incipiebas.\nCapsa superior paginae verba recentissima continet.\nMutationes tuae in capsa inferiore monstrantur.\nMutationes tuae in verba superiora adiungare debes.\n'''Solum''' verba capsae superioris servabuntur quando \"$1\" premes.",
        "yourtext": "Tua redactio",
        "deletereason-dropdown": "*Causae deletionum communes\n** Spam\n** Vandalismus\n** Violatio verborum privatorum\n** Desiderium auctoris\n** Redirectio fracta",
        "delete-edit-reasonlist": "Causas deletionum recensere",
        "rollback": "Reverti mutationes",
-       "rollbacklink": "reverti",
+       "rollbacklink": "Plura statim revertere",
        "rollbacklinkcount": "reverti {{PLURAL:$1|unam recensionem|$1 recensiones}}",
        "rollbacklinkcount-morethan": "reverti plus quam {{PLURAL:$1|unam recensionem|$1 recensiones}}",
        "rollbackfailed": "Reversum defecit",
index 67f9963..33c0478 100644 (file)
        "prefs-editor": "Editeur",
        "prefs-preview": "Kucken ouni ofzespäicheren",
        "prefs-advancedrc": "Méi Optiounen",
-       "prefs-opt-out": "Verbesserungen net méi benotzen",
        "prefs-advancedrendering": "Méi Optiounen",
        "prefs-advancedsearchoptions": "Méi Optiounen",
        "prefs-advancedwatchlist": "Méi Optiounen",
        "rcfilters-watchlist-edit-watchlist-button": "Ännert Är Lëscht vun iwwerwaachte Säiten",
        "rcfilters-watchlist-showupdated": "Ännerungen op Säiten déi Dir net besicht hutt zanter d'Ännerunge gemaach goufen si <strong>fett</strong> geschriwwen.",
        "rcfilters-preference-label": "Déi verbessert Versioun vun de rezenten Ännerunge verstoppen",
-       "rcfilters-watchlist-preference-label": "Déi verbessert Versioun vun der Iwwerwaachungslëscht verstoppen",
+       "rcfilters-watchlist-preference-label": "Den Interface ouni JavaScript benotzen",
        "rcfilters-target-page-placeholder": "Gitt en Numm vun enger Säit (oder enger Kategorie) an",
        "rcnotefrom": "Hei drënner {{PLURAL:$5|gëtt d'Ännerung|ginn d'Ännerungen}} zanter <strong>$3, $4</strong> (maximal <strong>$1</strong> Ännerunge gi gewisen).",
        "rclistfromreset": "Eraussiche vum Datum zrécksetzen",
index 095dca9..094cbd1 100644 (file)
        "prefs-editor": "Editador",
        "prefs-preview": "Previde",
        "prefs-advancedrc": "Elejes avansada",
-       "prefs-opt-out": "No partisipa en bonis",
        "prefs-advancedrendering": "Elejes avansada",
        "prefs-advancedsearchoptions": "Elejes avansada",
        "prefs-advancedwatchlist": "Elejes avansada",
index bcbcc0b..e490d21 100644 (file)
        "prefs-editor": "Bewirker",
        "prefs-preview": "Veurbesjouwing",
        "prefs-advancedrc": "Wiejer instèllinger",
-       "prefs-opt-out": "Neet mitdoen aan de verbeteringe",
        "prefs-advancedrendering": "Wiejer instèllinger",
        "prefs-advancedsearchoptions": "Wiejer instèllinger",
        "prefs-advancedwatchlist": "Wiejer instèllinger",
index 0429e32..0887611 100644 (file)
        "prefs-editor": "Redaktorius",
        "prefs-preview": "Peržiūra",
        "prefs-advancedrc": "Papildomi nustatymai",
-       "prefs-opt-out": "Atsisakyti patobulinimų",
        "prefs-advancedrendering": "Papildomi nustatymai",
        "prefs-advancedsearchoptions": "Papildomi nustatymai",
        "prefs-advancedwatchlist": "Papildomi nustatymai",
index d06513a..23b1f10 100644 (file)
        "timezonelegend": "Laika josla:",
        "localtime": "Vietējais laiks:",
        "timezoneuseserverdefault": "Lietot viki noklusēto ($1)",
-       "timezoneuseoffset": "Cita (norādi starpību)",
+       "timezoneuseoffset": "Cita (norādi starpību zemāk)",
        "servertime": "Servera laiks šobrīd:",
        "guesstimezone": "Izmantot datora sistēmas laiku",
        "timezoneregion-africa": "Āfrika",
        "prefs-editor": "Redaktors",
        "prefs-preview": "Priekšskatījums",
        "prefs-advancedrc": "Papildu iespējas",
-       "prefs-opt-out": "Atteikties no uzlabojumiem",
        "prefs-advancedrendering": "Papildu iespējas",
        "prefs-advancedsearchoptions": "Papildu iespējas",
        "prefs-advancedwatchlist": "Papildu iespējas",
        "rcfilters-filtergroup-lastRevision": "Pašreizējās versijas",
        "rcfilters-filter-lastrevision-label": "Pašreizējā versija",
        "rcfilters-filter-lastrevision-description": "Tikai nesenākā lapas izmaiņa.",
-       "rcfilters-filter-previousrevision-label": "Agrākas versijas",
+       "rcfilters-filter-previousrevision-label": "Ne pēdējā versija",
        "rcfilters-filter-previousrevision-description": "Visas izmaiņas, kas nav lapas pēdējā izmaiņa.",
        "rcfilters-exclude-button-off": "Izslēgt izvēlētos",
        "rcfilters-view-tags": "Iezīmētie labojumi",
        "rcfilters-watchlist-markseen-button": "Atzīmēt visas izmaiņas kā apskatītas",
        "rcfilters-watchlist-edit-watchlist-button": "Labot manu uzraugāmo lapu sarakstu",
        "rcfilters-watchlist-showupdated": "Izmaiņas lapās, kuras nav apmeklētas kopš izmaiņu veikšanas, ir <strong>trekninātā rakstā</strong>.",
-       "rcfilters-preference-label": "Paslēpt uzlaboto pēdējo izmaiņu versiju",
+       "rcfilters-preference-label": "Izmantot saskarni bez JavaScript atbalsta",
        "rcfilters-target-page-placeholder": "Ievadi lapas nosaukumu (vai kategoriju)",
        "rcnotefrom": "Zemāk {{PLURAL:$5|redzamas izmaiņas|redzama izmaiņa|redzamas izmaiņas}} kopš <strong>$3, $4</strong> (parādītas ne vairāk kā <strong>$1</strong>).",
        "rclistfromreset": "Atiestatīt datuma izvēli",
        "speciallogtitlelabel": "Mērķis (nosaukums vai {{ns:user}}:lietotājvārds dalībniekam):",
        "log": "Reģistri",
        "logeventslist-submit": "Rādīt",
+       "logeventslist-patrol-log": "Pārbaudes reģistrs",
+       "logeventslist-tag-log": "Iezīmju žurnāls",
        "all-logs-page": "Visi publiski pieejamie reģistri",
        "alllogstext": "Visi pieejamie {{grammar:akuzatīvs{{SITENAME}}}} reģistri.\nTu vari sašaurināt aplūkojamo reģistru, izvēloties reģistra veidu, lietotāja vārdu vai reģistrēto lapu. Visi teksta lauki izšķir lielos un mazos burtus.",
        "logempty": "Reģistrā nav atbilstošu ierakstu.",
        "uctop": "pēdējā izmaiņa",
        "month": "No mēneša (un senāki):",
        "year": "No gada (un senāki):",
+       "date": "No datuma (un senāki):",
        "sp-contributions-newbies": "Rādīt jauno lietotāju devumu",
        "sp-contributions-newbies-sub": "Jaunie lietotāji",
        "sp-contributions-newbies-title": "Jauno dalībnieku devums",
        "logentry-delete-delete": "$1 {{GENDER:$2|izdzēsa}} lapu $3",
        "logentry-delete-delete_redir": "$1 {{GENDER:$2|izdzēsa}} pāradresāciju $3 pārrakstot",
        "logentry-delete-restore": "$1 {{GENDER:$2|atjaunoja}} lapu $3 ($4)",
+       "restore-count-revisions": "{{PLURAL:$1|$1 versijas|$1 versija|$1 versijas}}",
        "restore-count-files": "{{PLURAL: $1|$1 faili|$1 fails|$1 faili}}",
        "logentry-delete-revision": "$1 {{GENDER:$2|nomainīja}} $5 {{PLURAL:$5|versiju|versijas|versiju}} redzamību lapai $3: $4",
        "logentry-suppress-delete": "$1 {{GENDER:$2|cenzēja}} lapu $3",
        "revdelete-unrestricted": "noņemt administratoriem ierobežojumus",
        "logentry-block-block": "$1 {{GENDER:$2|nobloķēja}} {{GENDER:$4|$3}} ar beigu termiņu $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|atbloķēja}} {{GENDER:$4|$3}}",
+       "logentry-import-interwiki": "$1 {{GENDER:$2|importēja}} $3 no citas vikivietnes",
        "logentry-move-move": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4",
        "logentry-move-move-noredirect": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4, neatstājot pāradresāciju",
        "logentry-move-move_redir": "$1 {{GENDER:$2|pārvietoja}} lapu $3 uz $4, atstājot pāradresāciju",
index 173b798..58f558b 100644 (file)
        "views": "覽",
        "toolbox": "多寶",
        "tool-link-userrights": "{{GENDER:$1|職權}}",
+       "tool-link-userrights-readonly": "權界",
        "tool-link-emailuser": "{{GENDER:$1|遺書}}",
        "imagepage": "述",
        "mediawikipage": "觀訊",
        "editusergroup": "治社",
        "editinguser": "正纂簿<strong>[[User:$1|$1]]</strong>之權",
        "userrights-editusergroup": "治社",
+       "userrights-viewusergroup": "權界",
        "saveusergroups": "定之",
        "userrights-groupsmember": "有員:",
        "userrights-groupsmember-auto": "固有員:",
        "intentionallyblankpage": "此頁為白也,試速之用",
        "external_image_whitelist": " #同留<pre>\n#下(中之//)乃正表式\n#乃外(連)圖配之\n#配乃成像,非配則成連\n#有 # 之為注\n#無為大小之異也\n\n#入正表式。同留</pre>",
        "tag-filter": "[[Special:Tags|標]] 之濾:",
-       "tag-list-wrapper": "[[Special:Tags|$1簽]]: $2",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|簽}}]]: $2",
        "tags-title": "標",
        "tags-tag": "標名",
        "tags-source-header": "源",
index ce95f67..71caf85 100644 (file)
@@ -24,7 +24,8 @@
                        "Tulsi Bhagat",
                        "Macofe",
                        "राम प्रसाद जोशी",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Haribanshi"
                ]
        },
        "tog-underline": "लिङ्कके रेखाङ्कित करी:",
        "botpasswords-label-grants-column": "प्रदान कएल",
        "botpasswords-bad-appid": "बोट नाम \"$1\" मान्य नै अछि।",
        "resetpass_forbidden": "कूटशब्द नै बदलल जा सकैए।",
+       "resetpass_forbidden-reason": "कूटशब्द नै बदलल जा सकैए: $1",
        "resetpass-no-info": "अहाँकेँ ऐ पन्नाकेँ सोझे प्रयोग करबालेल सम्प्रवेशित हुअए पड़त।",
        "resetpass-submit-loggedin": "कूटशब्द बदली",
        "resetpass-submit-cancel": "रद्द करी",
        "passwordreset-emailtext-user": "प्रयोक्ता $1 {{अन्तर्जाल}} पर अहाँक खाता विवरणक {{SITENAME}} लेल फेरसँ ($4) आग्रह केने छथि। ई प्रयोक्ता {{PLURAL:$3|खाता अछि|खाता सभ अछि}} ऐ ई-पत्र संकेतसँ जुड़ल: $2\n{{PLURAL:$3| ई अस्थायी कूटशब्द|ई सभ अस्थायी कूटशब्द}} खतम भऽ जाएत {{PLURAL:$5|एक दिन|$5 दिन}} मे।\nअहाँ सम्प्रवेश करू आ एकटा नव कूटशब्द आब चुनू। जँ कियो दोसर ई आग्रह केने छथि, वा जँ अहाँकेँ अपन मूल कूटशब्द मोन पड़ि गेल अछि, आ अहाँ आब ओइ कूटशब्दकेँ नै बदलऽ चाहै छी, अहाँ ऐ संदेशकेँ बिसरि सकै छी आ अपन पुरान कूटशब्दक प्रयोग जारी राखि सकै छी।",
        "passwordreset-emailelement": "प्रयोक्ता: \n$1\n\nअस्थायी कूटशब्द: \n$2",
        "passwordreset-emailsentemail": "एकटा ई-पत्र मोन पाड़बा लेल पठाओल गेल अछि।",
+       "passwordreset-nocaller": "कॉलर प्रदान करैलजाय",
        "passwordreset-invalidemail": "अवैध इमेल ठेगान",
        "passwordreset-nodata": "प्रयोगकर्ता नाम वा इमेल ठेगान नै देल गेल छल",
        "changeemail": "ई-मेल पता परिवर्तित करी",
        "savechanges": "रक्षण करी",
        "publishpage": "पृष्ठ प्रकाशित करी",
        "publishchanges": "परिवर्तन प्रकाशित करी",
+       "savearticle-start": "पन्नाक रक्षण करू",
+       "savechanges-start": "रक्षण करी",
+       "publishpage-start": "पृष्ठ प्रकाशित करी",
+       "publishchanges-start": "परिवर्तन प्रकाशित करी",
        "preview": "पूर्वावलोकन",
        "showpreview": "पूर्वप्रदर्शन",
        "showdiff": "परिवर्तन देखाबी",
        "revdelete-unsuppress": "पुनर्स्थापित संशोधन लेल प्रतिबन्ध हटाबी",
        "revdelete-log": "कारण:",
        "revdelete-submit": "चयनित {{PLURAL:$1|संसोधन|संसोधनसभ}} पर लागू करी",
-       "revdelete-success": "'''संशोधन दृश्यता सफलतापूर्वक अद्यतन कएल गेल।'''",
+       "revdelete-success": "संशोधन दृश्यता सफलतापूर्वक अद्यतन कएल गेल।",
        "revdelete-failure": "संशोधन दृश्यता अद्यतन नै कएल जा सकल: $1",
-       "logdelete-success": "'''वृत्तलेख दृश्यता सफलतासँ निर्धारित भेल।'''",
+       "logdelete-success": "वृत्तलेख दृश्यता सफलतासँ निर्धारित भेल।",
        "logdelete-failure": "'''वृत्तलेख दृश्यता निर्धारित नै भऽ सकल।'''$1",
        "revdel-restore": "दृष्टिकुशलता बदली",
        "pagehist": "पन्नाक इतिहास",
        "username": "{{GENDER:$1|प्रयोगकर्तानाम}}:",
        "prefs-memberingroups": "निम्नलिखित {{PLURAL:$1|समूह|समूहसभ}}क {{GENDER:$2|सदस्य}}:",
        "prefs-memberingroups-type": "$1",
+       "group-membership-link-with-expiry": "$1 ($2 तक)",
        "prefs-registration": "पञ्जीकरणक समए:",
        "prefs-registration-date-time": "$1",
        "yourrealname": "असली नाम:",
        "prefs-dateformat": "तिथि प्रारूप",
        "prefs-timeoffset": "समए संशोधक",
        "prefs-advancedediting": "विशिष्ट विकल्प सभ",
+       "prefs-developertools": "डेवलपर उपकरण",
        "prefs-editor": "सम्पादक",
        "prefs-preview": "पूर्वावलोकन",
        "prefs-advancedrc": "विशिष्ट विकल्पसभ",
        "prefs-advancedwatchlist": "विशिष्ट विकल्पसभ",
        "prefs-displayrc": "दृश्य विकल्पसभ",
        "prefs-displaywatchlist": "दृश्य विकल्पसभ",
+       "prefs-changesrc": "बदलेलहा देखाल",
        "prefs-tokenwatchlist": "टोकन",
        "prefs-diffs": "अन्तर",
        "prefs-help-prefershttps": "इ प्राथमिकता अहाँके फेर स सम्प्रवेश करलाक बाद प्रभाव पडत।",
        "userrights": "प्रयोक्ता अधिकारक प्रबन्धन",
        "userrights-lookup-user": "प्रयोक्ता समूहसभक प्रबन्ध करी",
        "userrights-user-editname": "एकटा प्रयोक्तानाम लिखी:",
-       "editusergroup": "{{GENDER:$1|सदस्य}} समूहसभक सम्पादन करी",
+       "editusergroup": "प्रयोगकर्ता समूह देखालजाय",
        "editinguser": "सदस्य '''[[User:$1|$1]]''' $2 क अधिकार बदलि\n{{GENDER:$1|सदस्य}}क सदस्य अधिकार बदलल जा रहल अछि <strong>[[User:$1|$1]]</strong> $2",
        "userrights-editusergroup": "प्रयोगकर्ता समूह सम्पादित करी",
        "saveusergroups": "{{GENDER:$1|सदस्य}} समूह सङ्ग्रह करी",
        "group-autoconfirmed": "स्वतःअनुमोदित प्रयोक्ता",
        "group-bot": "स्वचालक",
        "group-sysop": "प्रबन्धक",
+       "group-interface-admin": "इंटरफ़ेस प्रशासक",
        "group-bureaucrat": "अधिकारी",
        "group-suppress": "नुकाबए वाला",
        "group-all": "(सभ)",
        "group-autoconfirmed-member": "{{GENDER:$1|स्वतः स्थापित प्रयोगकर्ता}}",
        "group-bot-member": "{{GENDER:$1|बोट}}",
        "group-sysop-member": "{{GENDER:$1|प्रबन्धक}}",
+       "group-interface-admin-member": "{{GENDER:$1|इंटरफ़ेस प्रशासक}}",
        "group-bureaucrat-member": "{{GENDER:$1|प्रशासक}}",
        "group-suppress-member": "{{GENDER:$1|नुकाए वाला}}",
        "grouppage-user": "{{ns:project}}:प्रयोगकर्तासभ",
        "grouppage-autoconfirmed": "{{ns:project}}:स्वतःअनुमोदित प्रयोक्ता",
        "grouppage-bot": "{{ns:project}}:स्वचालक",
        "grouppage-sysop": "{{ns:project}}:प्रबन्धक",
+       "grouppage-interface-admin": "{{ns:project}}:इंटरफ़ेस प्रशासक",
        "grouppage-bureaucrat": "{{ns:project}}:अधिकारी",
        "grouppage-suppress": "{{ns:project}}:नुकाबी",
        "right-read": "पन्ना सभ पढ़ू",
        "grant-createaccount": "खाता खोलल जाए",
        "grant-createeditmovepage": "निर्माण, सम्पादन, आ स्थानान्तरण करनाए",
        "grant-delete": "लेख, अवतरण आ लग हटेनाए",
-       "grant-editinterface": "मिडियाविकि नामस्थान आ सदस्य सिएसएस/जेएस सम्पादित करनाए",
+       "grant-editinterface": "मिडियाविकि नामस्थान आ सदस्य सिएसएस/जेएस सम्पादित",
        "grant-editmycssjs": "अपन सदस्य सिएसएस/जेएस सम्पादित करी",
        "grant-editmyoptions": "अपन सदस्य पसन्द सम्पादित करी",
        "grant-editmywatchlist": "अपन साकांक्षसूची सम्पादित करी",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नव पन्नसभक सूची]] सेहो देखी)",
        "recentchanges-submit": "देखाबी",
        "rcfilters-legend-heading": "<strong>सङ्केतक सूची:</strong>",
+       "rcfilters-activefilters-hide": "नुकाबी",
+       "rcfilters-activefilters-show": "देखाबी",
+       "rcfilters-limit-title": "परिणाम देखाबी",
+       "rcfilters-savedqueries-rename": "नाम बदलु",
+       "rcfilters-savedqueries-setdefault": "मूल के रूप मे राखु",
+       "rcfilters-savedqueries-remove": "मेटाबी",
+       "rcfilters-savedqueries-new-name-label": "नाम",
+       "rcfilters-savedqueries-new-name-placeholder": "फ़िल्टर के उद्देश्य बताबु",
+       "rcfilters-savedqueries-apply-label": "फ़िल्टर बनाबु",
+       "rcfilters-savedqueries-cancel-label": "रद्द करु",
+       "rcfilters-clear-all-filters": "फ़िल्टरसभ मिटाबु",
+       "rcfilters-filterlist-title": "चलनीसभ",
+       "rcfilters-highlightmenu-title": "रंग चुनु",
+       "rcfilters-filter-editsbyself-label": "अहाक बदलावसभ",
+       "rcfilters-filter-editsbyself-description": "अहाक अपन योगदान।",
+       "rcfilters-filter-user-experience-level-registered-label": "पंजीकृत:",
+       "rcfilters-filter-user-experience-level-registered-description": "लॉग-इन संपादकसभ।",
+       "rcfilters-filter-user-experience-level-unregistered-label": "अपंजीकृत",
+       "rcfilters-filter-user-experience-level-newcomer-label": "अपरिचित",
+       "rcfilters-filter-user-experience-level-learner-label": "शिक्षार्थिसभ",
+       "rcfilters-filter-user-experience-level-experienced-label": "अनुभवी सदस्यसभ",
+       "rcfilters-filter-bots-label": "स्वचालक",
+       "rcfilters-filter-bots-description": "स्वचालित औजार से करलहा सम्पादनसभ।",
+       "rcfilters-filtergroup-reviewstatus": "पुनरीक्षण स्थिति",
+       "rcfilters-filter-reviewstatus-unpatrolled-label": "अपरीक्षित",
+       "rcfilters-filter-reviewstatus-auto-label": "सवापरिक्षित",
+       "rcfilters-filter-minor-label": "छोट सम्पादन",
+       "rcfilters-filter-watchlist-watched-label": "साकांक्षसूची",
+       "rcfilters-filter-watchlistactivity-seen-label": "परिवर्तन सभ चुनु",
+       "rcfilters-filtergroup-changetype": "बदल क प्रकार:",
+       "rcfilters-filter-pageedits-label": "पन्नाक संपादनसभ",
+       "rcfilters-liveupdates-button": "अखुनका अद्यतन",
        "rcnotefrom": "नीचाँमे '''$2''' सँ भेल परिवर्तन अछि ('''$1''' धरि देखाएल)।",
        "rclistfrom": "$3 $2 सँ शुरू भेल नव परिवर्तन देखी",
        "rcshowhideminor": "$1 अल्प सम्पादन",
index bd96921..a027a8b 100644 (file)
@@ -8,7 +8,8 @@
                        "Numulunj pilgae",
                        "아라",
                        "Macofe",
-                       "Fitoschido"
+                       "Fitoschido",
+                       "Vlad5250"
                ]
        },
        "tog-underline": "Сюлмафкснень алга китькстамс:",
        "right-editprotected": "Петнемс аралаф лопатнень (какскадонь араламада башка)",
        "right-editinterface": "Петнемс тиить лопанц арафнеманзон",
        "right-editusercss": "Петнемс иля тиихнень CSS файлснон",
+       "right-edituserjson": "Петнемс иля тиихнень JSON файлснон",
        "right-edituserjs": "Петнемс иля тиихнень JS файлснон",
        "right-rollback": "Куроконе мумс мекольце тиить конась петнесь лопат",
        "right-markbotedits": "Тяштемс мърдаф петнематнень кода робот петнематне",
index f564730..99db9e5 100644 (file)
        "passwordtooshort": "Лозинката мора да има најмалку {{PLURAL:$1|1 знак|$1 знаци}}.",
        "passwordtoolong": "Лозинката не треба да има повеќе од {{PLURAL:$1|1 знак|$1 знаци}}.",
        "passwordtoopopular": "Не се допуштаат пречесто застапени лозинки. Изберете потешка лозинка за погодување.",
+       "passwordinlargeblacklist": "Внесената лозинка е меѓу најчесто користените. Изберете поинаква.",
        "password-name-match": "Лозинката мора да се разликува од корисничкото име.",
        "password-login-forbidden": "Употребата на ова корисничко име и лозинка е забранета.",
        "mailmypassword": "Нова лозинка",
        "timezonelegend": "Часовен појас:",
        "localtime": "Месно време:",
        "timezoneuseserverdefault": "Од викито ($1)",
-       "timezoneuseoffset": "Друго (посочете отстапување)",
+       "timezoneuseoffset": "Друго (подолу посочете отстапување)",
+       "timezone-useoffset-placeholder": "Примерни вредности: „-07:00“ или „01:00“",
        "servertime": "Време на опслужувачот:",
        "guesstimezone": "Пополни од прелистувачот",
        "timezoneregion-africa": "Африка",
        "prefs-editor": "Уредник",
        "prefs-preview": "Преглед",
        "prefs-advancedrc": "Напредни нагодувања",
-       "prefs-opt-out": "Отпиши ме од подобрувањата",
        "prefs-advancedrendering": "Напредни нагодувања",
        "prefs-advancedsearchoptions": "Напредни нагодувања",
        "prefs-advancedwatchlist": "Напредни нагодувања",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинката не смее да биде од оние на црниот список",
        "passwordpolicies-policy-maximalpasswordlength": "Лозинката не треба да има повеќе од $1 {{PLURAL:$1|знак|знаци}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Лозинката не треба да биде {{PLURAL:$1|најзастапената|од списокот на $1 најзастапени лозинки}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинката не може да биде меѓу 100.000-те најчести лозинки.",
        "easydeflate-invaliddeflate": "Содржината не е соодветно прочистена",
        "unprotected-js": "JavaScript не може да се вчита од незаштитени страници од безбедносни причини. Создавајте JavaScript само во именскиот простор МедијаВики: или како корисничка потстраница"
 }
index 4738e1a..23d2ba7 100644 (file)
        "prefs-editor": "എഡിറ്റർ",
        "prefs-preview": "എങ്ങനെയുണ്ടെന്ന് കാണൽ",
        "prefs-advancedrc": "വിപുലമായ ഉപാധികൾ",
-       "prefs-opt-out": "പുതുക്കലുകൾ ഒഴിവാക്കുക",
        "prefs-advancedrendering": "വിപുലമായ ഉപാധികൾ",
        "prefs-advancedsearchoptions": "വിപുലമായ ഉപാധികൾ",
        "prefs-advancedwatchlist": "വിപുലമായ ഉപാധികൾ",
        "prefs-displayrc": "പ്രദർശന ഐച്ഛികങ്ങൾ",
        "prefs-displaywatchlist": "പ്രദർശന ഐച്ഛികങ്ങൾ",
+       "prefs-changesrc": "പ്രദർശിപ്പിച്ച മാറ്റങ്ങൾ",
+       "prefs-changeswatchlist": "പ്രദർശിപ്പിച്ച മാറ്റങ്ങൾ",
+       "prefs-pageswatchlist": "ശ്രദ്ധിച്ച താളുകൾ",
        "prefs-tokenwatchlist": "ചീട്ട്",
        "prefs-diffs": "വ്യത്യാസങ്ങൾ",
        "prefs-help-prefershttps": "താങ്കൾ അടുത്ത പ്രാവശ്യം പ്രവേശിക്കുമ്പോൾ ഇവ ഫലത്തിൽ വരുന്നതാണ്.",
        "saveusergroups": "{{GENDER:$1|ഉപയോക്തൃസംഘങ്ങൾ}} സേവ് ചെയ്യുക",
        "userrights-groupsmember": "അംഗത്വമുള്ളത്:",
        "userrights-groupsmember-auto": "അന്തർലീനമായ അംഗത്വം:",
-       "userrights-groups-help": "à´\88 à´\89പയàµ\8bà´\95àµ\8dതാവàµ\8d à´\89ൾപàµ\8dà´ªàµ\86à´\9fàµ\8dà´\9fà´¿à´\9fàµ\8dà´\9fàµ\81à´³àµ\8dà´³ à´¸à´\82à´\98à´\99àµ\8dà´\99ൾ à´¤à´¾à´\99àµ\8dà´\95ൾà´\95àµ\8dà´\95àµ\8d à´®à´¾à´±àµ\8dറാവàµ\81à´¨àµ\8dനതാണàµ\8d:\n* à´\89പയàµ\8bà´\95àµ\8dതാവàµ\8d à´\86 à´¸à´\82à´\98à´¤àµ\8dതിലàµ\81à´£àµ\8dà´\9fàµ\86à´¨àµ\8dà´¨àµ\8d à´¶à´°à´¿à´¯à´¿à´\9fàµ\8dà´\9f à´\9aà´¤àµ\81à´°à´\82 à´\85ർതàµ\8dഥമാà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81.\n* à´\89പയàµ\8bà´\95àµ\8dതാവàµ\8d à´\86 à´¸à´\82à´\98à´¤àµ\8dതിലിലàµ\8dà´²àµ\86à´¨àµ\8dà´¨àµ\8d à´¶à´°à´¿à´¯à´¿à´\9fാതàµ\8dà´¤ à´\9aà´¤àµ\81à´°à´\82 à´\85ർതàµ\8dഥമാà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81.\n* à´¸à´\82à´\98à´\99àµ\8dà´\99à´³àµ\8bà´\9fàµ\8aà´ªàµ\8dപമàµ\81à´³àµ\8dà´³ *,  à´\92à´°à´¿à´\95àµ\8dà´\95ൽ à´®à´¾à´±àµ\8dà´±à´\82 à´µà´°àµ\81à´¤àµ\8dതിയാൽ à´ªà´¿à´¨àµ\8dà´¨àµ\80à´\9fàµ\8d à´\85തിൽ à´®à´¾à´±àµ\8dà´±à´\82 à´µà´°àµ\81à´¤àµ\8dതാൻ à´¤à´¾à´\99àµ\8dà´\95ൾà´\95àµ\8dà´\95àµ\8d à´\95ഴിയിലàµ\8dà´²àµ\86à´¨àµ\8dà´¨àµ\8d à´\85ർതàµ\8dഥമാà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81.\n* à´¸à´\82à´\98à´\99àµ\8dà´\99à´³àµ\8bà´\9fàµ\8aà´ªàµ\8dപമàµ\81à´³àµ\8dà´³ #, à´¸à´\82à´\98à´¾à´\82à´\97à´¤àµ\8dവതàµ\8dതിനàµ\8dà´±àµ\86 à´\95ാലാവാധി à´ªà´¿à´¨àµ\8dà´¨àµ\8bà´\9fàµ\8dà´\9fà´¾à´\95àµ\8dà´\95ാമàµ\86à´¨àµ\8dà´¨àµ\8d à´¸àµ\82à´\9aà´¿à´ªàµ\8dപിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨àµ\81; à´¤à´¾à´\99àµ\8dà´\95ൾà´\95àµ\8dà´\95à´¤àµ\8d à´®àµ\81à´¨àµ\8dà´¨àµ\8bà´\9fàµ\8dà´\9fà´¾à´\95àµ\8dà´\95ാൻ à´¸à´¾à´§à´¿à´\95àµ\8dà´\95àµ\81à´\95യിലàµ\8dà´².",
+       "userrights-groups-help": "ഈ ഉപയോക്താവ് ഉൾപ്പെട്ടിട്ടുള്ള സംഘങ്ങൾ താങ്കൾക്ക് മാറ്റാവുന്നതാണ്:\n* ഉപയോക്താവ് ആ സംഘത്തിലുണ്ടെന്ന് ശരിയിട്ട ചതുരം അർത്ഥമാക്കുന്നു.\n* ഉപയോക്താവ് ആ സംഘത്തിലില്ലെന്ന് ശരിയിടാത്ത ചതുരം അർത്ഥമാക്കുന്നു.\n* സംഘങ്ങളോടൊപ്പമുള്ള *,  ഒരിക്കൽ മാറ്റം വരുത്തിയാൽ പിന്നീട് അതിൽ മാറ്റം വരുത്താൻ താങ്കൾക്ക് കഴിയില്ലെന്ന് അർത്ഥമാക്കുന്നു.\n* സംഘങ്ങളോടൊപ്പമുള്ള #, സംഘാംഗത്വത്തിന്റെ കാലാവധി പിന്നോട്ടാക്കാമെന്ന് സൂചിപ്പിക്കുന്നു; താങ്കൾക്കത് മുന്നോട്ടാക്കാൻ സാധിക്കുകയില്ല.",
        "userrights-reason": "കാരണം:",
        "userrights-no-interwiki": "മറ്റ് വിക്കികളിലെ ഉപയോക്തൃ അവകാശങ്ങൾ തിരുത്തുവാൻ താങ്കൾക്ക് അനുമതിയില്ല.",
        "userrights-nodatabase": "$1 എന്ന ഡാറ്റാബേസ് നിലവിലില്ല അല്ലെങ്കിൽ പ്രാദേശികമല്ല.",
        "group-autoconfirmed": "യാന്ത്രികമായി സ്ഥിരീകരിക്കപ്പെട്ട ഉപയോക്താക്കൾ",
        "group-bot": "യന്ത്രങ്ങൾ",
        "group-sysop": "കാര്യനിർവാഹകർ",
+       "group-interface-admin": "സമ്പർക്കമുഖ കാര്യനിർവാഹകർ",
        "group-bureaucrat": "ബ്യൂറോക്രാറ്റുകൾ",
        "group-suppress": "അമർച്ചകർ",
        "group-all": "(എല്ലാം)",
        "group-autoconfirmed-member": "{{GENDER:$1|യാന്ത്രികമായി സ്ഥിരീകരിക്കപ്പെട്ട ഉപയോക്താവ്}}",
        "group-bot-member": "{{GENDER:$1|യന്ത്രം}}",
        "group-sysop-member": "{{GENDER:$1|കാര്യനിർവാഹകൻ|കാര്യനിർവാഹക}}",
+       "group-interface-admin-member": "{{GENDER:$1|സമ്പർക്കമുഖ കാര്യനിർവാഹകൻ|സമ്പർക്കമുഖ കാര്യനിർവാഹക}}",
        "group-bureaucrat-member": "{{GENDER:$1|ബ്യൂറോക്രാറ്റ്}}",
        "group-suppress-member": "{{GENDER:$1|അമർച്ചക|അമർച്ചകൻ}}",
        "grouppage-user": "{{ns:project}}:ഉപയോക്താക്കൾ",
        "grouppage-autoconfirmed": "{{ns:project}}:യാന്ത്രികമായി സ്ഥിരീകരിക്കപ്പെട്ട ഉപയോക്താക്കൾ",
        "grouppage-bot": "{{ns:project}}:യന്ത്രങ്ങൾ",
        "grouppage-sysop": "{{ns:project}}:കാര്യനിർവാഹകർ",
+       "grouppage-interface-admin": "{{ns:project}}:സമ്പർക്കമുഖ കാര്യനിർവാഹകർ",
        "grouppage-bureaucrat": "{{ns:project}}:ബ്യൂറോക്രാറ്റ്",
        "grouppage-suppress": "{{ns:project}}:ഒതുക്കൽ",
        "right-read": "\nതാളുകൾ വായിക്കുക",
        "right-editusercss": "മറ്റ് ഉപയോക്താക്കളുടെ CSS പ്രമാണങ്ങൾ തിരുത്തുക",
        "right-edituserjson": "മറ്റ് ഉപയോക്താക്കളുടെ ജെസൺ പ്രമാണങ്ങൾ തിരുത്തുക",
        "right-edituserjs": "മറ്റ് ഉപയോക്താക്കളുടെ JS പ്രമാണങ്ങൾ തിരുത്തുക",
+       "right-editsitecss": "സൈറ്റ്-വ്യാപക സി.എസ്.എസ്. തിരുത്തുക",
+       "right-editsitejson": "സൈറ്റ്-വ്യാപക ജെസൺ തിരുത്തുക",
+       "right-editsitejs": "സൈറ്റ്-വ്യാപക ജാവാസ്ക്രിപ്റ്റ് തിരുത്തുക",
        "right-editmyusercss": "താങ്കളുടെ സ്വന്തം ഉപയോക്തൃ സി.എസ്.എസ്. പ്രമാണങ്ങൾ തിരുത്തുക",
+       "right-editmyuserjson": "താങ്കളുടെ സ്വന്തം ഉപയോക്തൃ ജെസൺ പ്രമാണങ്ങൾ തിരുത്തുക",
        "right-editmyuserjs": "താങ്കളുടെ സ്വന്തം ഉപയോക്തൃ ജാവാസ്ക്രിപ്റ്റ് പ്രമാണങ്ങൾ തിരുത്തുക",
        "right-viewmywatchlist": "താങ്കളുടെ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക സ്വയം കാണുക",
        "right-editmywatchlist": "താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക സ്വയം തിരുത്തുക. ഈ അവകാശമില്ലാതെതന്നെ ചില പ്രവൃത്തികൾ താളുകൾ കൂട്ടിച്ചേർക്കുമെന്ന് അറിഞ്ഞിരിക്കുക.",
        "right-managechangetags": "[[Special:Tags|ടാഗുകൾ]] സൃഷ്ടിക്കുക അല്ലെങ്കിൽ പ്രവർത്തനരഹിതമാക്കുക",
        "right-applychangetags": "മാറ്റങ്ങളോടൊപ്പം [[Special:Tags|ടാഗുകളും]] ബാധകമാക്കുക",
        "right-changetags": "ഒറ്റയൊറ്റ നാൾപ്പതിപ്പുകൾക്കും രേഖയിലെ ഉൾപ്പെടുത്തലുകൾക്കും ഐച്ഛിക [[Special:Tags|ടാഗുകൾ]] ചേർക്കുക അല്ലെങ്കിൽ നീക്കംചെയ്യുക",
+       "right-deletechangetags": "ഡേറ്റാബേസിൽ നിന്നും [[Special:Tags|റ്റാഗുകൾ]] മായ്ക്കുക",
        "grant-generic": "\"$1\" അവകാശ സഞ്ചയം",
        "grant-group-page-interaction": "താളുകളുമായി സമ്പർക്കം പുലർത്തുക",
        "grant-group-file-interaction": "മീഡിയയുമായി സമ്പർക്കം പുലർത്തുക",
        "grant-createaccount": "അംഗത്വങ്ങൾ സൃഷ്ടിക്കുക",
        "grant-createeditmovepage": "താളുകൾ സൃഷ്ടിക്കുക, തിരുത്തുക, മാറ്റുക",
        "grant-delete": "താളുകൾ, നാൾപ്പതിപ്പുകൾ, രേഖകളിലെ ഉൾപ്പെടുത്തലുകൾ മായ്ക്കുക",
-       "grant-editinterface": "à´®àµ\80ഡിയവിà´\95àµ\8dà´\95à´¿ à´¨à´¾à´®à´®àµ\87à´\96ലയàµ\81à´\82 à´\89പയàµ\8bà´\95àµ\8dà´¤àµ\83 à´¸à´¿.à´\8eà´¸àµ\8d.à´\8eà´¸àµ\8d./à´\9càµ\86സൺ/à´\9cാവാസàµ\8dà´\95àµ\8dà´°à´¿à´ªàµ\8dà´±àµ\8dà´±ും തിരുത്തുക",
+       "grant-editinterface": "à´®àµ\80ഡിയവിà´\95àµ\8dà´\95à´¿ à´¨à´¾à´®à´®àµ\87à´\96ലയàµ\81à´\82 à´¸àµ\88à´±àµ\8dà´±àµ\8d-à´µàµ\8dയാപà´\95/à´\89പയàµ\8bà´\95àµ\8dà´¤àµ\83 à´\9càµ\86സണും തിരുത്തുക",
        "grant-editmycssjs": "താങ്കളുടെ ഉപയോക്തൃ സി.എസ്.എസ്./ജെസൺ/ജാവാസ്ക്രിപ്റ്റ് തിരുത്തുക",
        "grant-editmyoptions": "താങ്കളുടെ ഉപയോക്തൃ ക്രമീകരണങ്ങൾ തിരുത്തുക",
        "grant-editmywatchlist": "താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക തിരുത്തുക",
+       "grant-editsiteconfig": "സൈറ്റ്-വ്യാപകവും ഉപയോക്താക്കളുടെയും സി.എസ്.എസ്./ജെ.എസ്. തിരുത്തുക",
        "grant-editpage": "നിലവിലുള്ള താളുകൾ തിരുത്തുക",
        "grant-editprotected": "സംരക്ഷിച്ചിട്ടുള്ള താളുകൾ തിരുത്തുക",
        "grant-highvolume": "ഉയർന്ന അളവിലുള്ള തിരുത്തുകൾ",
        "grant-oversight": "ഉപയോക്താക്കളെ മറയ്ക്കുക ഒപ്പം നാൾപ്പതിപ്പുകൾ ഒതുക്കുക",
        "grant-patrol": "താളുകളിലെ മാറ്റങ്ങളിൽ റോന്തുചുറ്റുക",
+       "grant-privateinfo": "സ്വകാര്യ വിവരങ്ങൾ എടുക്കാൻ കഴിയുക",
        "grant-protect": "താളുകൾ സംരക്ഷിക്കുക, സംരക്ഷണം നീക്കുക",
        "grant-rollback": "താളുകളിലെ മാറ്റങ്ങൾ മുൻപ്രാപനം ചെയ്യുക",
        "grant-sendemail": "മറ്റുപയോക്താക്കൾക്ക് ഇമെയിൽ അയയ്ക്കുക",
        "grant-basic": "അടിസ്ഥാന അവകാശങ്ങൾ",
        "grant-viewdeleted": "മായ്ക്കപ്പെട്ട പ്രമാണങ്ങളും താളുകളും കാണുക",
        "grant-viewmywatchlist": "താങ്കൾ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക കാണുക",
+       "grant-viewrestrictedlogs": "പരിമിതപ്പെടുത്തിയിട്ടുള്ള രേഖാ ഉൾപ്പെടുത്തലുകൾ കാണുക",
        "newuserlogpage": "ഉപയോക്തൃ സൃഷ്ടിയുടെ രേഖ",
        "newuserlogpagetext": "പുതിയതായി അംഗത്വമെടുത്ത ഉപയോക്താക്കളുടെ പട്ടിക താഴെ കാണാം.",
        "rightslog": "ഉപയോക്തൃ അവകാശ രേഖ",
        "rcfilters-watchlist-markseen-button": "എല്ലാ മാറ്റങ്ങളും കണ്ടതായി അടയാളപ്പെടുത്തുക",
        "rcfilters-watchlist-edit-watchlist-button": "താങ്കൾ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടിക തിരുത്തുക",
        "rcfilters-watchlist-showupdated": "മാറ്റങ്ങൾ ഉണ്ടായ ശേഷം താങ്കൾ സന്ദർശിക്കാത്ത താളുകളിലെ മാറ്റങ്ങൾ, തളിക അടയാളത്തോടൊപ്പം <strong>കടുപ്പിച്ച്</strong> കാണിച്ചിരിക്കുന്നു.",
-       "rcfilters-preference-label": "സമàµ\80à´ªà´\95ാലമാറàµ\8dà´±à´\99àµ\8dà´\99à´³àµ\81à´\9fàµ\86 à´ªàµ\81à´¤àµ\81à´\95àµ\8dà´\95à´¿à´¯ à´ªà´¤à´¿à´ªàµ\8dà´ªàµ\8d à´ªàµ\8dരദർശിപàµ\8dപിà´\95àµ\8dà´\95àµ\87à´£àµ\8dà´\9f",
-       "rcfilters-preference-help": "സമàµ\8dപർà´\95àµ\8dà´\95à´®àµ\81à´\96à´¤àµ\8dതിൽ 2017-ൽ à´µà´°àµ\81à´¤àµ\8dതിയ à´°àµ\82à´ªà´\95à´²àµ\8dപനാമാറàµ\8dà´±à´\99àµ\8dà´\99à´³àµ\81à´\82, à´\85à´¤àµ\8bà´\9fàµ\8aà´ªàµ\8dപവàµ\81à´\82 à´ªà´¿à´¨àµ\8dà´¨àµ\80à´\9fàµ\81à´\82 à´\9aàµ\87ർതàµ\8dà´¤ à´\8eà´²àµ\8dലാ à´\89à´ªà´\95à´°à´£à´\99àµ\8dà´\99à´³àµ\81à´\82 à´\92ഴിവാà´\95àµ\8dà´\95àµ\81à´\95.",
-       "rcfilters-watchlist-preference-label": "à´¶àµ\8dà´°à´¦àµ\8dധിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dനവയàµ\81à´\9fàµ\86 à´ªà´\9fàµ\8dà´\9fà´¿à´\95à´¯àµ\81à´\9fàµ\86 à´ªàµ\81à´¤àµ\81à´\95àµ\8dà´\95à´¿à´¯ à´ªà´¤à´¿à´ªàµ\8dà´ªàµ\8d à´ªàµ\8dരദർശിപàµ\8dപിà´\95àµ\8dà´\95àµ\87à´£àµ\8dà´\9fതിലàµ\8dà´²",
-       "rcfilters-watchlist-preference-help": "2017-ലെ സമ്പർക്കമുഖ പുനർരൂപകല്പനയും അതോടൊപ്പവും പിന്നീടും ചേർത്ത എല്ലാ ഉപകരണങ്ങളും ഒഴിവാക്കുക",
+       "rcfilters-preference-label": "à´\9cാവാസàµ\8dà´\95àµ\8dà´°à´¿à´ªàµ\8dà´±àµ\8dà´±àµ\8d-രഹിത à´¸à´®àµ\8dപർà´\95àµ\8dà´\95à´®àµ\81à´\96à´\82 à´\89പയàµ\8bà´\97à´¿à´\95àµ\8dà´\95àµ\81à´\95",
+       "rcfilters-preference-help": "à´\85à´°à´¿à´ªàµ\8dà´ªà´\95à´³àµ\81à´\82 à´ªàµ\8dà´°à´®àµ\81à´\96മാà´\95àµ\8dà´\95à´¿à´\95àµ\8dà´\95à´¾à´\9fàµ\8dà´\9fൽ à´¸àµ\97à´\95à´°àµ\8dയവàµ\81à´\82 à´\87à´²àµ\8dലാതàµ\86 à´¸à´®àµ\80à´ªà´\95ാലമാറàµ\8dà´±à´\99àµ\8dà´\99ൾ à´\8eà´\9fàµ\81à´\95àµ\8dà´\95àµ\81à´\95",
+       "rcfilters-watchlist-preference-label": "à´\9cാവാസàµ\8dà´\95àµ\8dà´°à´¿à´ªàµ\8dà´±àµ\8dà´±àµ\8d-രഹിത à´¸à´®àµ\8dപർà´\95àµ\8dà´\95à´®àµ\81à´\96à´\82 à´\89പയàµ\8bà´\97à´¿à´\95àµ\8dà´\95àµ\81à´\95",
+       "rcfilters-watchlist-preference-help": "അരിപ്പകളും പ്രമുഖമാക്കിക്കാട്ടൽ സൗകര്യവും ഇല്ലാതെ ശ്രദ്ധിക്കുന്നവയുടെ പട്ടിക എടുക്കുക.",
        "rcfilters-filter-showlinkedfrom-label": "കണ്ണി ചേർക്കപ്പെട്ട താളുകളിലെ മാറ്റങ്ങൾ കാണിക്കുക",
        "rcfilters-filter-showlinkedfrom-option-label": "തിരഞ്ഞെടുത്ത താളിൽ <strong>കണ്ണി ചേർക്കപ്പെട്ട താളുകൾ</strong>",
        "rcfilters-filter-showlinkedto-label": "കണ്ണി ചേർക്കപ്പെട്ട താളുകളിലെ മാറ്റങ്ങൾ കാണിക്കുക",
        "prefixindex": "പൂർവ്വപദത്തോടു കൂടിയ എല്ലാ താളുകളും",
        "prefixindex-namespace": "പൂർവ്വപദമുള്ള എല്ലാ താളുകളും (നാമമേഖല $1)",
        "prefixindex-submit": "പ്രദർശിപ്പിക്കുക",
-       "prefixindex-strip": "à´ªà´\9fàµ\8dà´\9fà´¿à´\95യിൽ à´¨à´¿à´¨àµ\8dà´¨àµ\8d à´ªàµ\82ർവàµ\8dവപദà´\82 à´\92ഴിവാക്കുക",
+       "prefixindex-strip": "à´«à´²à´\99àµ\8dà´\99ളിൽ à´¨à´¿à´¨àµ\8dà´¨àµ\8d à´ªàµ\82ർവàµ\8dവപദà´\82 à´®à´±à´¯àµ\8dക്കുക",
        "shortpages": "വിവരം ഏറ്റവും കുറവുള്ള താളുകൾ",
        "longpages": "വലിയ താളുകളുടെ പട്ടിക",
        "deadendpages": "അന്തർ വിക്കി കണ്ണിയാൽ ബന്ധിപ്പിക്കപ്പെടാത്ത താളുകൾ",
        "speciallogtitlelabel": "ലക്ഷ്യം (തലക്കെട്ട് അല്ലെങ്കിൽ ഉപയോക്താവിനെ തിരയാനുള്ള {{ns:user}}:ഉപയോക്തൃനാമം) :",
        "log": "പ്രവർത്തനരേഖകൾ",
        "logeventslist-submit": "പ്രദർശിപ്പിക്കുക",
+       "logeventslist-patrol-log": "റോന്തുചുറ്റൽ പ്രവർത്തനരേഖ",
+       "logeventslist-tag-log": "റ്റാഗ് രേഖ",
        "all-logs-page": "എല്ലാ പൊതുരേഖകളും",
        "alllogstext": "{{SITENAME}} സംരംഭത്തിൽ ലഭ്യമായ വിവിധ പ്രവർത്തന രേഖകൾ ഈ താളിൽ ഒരുമിച്ച് കാണാം. താങ്കൾക്ക് രേഖകളുടെ സ്വഭാവം, ഉപയോക്തൃനാമം (കേസ് സെൻസിറ്റീവ്), ബന്ധപ്പെട്ട താൾ (കേസ് സെൻസിറ്റീവ്) മുതലായവ തിരഞ്ഞെടുത്ത് അന്വേഷണം കൂടുതൽ ക്ഌപ്തപ്പെടുത്താവുന്നതാണ്.",
        "logempty": "പ്രവർത്തനരേഖയിൽ ബന്ധമുള്ളവ ഇല്ല.",
        "cachedspecial-refresh-now": "ഏറ്റവും പുതിയ പതിപ്പ് കാണുക.",
        "categories": "വർഗ്ഗങ്ങൾ",
        "categories-submit": "പ്രദർശിപ്പിക്കുക",
-       "categoriespagetext": "താഴàµ\86 à´\95àµ\8aà´\9fàµ\81à´¤àµ\8dതിരിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨ {{PLURAL:$1|വർà´\97àµ\8dà´\97à´¤àµ\8dതിൽ|വർà´\97àµ\8dà´\97à´\99àµ\8dà´\99ളിൽ}} à´¤à´¾à´³àµ\81à´\95à´³àµ\81à´\82 à´ªàµ\8dരമാണà´\99àµ\8dà´\99à´³àµ\81à´®àµ\81à´£àµ\8dà´\9fàµ\8d.\n[[Special:UnusedCategories|à´\89പയàµ\8bà´\97à´¿à´\95àµ\8dà´\95à´ªàµ\8dà´ªàµ\86à´\9fാതàµ\8dà´¤ à´µàµ¼à´\97àµ\8dà´\97à´\99àµ\8dà´\99ൾ]] à´\87വിà´\9fàµ\86 à´\95ാണിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dനിലàµ\8dà´².\n[[Special:WantedCategories|അവശ്യവർഗ്ഗങ്ങൾ]] കൂടി കാണുക.",
+       "categoriespagetext": "താഴàµ\86 à´\95àµ\8aà´\9fàµ\81à´¤àµ\8dതിരിà´\95àµ\8dà´\95àµ\81à´¨àµ\8dà´¨ {{PLURAL:$1|വർà´\97àµ\8dà´\97à´\82|വർà´\97àµ\8dà´\97à´\99àµ\8dà´\99ൾ}} à´µà´¿à´\95àµ\8dà´\95ിയിലàµ\81à´£àµ\8dà´\9fàµ\86à´\99àµ\8dà´\95à´¿à´²àµ\81à´\82, à´\89പയàµ\8bà´\97à´¿à´\95àµ\8dà´\95à´ªàµ\8dà´ªàµ\86à´\9fാനàµ\8b à´\89പയàµ\8bà´\97à´¿à´\95àµ\8dà´\95à´ªàµ\8dà´ªàµ\86à´\9fാതിരിà´\95àµ\8dà´\95ാനàµ\8b à´¸à´¾à´¦àµ\8dà´§àµ\8dയതയàµ\81à´£àµ\8dà´\9fàµ\8d.\n[[Special:WantedCategories|അവശ്യവർഗ്ഗങ്ങൾ]] കൂടി കാണുക.",
        "categoriesfrom": "ഇങ്ങനെ തുടങ്ങുന്ന വർഗ്ഗങ്ങൾ കാട്ടുക:",
        "deletedcontributions": "മായ്ക്കപ്പെട്ട ഉപയോക്തൃസംഭാവനകൾ",
        "deletedcontributions-title": "മായ്ക്കപ്പെട്ട ഉപയോക്തൃസംഭാവനകൾ",
        "ipb-disableusertalk": "തടയപ്പെട്ടിരിക്കുമ്പോൾ സ്വന്തം സംവാദം താൾ തിരുത്തുന്നതിൽ നിന്നും ഈ ഉപയോക്താവിനെ തടയുക",
        "ipb-change-block": "ഈ ക്രമീകരണപ്രകാരം ഉപയോക്താവിനെ വീണ്ടും തടയുക",
        "ipb-confirm": "തടയൽ സ്ഥിരീകരിക്കുക",
+       "ipb-sitewide": "സൈറ്റ്-വ്യാപകം",
+       "ipb-partial": "ഭാഗികം",
+       "ipb-type-label": "തരം",
+       "ipb-pages-label": "താളുകൾ",
        "badipaddress": "അസാധുവായ ഐ.പി. വിലാസം.",
        "blockipsuccesssub": "തടയൽ വിജയിച്ചിരിക്കുന്നു",
        "blockipsuccesstext": "[[Special:Contributions/$1|$1]] എന്ന ഉപയോക്താവിനെ തടഞ്ഞിരിക്കുന്നു.<br />\nതടയൽ പുനഃപരിശോധിക്കാൻ [[Special:BlockList|തടയൽ പട്ടിക]] കാണുക.",
        "createaccountblock": "അംഗത്വം സൃഷ്ടിക്കുന്നതിൽനിന്ന് തടഞ്ഞിരിക്കുന്നു",
        "emailblock": "ഇമെയിൽ ഉപയോഗിക്കുന്നതു തടഞ്ഞിരിക്കുന്നു",
        "blocklist-nousertalk": "സ്വന്തം സം‌വാദ താളിൽ തിരുത്താൻ സാധിക്കില്ല",
+       "blocklist-editing": "തിരുത്ത്",
+       "blocklist-editing-sitewide": "തിരുത്ത് (സൈറ്റ്-വ്യാപകം)",
        "ipblocklist-empty": "തടയൽപ്പട്ടിക ശൂന്യമാണ്‌.",
        "ipblocklist-no-results": "ഈ ഐ.പി. വിലാസമോ ഉപയോക്തൃനാമമോ തടഞ്ഞിട്ടില്ല.",
        "blocklink": "തടയുക",
        "move-watch": "ഈ താളിലെ മാറ്റങ്ങൾ ശ്രദ്ധിക്കുക",
        "movepagebtn": "താൾ മാറ്റുക",
        "pagemovedsub": "തലക്കെട്ടു മാറ്റം വിജയിച്ചിരിക്കുന്നു",
+       "cannotmove": "ഇനി പറയുന്ന {{PLURAL:$1|കാരണത്താൽ|കാരണങ്ങളാൽ}} താൾ മാറ്റാൻ കഴിയില്ല:",
        "movepage-moved": "'''\"$1\" എന്ന ലേഖനം \"$2\" എന്ന തലക്കെട്ടിലേക്ക് മാറ്റിയിരിക്കുന്നു'''",
        "movepage-moved-redirect": "ഒരു തിരിച്ചുവിടൽ സൃഷ്ടിച്ചിരിക്കുന്നു.",
        "movepage-moved-noredirect": "തിരിച്ചുവിടലിന്റെ സൃഷ്ടി ഒതുക്കിയിരിക്കുന്നു.",
        "pageinfo-category-files": "പ്രമാണങ്ങളുടെ എണ്ണം",
        "pageinfo-user-id": "ഉപയോക്തൃ ഐ.ഡി.",
        "pageinfo-file-hash": "ഹാഷ് വില",
+       "pageinfo-view-protect-log": "ഈ താളിന്റെ സംരക്ഷണ രേഖ കാണുക.",
        "markaspatrolleddiff": "റോന്തുചുറ്റിയതായി അടയാളപ്പെടുത്തുക",
        "markaspatrolledtext": "ഈ താളിൽ റോന്തുചുറ്റിയതായി രേഖപ്പെടുത്തുക",
        "markaspatrolledtext-file": "പ്രമാണത്തിന്റെ ഈ പതിപ്പിൽ റോന്തുചുറ്റിയതായി അടയാളപ്പെടുത്തുക",
        "previousdiff": "← മുൻപത്തെ വ്യത്യാസം",
        "nextdiff": "അടുത്ത വ്യത്യാസം →",
        "mediawarning": "'''മുന്നറിയിപ്പ്''': ഈ തരത്തിലുള്ള പ്രമാണത്തിൽ വിനാശകാരിയായ കോഡ് ഉണ്ടായേക്കാം. ഇതു തുറക്കുന്നതു താങ്കളുടെ കമ്പ്യൂട്ടറിനു അപകടമായി തീർന്നേക്കാം.",
-       "imagemaxsize": "à´\9aà´¿à´¤àµ\8dà´°à´¤àµ\8dതിനàµ\8dà´±àµ\86 à´µà´²à´¿à´ªàµ\8dà´ªà´\82:<br />''(à´ªàµ\8dരമാണതàµ\8dതിനàµ\8dà´±àµ\86 à´µà´¿à´µà´°à´£ à´¤à´¾à´³àµ\81à´\95ളിൽ)''",
+       "imagemaxsize": "à´ªàµ\8dരമാണതàµ\8dതിനàµ\8dà´±àµ\86 à´µà´¿à´µà´°à´£ à´¤à´¾à´³àµ\81à´\95ളിൽ à´\9aà´¿à´¤àµ\8dà´°à´¤àµ\8dതിനàµ\8dà´±àµ\86 à´µà´²à´¿à´ªàµ\8dà´ªà´\82:",
        "thumbsize": "ലഘുചിത്രത്തിന്റെ വലിപ്പം:",
        "widthheightpage": "$1 × $2, $3 {{PLURAL:$3|താൾ|താളുകൾ}}",
        "file-info": "പ്രമാണത്തിന്റെ വലിപ്പം: $1, മൈം തരം: $2",
        "confirm-unwatch-top": "ഈ താൾ ഞാൻ ശ്രദ്ധിക്കുന്ന താളുകളുടെ പട്ടികയിൽനിന്നും നീക്കട്ടെ?",
        "confirm-rollback-button": "ശരി",
        "confirm-rollback-top": "ഈ താളിലെ തിരുത്തുകൾ തിരിച്ചാക്കണോ?",
+       "confirm-mcrrestore-title": "ഒരു നാൾപ്പതിപ്പ് പുനഃസ്ഥാപിക്കുക",
+       "confirm-mcrundo-title": "ഒരു മാറ്റം തിരസ്കരിക്കുക",
+       "mcrundofailed": "തിരസ്കരണം പരാജയപ്പെട്ടു",
+       "mcrundo-missingparam": "അഭ്യർത്ഥനയ്ക്ക് ആവശ്യമുള്ള ചരങ്ങൾ നൽകിയിട്ടില്ല.",
        "quotation-marks": "\"$1\"",
        "imgmultipageprev": "← മുൻപത്തെ താൾ",
        "imgmultipagenext": "അടുത്ത താൾ →",
        "special-characters-title-emdash": "എം ഡാഷ്",
        "special-characters-title-minus": "വ്യവകലന ചിഹ്നം",
        "mw-widgets-abandonedit": "സേവ് ചെയ്യാതെ തന്നെ തിരുത്തുന്നതിൽ നിന്ന് പോകണം എന്ന് താങ്കൾക്കുറപ്പാണോ?",
-       "mw-widgets-abandonedit-discard": "തിരàµ\81à´¤àµ\8dà´¤àµ\81à´\95ൾ à´\85à´µà´\97à´£ിക്കുക",
+       "mw-widgets-abandonedit-discard": "തിരàµ\81à´¤àµ\8dà´¤àµ\81à´\95ൾ à´¨à´¿à´°à´¾à´\95à´°ിക്കുക",
        "mw-widgets-abandonedit-keep": "തിരുത്ത് തുടരുക",
        "mw-widgets-abandonedit-title": "താങ്കൾക്ക് ഉറപ്പാണോ?",
        "mw-widgets-dateinput-no-date": "തീയതി ഒന്നും തിരഞ്ഞെടുത്തിട്ടില്ല",
        "mw-widgets-titleinput-description-redirect": "$1 എന്ന താളിലേക്കുള്ള തിരിച്ചുവിടൽ",
        "mw-widgets-categoryselector-add-category-placeholder": "വർഗ്ഗം ചേർക്കുക...",
        "mw-widgets-usersmultiselect-placeholder": "കൂടുതൽ ചേർക്കുക...",
+       "mw-widgets-titlesmultiselect-placeholder": "കൂടുതൽ ചേർക്കുക...",
        "date-range-from": "ഈ തീയതി മുതൽ:",
        "date-range-to": "ഈ തീയതി വരെ:",
        "sessionmanager-tie": "വ്യത്യസ്ത തരത്തിലുള്ള അനുമതി നൽകൽ തരങ്ങൾ സംയോജിപ്പിക്കാനാവില്ല: $1.",
index 55eaaec..5244710 100644 (file)
        "prefs-advancedwatchlist": "အဆင့်မြင့် ရွေးချယ်မှု",
        "prefs-displayrc": "ပြသရန် ရွေးချယ်မှု",
        "prefs-displaywatchlist": "ပြသရန် ရွေးချယ်မှု",
+       "prefs-changesrc": "ပြောင်းလဲမှုများ ပြသပြီး",
+       "prefs-changeswatchlist": "ပြောင်းလဲမှုများ ပြသပြီး",
+       "prefs-pageswatchlist": "စောင့်ကြည့် စာမျက်နှာများ",
        "prefs-tokenwatchlist": "တိုကင်",
        "prefs-diffs": "ကွဲပြားချက်",
        "prefs-help-prefershttps": "ဤအပြင်အဆင်များသည် နောက်တခါအကောင့်ထဲဝင်ပါက သက်ရောက်မှုရှိလာပါလိမ့်မည်။",
index 35d8d01..e1c7db0 100644 (file)
        "watchlistedit-normal-done": "Í-keng uì lí ê kám-sī-toaⁿ soá {{PLURAL:$1|ia̍h}} cháu:",
        "watchlisttools-edit": "Khoàⁿ koh kái kàm-sī-toaⁿ",
        "watchlisttools-raw": "Kái chhiⁿ ê kàm-sī-toaⁿ",
+       "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|thó-lūn]])",
        "duplicate-defaultsort": "'''Thê-chhíⁿ lí:'''Siat-piān ê pâi-lia̍t hong-sek \"$2\" thè-oāⁿ chìn-chêng ê siat-piān ê pâi-lia̍t hong-sek \"$1\".",
        "version": "Pán-pún",
        "specialpages": "Te̍k-sû-ia̍h",
index efd9af2..3c05a60 100644 (file)
        "prefs-editor": "Editore",
        "prefs-preview": "Anteprimma",
        "prefs-advancedrc": "Opziune avanzate",
-       "prefs-opt-out": "Stuta miglioramente",
        "prefs-advancedrendering": "Opziune avanzate",
        "prefs-advancedsearchoptions": "Opziune avanzate",
        "prefs-advancedwatchlist": "Opziune avanzate",
        "rcfilters-filter-watchlist-notwatched-label": "Nun sta ncopp'ê ppaggene cuntrullate",
        "rcfilters-filtergroup-lastRevision": "Ùrdeme verziune",
        "rcfilters-filter-lastrevision-label": "Verzione 'e mmo",
+       "rcfilters-watchlist-markseen-button": "Segna tutt'ê cagni comme visti",
        "rcfilters-watchlist-edit-watchlist-button": "Càgna 'e lista tuia d'ê paggene cuntrullate",
+       "rcfilters-watchlist-showupdated": "'E càgne 'e ppaggene ca nun hê visto songo signati 'n <strong>niro</strong> e c'ê ppalluccelle chiene.",
+       "rcfilters-target-page-placeholder": "Scrivi 'o nomme 'e na paggene (o na categuria)",
        "rcnotefrom": "Ccà abbascio {{PLURAL:$5|è alencato 'o cagnamiento appurtato|song' alincate 'e cagnamiente appurtate}} 'a <strong>$3, $4</strong> (mmustate nfin'a <strong>$1</strong>).",
        "rclistfrom": "Faje vedé 'e cagnamiénte fatte a partì 'a $3 $2",
        "rcshowhideminor": "$1 'e cagnamiénte piccerille",
        "uploadstash-refresh": "Agghiuorna l'elenco d' 'e file",
        "uploadstash-thumbnail": "vide miniatura",
        "uploadstash-exception": "Nun s'è pututo sarvà 'a càrreca dint' 'a stash ($1): \"$2\".",
+       "uploadstash-bad-path-unknown-type": "Tipo \"$1\" scanosciuto",
+       "uploadstash-bad-path-bad-format": "'A chiave \"$1\" nun sta scritta bona.",
+       "uploadstash-file-not-found": "N'aggio truvato 'a chiave \"$1\".",
+       "uploadstash-file-not-found-no-thumb": "Nun pozzo fà 'a fiùrella.",
+       "uploadstash-file-not-found-no-remote-thumb": "N'aggio truvato 'a figurella: $1 URL = $2",
        "invalid-chunk-offset": "Distanza d' 'a parte nun valida",
        "img-auth-accessdenied": "Acciesso negato",
        "img-auth-nopathinfo": "PATH_INFO mancante.\n'O server nun è mpustato pe' passà sta nfurmazione.\nPuò darse ca, essenno basato ncopp'a CGI, nun putesse suppurtà img_auth.\nVide https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:Image_Authorization",
        "http-timed-out": "Richieste HTTP fore tiempo.",
        "http-curl-error": "Errore analizzanno l'URL: $1",
        "http-bad-status": "C'è stato nu probblema pe' tramente ca se faceva 'a richiesta HTTP: $1, $2",
+       "http-internal-error": "Errore interno HTTP.",
        "upload-curl-error6": "Nun se riesce 'arrevà a l'URL",
        "upload-curl-error6-text": "A l'URL c'avete scritto nun se può arrevà.\nPe' piacere, cuntrullate ca l'URL è curretta e ca 'o sito è appicciato.",
        "upload-curl-error28": "Fore tiempo p' 'a carreca",
        "listfiles_size": "Dimenzione",
        "listfiles_description": "Descrizzione",
        "listfiles_count": "Verziune",
-       "listfiles-show-all": "Nclude 'e verziune viecchie 'e ll'immaggene",
+       "listfiles-show-all": "Nclude 'e verziune viecchie 'e ffiùre",
        "listfiles-latestversion": "Verzione 'e mo",
        "listfiles-latestversion-yes": "Sì",
        "listfiles-latestversion-no": "No",
        "apisandbox-dynamic-error-exists": "Nu parametro denommenato \"$1\" esiste già.",
        "apisandbox-deprecated-parameters": "Parametri obsoleti",
        "apisandbox-fetch-token": "Auto-ghienche 'o token",
+       "apisandbox-add-multi": "Azzecca",
        "apisandbox-submit-invalid-fields-title": "Cocche campo nun è buono",
        "apisandbox-submit-invalid-fields-message": "Pe' piacere curriggite 'e campe nzegnàte e tentate n'ata vota.",
        "apisandbox-results": "Rezurtate",
        "apisandbox-loading-results": "Ricezione d' 'e risultate 'e ll'API 'ncurzo...",
        "apisandbox-results-error": "N'errore cumparette pe' tramente ca se steva carrecanno na risposta 'e query API: $1.",
        "apisandbox-request-url-label": "URL addimannata:",
+       "apisandbox-request-json-label": "Spiata JSON:",
        "apisandbox-request-time": "Tiempo addimannato: {{PLURAL:$1|$1 ms}}",
        "apisandbox-results-fixtoken": "Curregge 'e token e manna n'ata vota",
        "apisandbox-results-fixtoken-fail": "Scassaje a se piglià 'o token \"$1\".",
        "apisandbox-alert-field": "'O valore int'a stu campo nun è valido.",
        "apisandbox-continue": "Annanze",
        "apisandbox-continue-clear": "Pulezza",
+       "apisandbox-continue-help": "{{int:apisandbox-continue}} [https://www.mediawiki.org/wiki/API:Query#Continuing_queries continuarrà] l'urtima spiata; {{int:apisandbox-continue-clear}} pulezzarrà 'e parametri pe 'i annanzi.",
+       "apisandbox-param-limit": "Scrivi <kbd>max</kbd> p'ausà 'o limmete massimo.",
        "apisandbox-multivalue-all-namespaces": "$1 (Tutt'ê namespace)",
        "apisandbox-multivalue-all-values": "$1 (Tutt'ê valuri)",
        "booksources": "Funte libbrarie",
        "booksources-search": "Ascìa",
        "booksources-text": "Ccà abbascio ce sta na lista 'e cullegamiente a l'ati site ca venneno libbre nuove e viecchie, ca putessero pure avé cchiù nfurmaziune ncopp' 'e libbre ca jate ascianno:",
        "booksources-invalid-isbn": "L'ISBN c'avete miso nun pare bbuono; cuntrolla si ce sta cocch'errore quanno stavate cupianno stu nummero d' 'a fonte origginale.",
+       "magiclink-tracking-rfc": "Paggene c'ausano jonte RFC affattorate",
+       "magiclink-tracking-rfc-desc": "Sta paggena ausa jonte RFC affattorate. Vire [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] p' 'a migrazione.",
+       "magiclink-tracking-pmid": "Paggene c'ausano jonte RMID affattorate",
+       "magiclink-tracking-pmid-desc": "Sta paggena ausa jonte PMID affattorate. Vire [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] p' 'a migrazione.",
+       "magiclink-tracking-isbn": "Paggene c'ausano jonte ISBN affattorate",
+       "magiclink-tracking-isbn-desc": "Sta paggena ausa jonte ISBN affattorate. Vire [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Magic_links mediawiki.org] p' 'a migrazione.",
        "specialloguserlabel": "Mplementatore:",
        "speciallogtitlelabel": "Destinazione (titolo o {{ns:user}}:cunto utente pe' ll'utente):",
        "log": "Logs",
        "cachedspecial-refresh-now": "Vide l'urdeme.",
        "categories": "Categurìe",
        "categories-submit": "Faje vedé",
-       "categoriespagetext": "{{PLURAL:$1|'A categurìa 'nnecata 'e seguito cuntiene|'E categurìe 'nnecate 'e seguito cuntengono}} paggene o file multimediale.\n'E [[Special:UnusedCategories|categurìe vuote]] nun song mostrate ccà.\nVere anche 'e [[Special:WantedCategories|categurìe richieste]].",
+       "categoriespagetext": "{{PLURAL:$1|'A categurìa 'nnecata 'e seguito esiste|'E categurìe 'nnecate 'e seguito esistono}} ncopp'a sta wiki, ca s'ausano o no.\nVire purzì 'e [[Special:WantedCategories|categurìe richieste]].",
        "categoriesfrom": "Fà vedè 'e categurìe partenno 'a:",
        "deletedcontributions": "Contribbute utente scancellate",
        "deletedcontributions-title": "Contribbute utente scancellate",
        "activeusers-intro": "Chest'è n'elenco d'utente c'hanno fatto cierti tipe d'attività nfin'a $1 {{PLURAL:$1|juorno|ghiuorne}} fa.",
        "activeusers-count": "$1 {{PLURAL:$1|cagnamiento|cagnamiente}} int'a l'urdeme {{PLURAL:$3|ghiuorne}}",
        "activeusers-from": "Fà vedè l'utente partenno 'a:",
+       "activeusers-groups": "Fa verè l'utenti ca stanno int'ê gruppi:",
+       "activeusers-excludegroups": "Nun fa verè ll'utenti che stanno int'ê gruppi:",
        "activeusers-noresult": "Nisciun'utente truvato.",
        "activeusers-submit": "Mmusta cunte attive",
        "listgrouprights": "Deritte d' 'e gruppe utente",
        "emailccsubject": "Copia d' 'a mmasciata tua 'a $1: $2",
        "emailsent": "Mmasciata e-mail mannata",
        "emailsenttext": "'A mmasciata d' 'a toja s'è mannata.",
-       "emailuserfooter": "Chista mmasciata e-mail è stata {{GENDER:$1|mannata}} 'a $1 a {{GENDER:$2|$2}} p' 'a funziona \"{{int:emailuser}}\" 'e {{SITENAME}}.",
+       "emailuserfooter": "Chista mmasciata e-mail venette {{GENDER:$1|mannata}} 'a $1 a {{GENDER:$2|$2}} p' 'a funziona \"{{int:emailuser}}\" 'e {{SITENAME}}. Si {{GENDER:$2|ttu}} risponni a st'e-mail, l'e-mail {{GENDER:$2|toia}} sarrà mannata a {{GENDER:$1|chi t'ha scritto}}, mustranno 'o 'ndirizzo 'e posta {{GENDER:$2|tuoio}} a {{GENDER:$1|}}.",
        "usermessage-summary": "Lassanno na mmasciata 'e sistema.",
        "usermessage-editor": "Mmasciatore d' 'o sistema",
        "watchlist": "Paggene cuntrullate",
        "enotif_body_intro_moved": "'A paggena $1 'e {{SITENAME}} è stata cagnata 'e posto ncopp'a $PAGEEDITDATE 'a {{gender:$2|$2}}, vedite $3 p' 'a verzione 'e mo.",
        "enotif_body_intro_restored": "'A paggena $1 'e {{SITENAME}} è stata arripigliata ncopp'a $PAGEEDITDATE 'a {{gender:$2|$2}}, vedite $3 p' 'a verzione 'e mo.",
        "enotif_body_intro_changed": "'A paggena $1 'e {{SITENAME}} è stata cagnata ncopp'a $PAGEEDITDATE 'a {{gender:$2|$2}}, vedite $3 p' 'a verzione 'e mo.",
-       "enotif_lastvisited": "Vedite $1 pe' tutt' 'e cagnamiente 'a ll'urdema visita vuosta.",
-       "enotif_lastdiff": "Vedite $1 pe' vedè stu cagnamiento.",
+       "enotif_lastvisited": "Vedite $1 pe' tutt' 'e cagnamiente 'a ll'urdema visita vuosta",
+       "enotif_lastdiff": "Pe vedè stu cagnamiento, vire $1.",
        "enotif_anon_editor": "Utente anonimo $1",
        "enotif_body": "Caro $WATCHINGUSERNAME,\n\n$PAGEINTRO $NEWPAGE\n\nRiepilego 'e cagnamiente: $PAGESUMMARY $PAGEMINOREDIT\n\nCuntattate l'autore:\ne-mail: $PAGEEDITOR_EMAIL\nncopp' 'o sito: $PAGEEDITOR_WIKI\n\nNun se mannarranno ati notifiche si facite cocch'at'attività senza venì a sta paggena.\nPutite pure cagnà 'e mpustaziune 'e notifeca pe' tutt' 'e paggene cuntrullate dint' 'a l'elenco.\n\nStatteve Bbuon, 'o sistema 'e notifiche ncopp' 'a {{SITENAME}} vuosto\n\n--\nPe' cagnà 'e mpustaziune d' 'e notifiche 'e mmasciate elettroniche, jate ccà: {{canonicalurl:{{#special:Preferences}}}}\n\nPe' cagnà 'e mpustaziune 'e l'elenco 'e paggene cuntrullate vuoste jate ccà: {{canonicalurl:{{#special:EditWatchlist}}}}\n\nPe' scancellà l'elenco 'e paggene cuntrullate vedite $UNWATCHURL\n\nSegnalaziune e at'assistenze:\n$HELPPAGE",
        "enotif_minoredit": "Chisto è nu cagnamiénto piccerillo",
        "modifiedarticleprotection": "'o livello 'e prutezione è stato cagnato pe' \"[[$1]]\"",
        "unprotectedarticle": "sprutetto 'a \"[[$1]]\"",
        "movedarticleprotection": "'mpustaziune 'e protezzione spustate 'a \"[[$2]]\" a \"[[$1]]\"",
+       "protectedarticle-comment": "{{GENDER:$2|Pruteggette}} \"[[$1]]\"",
+       "modifiedarticleprotection-comment": "{{GENDER:$2|Cagnaje 'a prutezione}} pe \"[[$1]]\"",
+       "unprotectedarticle-comment": "{{GENDER:$2|Levaie 'a protezione}} 'a \"[[$1]]\"",
        "protect-title": "Cagna 'o livello 'e prutezione pe' \"[[$1]]\"",
        "protect-title-notallowed": "Fà vedé 'o livello 'e prutezione pe' \"$1\"",
        "prot_1movedto2": "ha spustato [[$1]] a [[$2]]",
        "uctop": "attuale",
        "month": "D' 'o mese (e pure cchiù primma):",
        "year": "'E ll'anno (e primma):",
+       "date": "'A data (e tanno)",
        "sp-contributions-newbies": "Mosta solo 'e contribbute dde nove utente",
        "sp-contributions-newbies-sub": "Pe' l'utente nuove",
        "sp-contributions-newbies-title": "Contribbute 'a l'utente nuove",
        "sp-contributions-blocklog": "blocche",
        "sp-contributions-suppresslog": "contribbute utente scancellate",
-       "sp-contributions-deleted": "contribbute d'utente scancellate",
+       "sp-contributions-deleted": "contribbute 'e l'{{GENDER:$1|utente}} scancellate",
        "sp-contributions-uploads": "carreche",
        "sp-contributions-logs": "riggistre",
        "sp-contributions-talk": "Chiàcchiera",
index 82efe94..f67a07c 100644 (file)
        "passwordtooshort": "Passord må ha minst {{PLURAL:$1|ett tegn|$1 tegn}}.",
        "passwordtoolong": "Passord kan ikke overskride {{PLURAL:$1|1 character|$1 characters}}.",
        "passwordtoopopular": "Hyppig brukte passord kan ikke brukes. Vennligst bruk et mer unikt passord.",
+       "passwordinlargeblacklist": "Passordet du skrev inn er på en liste over veldig vanlige passord. Velg et mer unikt passord.",
        "password-name-match": "Passord og brukernavn kan ikke være det samme.",
        "password-login-forbidden": "Bruken av dette brukernavnet og passordet er forbudt.",
        "mailmypassword": "Tilbakestill passord",
        "timezonelegend": "Tidssone:",
        "localtime": "Lokaltid:",
        "timezoneuseserverdefault": "Bruk wikistandard ($1)",
-       "timezoneuseoffset": "Annet (spesifiser forskjell)",
+       "timezoneuseoffset": "Annet (spesifiser forskjellen nedenfor)",
+       "timezone-useoffset-placeholder": "Eksempler: «-07:00» eller «01:00»",
        "servertime": "Serverens tid er nå:",
        "guesstimezone": "Hent tidssone fra nettleseren",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Tekstbehandling",
        "prefs-preview": "Forhåndsvisning",
        "prefs-advancedrc": "Avanserte alternativ",
-       "prefs-opt-out": "Velg å ikke få forbedret utgave",
        "prefs-advancedrendering": "Avanserte alternativer",
        "prefs-advancedsearchoptions": "Avanserte alternativer",
        "prefs-advancedwatchlist": "Avanserte alternativer",
        "rcfilters-watchlist-markseen-button": "Merk alle endringer som sett.",
        "rcfilters-watchlist-edit-watchlist-button": "Rediger listen over sider du overvåker",
        "rcfilters-watchlist-showupdated": "Endringer til sider du ikke har besøkt siden endringene ble gjort vises med <strong>fet</strong> skrift.",
-       "rcfilters-preference-label": "Skjul den forbedrede versjonen av siste endringer",
-       "rcfilters-preference-help": "Fjerner grensesnittendringen fra 2017 og alle verktøyene som ble lagt fra og med da.",
-       "rcfilters-watchlist-preference-label": "Skjul den forbedrede versjonen av overvåkningslisten",
-       "rcfilters-watchlist-preference-help": "Ruller tilbake det omarbeidede grensesnittet fra 2017 og alle verktøy som ble lagt til da og etterpå.",
+       "rcfilters-preference-label": "Bruk grensesnitt uten JavaScript",
+       "rcfilters-preference-help": "Laster siste endringer uten filtre eller markeringsfunksjonalitet.",
+       "rcfilters-watchlist-preference-label": "Bruk grensesnitt uten JavaScript",
+       "rcfilters-watchlist-preference-help": "Laster overvåkningslisten uten filtre eller markeringsfunksjonalitet.",
        "rcfilters-filter-showlinkedfrom-label": "Vis endringer på sider som lenkes fra",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sider som lenkes fra</strong> den valgte siden",
        "rcfilters-filter-showlinkedto-label": "Vis endringer på sider som lenker til",
        "logentry-block-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingen av {{GENDER:$4|$3}} med en utløpstid på $5 $6",
        "logentry-partialblock-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} fra å redigere {{PLURAL:$8|siden|sidene}} $7 med en utløpstid på $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingene for {{GENDER:$4|$3}} og forhindret redigeringen av {{PLURAL:$8|siden|sidene}} $7 med en utløpstid på $5 $6",
-       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} fra handlinger som ikke er redigering med en utløpstid på $5 $6",
-       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingene for {{GENDER:$4|$3}} for handlinger som ikke er redigering med en utløpstid på $5 $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} fra visse handlinger som ikke er redigering med en utløpstid på $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingene for {{GENDER:$4|$3}} for visse handlinger som ikke er redigering med en utløpstid på $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} med en utløpstid på $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|endret}} blokkeringsinnstillingen for {{GENDER:$4|$3}} med en utløpstid på $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importert}} $3 gjennom filopplastning",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Passordet kan ikke matche spesifikt svartelistede passord",
        "passwordpolicies-policy-maximalpasswordlength": "Passordet kan maksimalt være på $1 {{PLURAL:$1|tegn}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Passordet kan ikke være {{PLURAL:$1|det populære passordet|i lista over $1 populære passord}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Passord kan ikke være i listen over de vanligste 100&nbsp;000 passordene.",
        "easydeflate-invaliddeflate": "Det gitte innholdet er ikke riktig komprimert",
        "unprotected-js": "Av sikkerhetsårsaker kan ikke JavaScript lastes fra ubeskyttede sider. Bare skap JavaScript i MediaWiki-navnerommet eller som en brukerunderside"
 }
index f7d7dbf..c356a49 100644 (file)
        "badarticleerror": "यो कार्य यस पृष्ठमा गर्न मिल्दैन।",
        "cannotdelete": "\"$1\" पृष्ठ वा फ़ाइल मेट्नसकिएन।\nयो अघिबाट नैं मेटिएको हुनुपर्छ।",
        "cannotdelete-title": "पृष्ठ  \"$1\" लाई मेट्न सकिएन",
-       "delete-scheduled": "$1 à¤ªà¥\83षà¥\8dठ à¤®à¥\87à¤\9fाà¤\89नà¤\95à¥\8b à¤²à¤¾à¤\97à¥\80 निर्धारित गरिएकाे छ।\nकृपया धैर्य हुनुहोस्।",
+       "delete-scheduled": "$1 à¤ªà¥\83षà¥\8dठ à¤®à¥\87à¤\9fाà¤\89नà¤\95à¥\8b à¤²à¤¾à¤\97ि निर्धारित गरिएकाे छ।\nकृपया धैर्य हुनुहोस्।",
        "delete-hook-aborted": "हुकले सम्पादनकार्य बन्द गरिदियो ।\nकुनै कारण दिइएन ।",
        "no-null-revision": "$1 पृष्ठको लागि खालि पुनरावलोकन सिर्जना गर्न सकिएन",
        "badtitle": "गलत शीर्षक",
        "cascadeprotected": "यो पृष्ठ सम्पादन गर्नबाट सुरक्षित गरिएकोछ किनभनें {{PLURAL:$1|पृष्ठ |पृष्ठहरू}}मा सुरक्षित गर्नुका साथै प्रपात (\"cascading\") विकल्प खुल्ला राखिएको छ:\n$2",
        "namespaceprotected": " '''$1'''  नेमस्पेसमा रहेका पृष्ठहरू सम्पादन गर्ने अनुमति यहाँलाई छैन ।",
        "customcssprotected": "तपाईंलाई यो  पृष्ठ सम्पादन गर्ने अनुमति छैन, किनकी यसमा कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
+       "customjsonprotected": "तपाईँसँग यस जेसन (JSON) फाइललाई सम्पादन गर्ने अनुमति छैन् किनकि यसमा कुनै अरू व्यक्तिका वैयक्तिक मिलानहरू रहेका छन्।",
        "customjsprotected": "तपाईंलाई यो जाभास्कृप्ट पृष्ठ सम्पादन गर्ने अनुमति छैन, किनकी यसमा कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
+       "sitecssprotected": "तपाईँसँग यो सिएसएस (CSS) पृष्ठ सम्पादन गर्ने अनुमति छैन् किनकि यसले सबै आगन्तुकहरूलाई असर पार्न सक्दछ।",
+       "sitejsonprotected": "तपाईँसँग यो जेसन (JSON) पृष्ठ सम्पादन गर्ने अनुमति छैन् किनकि यसले सबै आगन्तुकहरूलाई असर पार्न सक्दछ।",
        "mycustomcssprotected": "यो CSSपृष्ठ सम्पादन गर्नको लागि लागि तपाईंलाई अनुमति छैन ।",
        "mycustomjsprotected": "यो जावास्क्रिप्ट पृष्ठ सम्पादन गर्नको लागि तपाईंलाई अनुमति छैन ।",
        "myprivateinfoprotected": "तपाईंसँग तपाईंको निजी जानकारीहरू सम्पादन गर्ने अनुमती छैन",
        "nosuchusershort": " \"$1\" नामको कुनै पनि प्रयोगकर्ता भेटिएन।\n तपाईंको हिज्जे जाँच्नुहोस् ।",
        "nouserspecified": "तपाँईले प्रयोगकर्ताको नाम जनाउनुपर्छ।",
        "login-userblocked": "यस प्रयोगकर्तालाई रोक लगाइएको छ। प्रवेश गर्ने अनुमति छैन।",
-       "wrongpassword": "यà¥\81à¤\9cरनà¥\87म à¤µà¤¾ à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\97लत à¤¹à¤¾à¤²à¤¨à¥\81भयाà¥\87।\nà¤\95à¥\83पया à¤«à¥\87रि à¤ªà¥\8dरयास à¤\97रà¥\8dनà¥\81हà¥\8bला।",
+       "wrongpassword": "पà¥\8dरयà¥\8bà¤\97à¤\95रà¥\8dता à¤¨à¤¾à¤® à¤µà¤¾ à¤ªà¤¾à¤¸à¤µà¤°à¥\8dड à¤\97लत à¤¹à¤¾à¤²à¥\8dनà¥\81भयाà¥\87।\nà¤\95à¥\83पया à¤«à¥\87रि à¤ªà¥\8dरयास à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d।",
        "wrongpasswordempty": "हालिएको पासवर्ड खालि थियो।\nकृपया फेरी प्रयास गर्नुहोला।",
        "passwordtooshort": "पासवर्ड कम्तिमा {{PLURAL:$1|१ अक्षर|$1 अक्षरहरू}}को हुनुपर्छ।",
        "passwordtoolong": "पासवर्ड {{PLURAL:$1|१ अक्षर|$1 अक्षरहरू}} भन्दा लामो हुनु हुदैन ।",
        "botpasswords": "बोट पासवर्ड",
        "botpasswords-disabled": "बोट पासवर्डहरू असक्षम गरिएका छन्।",
        "botpasswords-createnew": "नयाँ बोटको लागि पासवर्ड बनाउने",
+       "botpasswords-editexisting": "उपलब्ध बोट पासवर्ड सम्पादन गर्नुहोस्",
+       "botpasswords-label-needsreset": "(पासवर्ड फेर्न आवश्यक छ)",
        "botpasswords-label-appid": "बोट नाम",
        "botpasswords-label-create": "बनाउनुहोस्",
        "botpasswords-label-update": "अद्यतन गर्ने (अपडेट)",
        "botpasswords-insert-failed": "\"$1\" बोट नाम थप्न असफल भयो। के यो पहिले नै थपिएको थियो?",
        "botpasswords-update-failed": "\"$1\" बोट नाम अद्यावधिक गर्न असफल भयो। के यो हटाइयो हो?",
        "botpasswords-created-title": "बोट पासवर्ड सिर्जना गरियो",
+       "botpasswords-updated-title": "बोट पासवर्ड परिवर्तन गरियो",
+       "botpasswords-deleted-title": "बोट पासवर्ड मेटाइयो",
        "resetpass_forbidden": "पासवर्ड परिवर्तन गर्न मिल्दैन",
+       "resetpass_forbidden-reason": "पासवर्डहरू परिवर्तन गर्न सकिदैन: $1",
        "resetpass-no-info": "यो पृष्ठ सिधै हेर्नको लागि तपाईंले प्रवेश गर्नुपर्छ ।",
        "resetpass-submit-loggedin": "प्रवेसशब्द परिवर्तन गर्ने",
        "resetpass-submit-cancel": "रद्द गर्ने",
        "passwordreset-emailelement": "प्रयोगकर्ताको नाम: \n$1\n\nअस्थाई पासवर्ड: \n$2",
        "passwordreset-emailsentemail": "पासवर्ड परिवर्तनको लागि इमेल पठाइएको छ।",
        "passwordreset-invalidemail": "अमान्य इमेल ठेगाना",
-       "changeemail": "à¤\87मà¥\87ल à¤ à¥\87à¤\97ाना à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dनà¥\81हà¥\8bस",
+       "changeemail": "à¤\87मà¥\87ल à¤ à¥\87à¤\97ाना à¤¹à¤\9fाà¤\89नà¥\81हà¥\8bसà¥\8d à¤µà¤¾ à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d",
        "changeemail-header": "खाताको इमेल ठेगाना परिवर्तन गर्नुहोस",
        "changeemail-no-info": "यस पृष्ठमा सिधै जानको लागि प्रवेश गर्नु पर्ने हुन्छ ।",
        "changeemail-oldemail": "हालको इमेल-ठेगाना:",
        "savechanges": "परिवर्तन सङ्ग्रह गर्नुहोस्",
        "publishpage": "पृष्ठ प्रकाशित गर्ने",
        "publishchanges": "परिवर्तनहरू प्रकाशित गर्ने",
-       "savearticle-start": "पृष्ठ संग्रह गर्ने…",
+       "savearticle-start": "पृष्ठ सङ्ग्रह गर्नुहोस्…",
+       "savechanges-start": "परिवर्तनहरू सङ्ग्रह गर्नुहोस्",
+       "publishpage-start": "पृष्ठ प्रकाशित...",
+       "publishchanges-start": "परिवर्तनहरू प्रकाशित...",
        "preview": "पूर्वावलोकन",
        "showpreview": "पूर्वालोकन देखाउनुहोस्",
        "showdiff": "परिवर्तन देखाउनुहोस्",
        "postedit-confirmation-created": "पृष्ठ सिर्जना गरियो ।",
        "postedit-confirmation-restored": "पृष्ठ पूर्वरूपमा फर्कायो ।",
        "postedit-confirmation-saved": "तपाईंको सम्पादन संग्रह गरिएको छ ।",
+       "postedit-confirmation-published": "तपाईँको सम्पादन प्रकाशित गरियो।",
        "edit-already-exists": "नयाँ पृष्ठ बनाउन सकिएन ।\nयो पहिले देखि नै रहेको छ।",
        "defaultmessagetext": "डिफल्ट सन्देश पाठ",
        "content-failed-to-parse": "$1 को लागि $2 सामग्रीलाई पार्स गर्न विफल, त्रुटि: $3",
        "revdelete-submit": "{{PLURAL:$1|छानिएको संशोधन|छानिएका संशोधनहरु}}मा प्रयोग गर्ने",
        "revdelete-success": "संशोधन दृश्यता अद्यतन भयो।",
        "revdelete-failure": "'''संशोधन दृश्यता अद्यतन गर्न सकिएन:'''\n$1",
-       "logdelete-success": "दà¥\83षà¥\8dà¤\9fि à¤²à¤\97 à¤¸à¤«à¤²à¤¤à¤¾à¤ªà¥\82रà¥\8dवà¤\95 à¤®à¤¿à¤²à¤¾à¤\87यà¥\8b ।",
+       "logdelete-success": "लà¤\97 à¤¦à¥\83शà¥\8dयता à¤¸à¤«à¤²à¤¤à¤¾à¤ªà¥\82रà¥\8dवà¤\95 à¤®à¤¿à¤²à¤¾à¤\87यà¥\8b।",
        "logdelete-failure": "'''लग दृष्टि मिलाउन सकिएन :'''\n$1",
        "revdel-restore": "दृष्टि परिवर्तन गर्ने",
        "pagehist": "पृष्ठको इतिहास",
        "mergehistory-empty": "कुनै पनि पुनरावलोकनहरू जोड्न मिल्दैन ।",
        "mergehistory-done": "$3 {{PLURAL:$3|संस्करण|संस्करणहरू}}  $1बाट सफलतापूर्वक [[:$2]]मा थपियो ।",
        "mergehistory-fail": "इतिहास जोड्न सकिएन कृपया पृष्ठको नाम र समयमान जाँच गर्नुहोस्।",
+       "mergehistory-fail-invalid-source": "स्रोत पृष्ठ अमान्य छ।",
+       "mergehistory-fail-invalid-dest": "लक्ष्य पृष्ठ अमान्य छ।",
        "mergehistory-fail-toobig": "इतिहास समाहित गर्न सम्भव छैन किनभने अवतरण सिमा $1 भन्दा बढी {{PLURAL:$1|अवतरण|अवतरणहरू}} लाई स्थानान्तरित गर्नु पर्छ।",
        "mergehistory-no-source": "स्रोत पृष्ठ $1 अस्तित्वमा छैन ।",
        "mergehistory-no-destination": "गन्तव्य पृष्ठ $1 अस्तित्वमा छैन ।",
        "diff-multi-manyusers": "($2 {{PLURAL:$2|भन्दा अधिक प्रयोगकर्ता|भन्दा अधिक प्रयोगकर्ताहरू}}द्वारा {{PLURAL:$1|एउटा मध्यवर्ती संशोधन|$1 मध्यवर्ती संशोधनहरू}} नदेखाइएको)",
        "difference-missing-revision": "यस अन्तर {{PLURAL:$2|को एक अवतरण|को $2 अवतरण}} ($1)  {{PLURAL:$2|भेटिएन|खोज्न सकिएन}}।\n\nयो सामान्य रूपमा एउटा हताइएको पृष्ठको अवतरणहरूमा अन्तर खोज्दा हुन्छ । अधिक जानकारी [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} हटाइएको लग]मा हेर्न सकिन्छ।",
        "searchresults": "खोज नतिजाहरू",
+       "search-filter-title-prefix-reset": "सबै पृष्ठहरू खोजी गर्नुहोस्",
        "searchresults-title": " \"$1\"को लागि खोज नतिजाहरू",
        "titlematches": "पृष्ठ शिर्षक मिल्छ",
        "textmatches": "पृष्ठ पाठ मिल्छ",
        "search-category": "(श्रेणी $1)",
        "search-file-match": "(भेटिएका फाइल सामाग्री)",
        "search-suggest": "कतै तपाईंको खोजाई : $1 त होइन ?",
-       "search-interwiki-caption": "समà¥\8dबनà¥\8dधà¥\80 à¤ªà¤°à¤¿à¤¯à¥\8bà¤\9cनाहरà¥\82à¤\95ा परिणामहरू",
+       "search-interwiki-caption": "भà¥\8dरातà¥\83 à¤ªà¤°à¤¿à¤¯à¥\8bà¤\9cनाहरà¥\82बाà¤\9f परिणामहरू",
        "search-interwiki-default": "$1देखिका नतिजाहरू:",
        "search-interwiki-more": "(अझै)",
        "search-interwiki-more-results": "धेरै परिणामहरू",
        "prefs-watchlist-edits": "निगरानी सूचीमा देखाउनको लागि उच्चतम परिवर्तन संख्या:",
        "prefs-watchlist-edits-max": "उच्चतम संख्या : १०००",
        "prefs-watchlist-token": "अवलोकन सूची टोकन:",
-       "prefs-watchlist-managetokens": "टोकन व्यवस्थापन",
+       "prefs-watchlist-managetokens": "टोकनहरू व्यवस्थापन",
        "prefs-misc": "साधारण",
        "prefs-resetpass": "प्रवेश शब्द परिवर्तन",
        "prefs-changeemail": "इमेल परिवर्तन गर्ने",
        "userrights-user-editname": "प्रयोगकर्ता नाम दिनुहोस् :",
        "editusergroup": "प्रयोगकर्ता समूह सम्पादन गर्नुहोस्",
        "editinguser": "प्रयोगकर्ता '''[[User:$1|$1]]''' $2 को अधिकार परिवर्तन गर्ने\n{{GENDER:$1|प्रयोगकर्ता}}को प्रयोगकर्ता अधिकार परिवर्तन हुँदैछ <strong>[[User:$1|$1]]</strong> $2",
-       "userrights-editusergroup": "प्रयोगकर्ता समूह सम्पादन गर्नुहोस्",
+       "userrights-editusergroup": "{{GENDER:$1|प्रयोगकर्ता}} समूहहरू सम्पादन गर्नुहोस्",
        "userrights-viewusergroup": "{{GENDER:$1|प्रयोगकर्ता}} समूहहरू हेर्नुहोस्।",
-       "saveusergroups": "प्रयोगकर्ता समूहरू संग्रह गर्नुहोस्",
+       "saveusergroups": "{{GENDER:$1|प्रयोगकर्ता}} समूहहरू सङ्ग्रह गर्नुहोस्",
        "userrights-groupsmember": "को सदस्य:",
        "userrights-groupsmember-auto": "अंतर्निहित सदस्य:",
        "userrights-groups-help": "यो प्रयोगकर्ता भएको समूहलाई अदलबदल गर्न सक्नुहुन्छ:\n* बाकस चेक्ड(checked) हुनु्को अर्थ प्रयोगकर्ता त्यस समूहमा छ।\n* बाकस अनचेक्ड (unchecked) हुनु्को अर्थ प्रयोगकर्ता त्यस समूहमा छैन।\n*  *ले संकेत दिन्छ तपाईं त्यस समूहलाई हटाउन सक्नुहुन्न जब तपाईंले यसलाई जोड़िसक्नु भएकोछ अथवा अदला बदलि गर्नुभएकोछ।",
        "grant-group-file-interaction": "मिडियासँग अन्तरक्रिया गर्नुहोस्",
        "grant-group-watchlist-interaction": "तपाईंको दृष्टिसूचीसँग अन्तरक्रिया गर्नुहोस्",
        "grant-group-email": "इ-मेल पठाउनुहोस्",
-       "grant-createaccount": "खाता खोल्नुहोस्",
+       "grant-createaccount": "खाताहरू खोल्नुहोस्",
        "grant-createeditmovepage": "पृष्ठहरूमा परिवर्तन गर्नुहोस्",
-       "grant-editmycssjs": "तपाईंको प्रयोगकर्ताकाे CSS/JavaScript सम्पादन गर्नुहोस्",
+       "grant-editmycssjs": "तपाईंको प्रयोगकर्ता सीएसएस/जेसन/जावास्क्रिप्ट (CSS/JSON/JavaScript) सम्पादन गर्नुहोस्",
        "grant-editmyoptions": "तपाईंको प्रयोगकर्ता अभिरूचीहरूलाई सम्पादन गर्नुहोस्",
-       "grant-editmywatchlist": "à¤\85वलà¥\8bà¤\95नसà¥\82à¤\9aà¥\80 à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनà¥\87",
+       "grant-editmywatchlist": "तपाà¤\88à¤\81à¤\95à¥\8b à¤\85वलà¥\8bà¤\95नसà¥\82à¤\9aà¥\80 à¤¸à¤®à¥\8dपादन à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d",
        "grant-sendemail": "अन्य प्रयोगकर्ताहरूलाई इमेल पठाउने",
        "grant-viewdeleted": "मेटाइएका फाइल तथा पृष्ठहरू हेर्ने",
        "newuserlogpage": "प्रयोगकर्ता श्रृजना लग",
        "action-read": "यो पृष्ठ पढ्ने",
        "action-edit": "यो पृष्ठ सम्पादन गर्ने",
        "action-createpage": "यो पृष्ठ सृजना गर्ने",
-       "action-createtalk": "याà¥\87 à¤\9bलफल à¤ªà¥\83षà¥\8dठ à¤¸à¥\83à¤\9cना à¤\97रà¥\8dनà¥\87",
+       "action-createtalk": "याà¥\87 à¤\9bलफल à¤ªà¥\83षà¥\8dठ à¤¸à¥\83à¤\9cना à¤\97रà¥\8dनà¥\81हà¥\8bसà¥\8d",
        "action-createaccount": "यो प्रयोगकर्ताखाता बनाउने",
        "action-history": "यस पृष्ठको इतिहास हेर्ने",
        "action-minoredit": "यस सम्पादनलाई साधारणको रुपमा चिनो लगाउने",
        "rcfilters-days-show-days": "$1 {{PLURAL:$1|दिन|दिनहरू}}",
        "rcfilters-days-show-hours": "$1 {{PLURAL:$1|घण्टा|घण्टाहरू}}",
        "rcfilters-savedqueries-setdefault": "पूर्वनिर्धारितको रुपमा सेट गर्नुहोस्",
-       "rcfilters-savedqueries-remove": "मà¥\87à¤\9fà¥\8dनà¥\87",
+       "rcfilters-savedqueries-remove": "मà¥\87à¤\9fà¥\8dनà¥\81हà¥\8bसà¥\8d",
        "rcfilters-savedqueries-new-name-label": "नाम",
        "rcfilters-savedqueries-cancel-label": "रद्द गर्नुहोस्",
        "rcfilters-show-new-changes": "नवीनतम परिवर्तनहरू हेर्नुहोस्",
        "rcfilters-filterlist-title": "फिल्टरहरू",
-       "rcfilters-highlightmenu-title": "रà¤\82à¤\97 à¤\9bनà¥\8dनà¥\81हाà¥\87स",
-       "rcfilters-filter-user-experience-level-registered-label": "दरà¥\8dता à¤\97रà¥\80एकाे",
+       "rcfilters-highlightmenu-title": "रà¤\99à¥\8dà¤\97 à¤\9bानà¥\8dनà¥\81हाà¥\87सà¥\8d",
+       "rcfilters-filter-user-experience-level-registered-label": "दरà¥\8dता à¤\97रिएकाे",
        "rcfilters-filter-user-experience-level-unregistered-label": "दर्ता नभएकाे",
        "rcfilters-filter-bots-label": "बोट",
        "rcfilters-filter-minor-label": "सामान्य सम्पादनहरू",
        "apisandbox-reset": "हटाउने",
        "apisandbox-retry": "पुनः प्रयास गर्नुहोस्",
        "apisandbox-examples": "उदाहरण",
-       "apisandbox-results": "परिणाम",
+       "apisandbox-results": "नतिà¤\9cाहरà¥\82",
        "apisandbox-request-url-label": "अनुरोध युआरयल:",
-       "apisandbox-request-time": "अनुरोधको समयावधी: $1",
+       "apisandbox-request-time": "अनुरोध समयावधी: {{PLURAL:$1|$1 मिसे}}",
        "apisandbox-continue-clear": "खाली गर्नुहोस्",
        "booksources": "किताबका श्रोतहरु",
        "booksources-search-legend": "किताबका श्रोतहरु खोज्ने",
index e47a88c..f865446 100644 (file)
        "timezonelegend": "Tijdzone:",
        "localtime": "Plaatselijke tijd:",
        "timezoneuseserverdefault": "Wikistandaard gebruiken ($1)",
-       "timezoneuseoffset": "Anders (tijdverschil opgeven)",
+       "timezoneuseoffset": "Anders (vul tijdverschil hier beneden in)",
+       "timezone-useoffset-placeholder": "Voorbeeldinvoer: \"-07:00\" of \"01:00\"",
        "servertime": "Servertijd:",
        "guesstimezone": "Vanuit de browser toevoegen",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Tekstverwerker",
        "prefs-preview": "Voorvertoning",
        "prefs-advancedrc": "Gevorderde instellingen",
-       "prefs-opt-out": "Niet deelnemen aan verbeteringen",
        "prefs-advancedrendering": "Gevorderde instellingen",
        "prefs-advancedsearchoptions": "Gevorderde instellingen",
        "prefs-advancedwatchlist": "Gevorderde instellingen",
        "rcfilters-savedqueries-apply-label": "Filter aanmaken",
        "rcfilters-savedqueries-apply-and-setdefault-label": "Standaard filter aanmaken",
        "rcfilters-savedqueries-cancel-label": "Annuleren",
-       "rcfilters-savedqueries-add-new-title": "Huidige filter instellingen opslaan",
+       "rcfilters-savedqueries-add-new-title": "Huidige filterinstellingen opslaan",
        "rcfilters-savedqueries-already-saved": "Deze filters zijn al opgeslagen. Wijzig uw instellingen om een nieuw Filter op te slaan.",
        "rcfilters-restore-default-filters": "Standaard filters terugzetten",
        "rcfilters-clear-all-filters": "Alle filters verwijderen",
index df6b5f6..ee10a52 100644 (file)
        "summary-preview": "Førehandsvising av endringssamandraget:",
        "subject-preview": "Førehandsvising av emne/overskrift:",
        "blockedtitle": "Brukaren er blokkert",
-       "blockedtext": "'''Brukarnamnet ditt eller IP-adressa di er blokkert'''\n\nBlokkeringa vart gjord av $1.\nDenne grunnen vart gjeven: ''$2''.\n\n* Blokkeringa byrja: $8\n* Blokkeringa endar: $6\n* Blokkeringa var meint for: $7\n\nDu kan kontakte $1 eller ein annan [[{{MediaWiki:Grouppage-sysop}}|administrator]] for å diskutere blokkeringa.\nVer merksam på at du ikkje kan bruke «send e-post til brukar»-funksjonen så lenge du ikkje har ei gyldig e-postadresse registrert i [[Special:Preferences|innstillingane dine]]. Du kan heller ikkje bruke funksjonen dersom du er blokkert frå å sende e-post.\nIP-adressa di er $3, og blokkeringsnummeret er $5.\nTak med alle opplysningane over ved eventuelle førespurnader.",
-       "autoblockedtext": "IP-adressa di er automatisk blokkert fordi ho vart brukt av ein annan brukar som vart blokkert av $1. Grunne til dette vart gjeve som: ''$2''.\n\n* Blokkeringa byrja: $8\n* Blokkeringa går ut: $6\n* Blokkeringa er meint for: $7\n\nDu kan kontakte $1 eller ein annan [[{{MediaWiki:Grouppage-sysop}}|administrator]] for å diskutere blokkeringa. Ver merksam på at du ikkje kan bruke «send e-post til brukar»-funksjonen så lenge du ikkje har ei gyldig e-postadresse registrert i [[Special:Preferences|innstillingane dine]].\n\nIP-adressa di er $3, og blokkeringnummeret ditt er #$5.\nVer venleg og opplyse dette ved eventuelle førespurnader.",
+       "blocked-email-user": "<strong>Brukarnamnet ditt er blokkert frå å senda e-post. Du kan framleis endra andre sider på denne wikien.</strong> Du kan sjå alle detaljane om blokkeringa i [[Special:MyContributions|bidragslista]].\n\nBlokkeringa vart gjord av $1.\n\nDen oppgjevne årsaka er <em>$2</em>.\n\n* Blokkeringa byrja: $8\n* Blokkeringa endar: $6\n* Blokkeringa gjeld brukar: $7\n* Blokkerings-ID #$5",
+       "blockedtext-partial": "<strong>Brukarnamnet ditt er blokkert frå å endra denne sida. Du kan framleis endra andre sider på denne wikien.</strong> Du kan sjå alle detaljane om blokkeringa i [[Special:MyContributions|bidragslista]].\n\nBlokkeringa vart gjord av $1.\n\nDen oppgjevne årsaka er <em>$2</em>.\n\n* Blokkeringa byrja: $8\n* Blokkeringa endar: $6\n* Blokkeringa gjeld brukar: $7\n* Blokkerings-ID #$5",
+       "blockedtext": "<strong>Brukarnamnet ditt eller IP-adressa di er blokkert.</strong>\n\nBlokkeringa vart gjord av $1.\nDen oppgjevne årsaka er <em>$2</em>.\n\n* Blokkeringa byrja: $8\n* Blokkeringa endar: $6\n* Blokkeringa gjeld brukar: $7\n\nDu kan kontakte $1 eller ein annan [[{{MediaWiki:Grouppage-sysop}}|administrator]] for å diskutere blokkeringa.\nVer merksam på at du ikkje kan bruke «{{int:emailuser}}»-funksjonen minder du har ei gyldig e-postadresse registrert i [[Special:Preferences|innstillingane dine]] og ikkje er blokkert frå å bruke denne funksjonen.\nDen gjeldande IP-adressa di er $3, og blokkerings-ID-en er #$5.\nTa med alle opplysingane over ved eventuelle førespurnader.",
+       "autoblockedtext": "IP-adressa di vart blokkert automatisk fordi ho vart brukt av ein annan brukar som var blokkert av $1.\nDen oppgjevne årsaka er:\n\n:<em>$2</em>\n\n* Blokkeringa byrja: $8\n* Blokkeringa endar: $6\n* Blokkeringa gjeld brukar: $7\n\nDu kan kontakte $1 eller ein annan [[{{MediaWiki:Grouppage-sysop}}|administrator]] for å diskutere blokkeringa.\n\nVer merksam på at du ikkje kan bruke «{{int:emailuser}}»-funksjonen minder du har ei gyldig e-postadresse registrert i [[Special:Preferences|innstillingane dine]] og ikkje er blokkert frå å bruke denne funksjonen.\n\nDen gjeldande IP-adressa di er $3, og blokkerings-ID-en er #$5.\nTa med alle opplysingane over ved eventuelle førespurnader.",
+       "systemblockedtext": "Brukarnamnet ditt eller IP-adressa di vart blokkert automatisk av MediaWiki.\nDen oppgjevne årsaka er:\n\n:<em>$2</em>\n\n* Blokkeringa byrja: $8\n* Blokkeringa endar: $6\n* Blokkeringa gjeld brukar: $7\n\nDen gjeldande IP-adressa di er $3.\nTa med alle opplysingane over ved eventuelle førespurnader.",
        "blockednoreason": "inga grunngjeving",
        "whitelistedittext": "Du lyt $1 for å endre sider.",
        "confirmedittext": "Du må stadfeste e-postadressa di før du kan endre sidene. Ver venleg og legg inn og stadfest e-postadressa di i [[Special:Preferences|innstillingane dine]].",
        "protect-expiry-options": "1 time:1 hour,1 dag:1 day,1 veke:1 week,2 veker:2 weeks,1 månad:1 month,3 månader:3 months,6 månader:6 months,1 år:1 year,endelaus:infinite",
        "restriction-type": "Tilgang:",
        "restriction-level": "Avgrensingsnivå:",
-       "minimum-size": "Minimumstorleik",
-       "maximum-size": "Maksimumstorleik:",
+       "minimum-size": "Minstestorleik",
+       "maximum-size": "Størstestorleik:",
        "pagesize": "(byte)",
        "restriction-edit": "Endring",
        "restriction-move": "Flytting",
        "autoblockid": "Autoblokker #$1",
        "block": "Blokker brukar",
        "unblock": "Opphev blokkering av brukar",
-       "blockip": "Blokker brukar",
+       "blockip": "Blokker {{GENDER:$1|brukar}}",
        "blockiptext": "Bruk skjemaet nedanfor for å blokkere skrivetilgangen frå ei spesifikk IP-adresse eller brukarnamn. Dette bør berre gjerast for å hindre hærverk, og i samsvar med [[{{MediaWiki:Policy-url}}|retningslinene]].",
        "ipaddressorusername": "IP-adresse eller brukarnamn",
        "ipbexpiry": "Opphøyrstid:",
        "tags-create-reason": "Årsak:",
        "tags-create-submit": "Opprett",
        "tags-create-no-name": "Du må oppgje eit merkenamn.",
+       "tags-update-blocked": "Du kan ikkje leggja til eller fjerna merke medan {{GENDER:$1|du}} er blokkert.",
        "tags-edit-title": "Endra merke",
        "tags-edit-existing-tags-none": "«Ingen»",
        "tags-edit-chosen-placeholder": "Vel nokre merke",
        "revdelete-unrestricted": "fjerna avgrensingar for administratorar",
        "logentry-block-block": "$1 {{GENDER:$2|blokkerte}} {{GENDER:$4|$3}} for $5 $6",
        "logentry-block-unblock": "$1 {{GENDER:$2|oppheva}} blokkeringa av {{GENDER:$4|$3}}",
+       "logentry-block-reblock": "$1 {{GENDER:$2|endra}} innstillingar for blokkeringa av {{GENDER:$4|$3}} som endar $5 $6",
+       "logentry-partialblock-reblock": "$1 {{GENDER:$2|endra}} innstillingar for blokkeringa av {{GENDER:$4|$3}} som hindrar endring av {{PLURAL:$8|sida|sidene}} $7 og som endar $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|endra}} innstillingar for blokkeringa av {{GENDER:$4|$3}} for visse handlingar som ikkje er endringar og som endar $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|endra}} blokkeringsinnstillingar for {{GENDER:$4|$3}} med opphøyrstid $5 $6",
        "logentry-merge-merge": "$1 {{GENDER:$2|fletta}} $3 inn i $4 (versjonar til og med $5)",
        "logentry-move-move": "$1 {{GENDER:$2|flytte}} sida $3 til $4",
        "date-range-from": "Frå dato:",
        "date-range-to": "Til dato:",
        "randomrootpage": "Tilfeldig rotside",
+       "log-action-filter-block": "Blokkeringstype:",
        "log-action-filter-newusers": "Type kontooppretting:",
        "log-action-filter-rights": "Type endring av rettar:",
        "log-action-filter-all": "Alle",
+       "log-action-filter-block-block": "Blokkering",
        "log-action-filter-delete-delete_redir": "Overskriving av omdirigering",
        "log-action-filter-delete-restore": "Attoppretting av side",
        "log-action-filter-delete-revision": "Versjonssletting",
        "log-action-filter-newusers-autocreate": "Automatisk oppretting",
        "log-action-filter-newusers-byemail": "Oppretting med passord sendt på e-post",
        "log-action-filter-suppress-revision": "Versjonsundertrykking",
+       "log-action-filter-suppress-block": "Fjerning av brukar ved blokkering",
        "authmanager-userdoesnotexist": "Brukarkontoen «$1» er ikkje oppretta.",
        "authmanager-provider-temporarypassword": "Mellombels passord",
        "userjsispublic": "Merk: JavaScript-undersider bør ikkje innehalda konfidensielle data sidan dei er synlege for andre brukarar.",
index f10f482..2b6a657 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Apercebut",
        "prefs-advancedrc": "Opcions avançadas",
-       "prefs-opt-out": "Refusar los melhoraments",
        "prefs-advancedrendering": "Opcions avançadas",
        "prefs-advancedsearchoptions": "Opcions avançadas",
        "prefs-advancedwatchlist": "Opcions avançadas",
index 9184978..32ee769 100644 (file)
@@ -99,7 +99,8 @@
                        "Acamicamacaraca",
                        "DeRudySoulStorm",
                        "Railfail536",
-                       "Vlad5250"
+                       "Vlad5250",
+                       "CiaPan"
                ]
        },
        "tog-underline": "Podkreślenie linków:",
        "localtime": "Czas lokalny:",
        "timezoneuseserverdefault": "Użyj domyślnej dla tej wiki ($1)",
        "timezoneuseoffset": "Inna (określ różnicę czasu)",
+       "timezone-useoffset-placeholder": "Przykładowe wartości: \"-07:00\" lub \"01:00\"",
        "servertime": "Czas serwera:",
        "guesstimezone": "Pobierz z przeglądarki",
        "timezoneregion-africa": "Afryka",
        "prefs-editor": "Edytor",
        "prefs-preview": "Podgląd",
        "prefs-advancedrc": "Zaawansowane",
-       "prefs-opt-out": "Rezygnacja z ulepszeń",
        "prefs-advancedrendering": "Zaawansowane",
        "prefs-advancedsearchoptions": "Zaawansowane",
        "prefs-advancedwatchlist": "Zaawansowane",
        "tooltip-t-emailuser": "Wyślij e‐mail do {{GENDER:$1|tego użytkownika|tej użytkowniczki}}",
        "tooltip-t-info": "Więcej informacji na temat tej strony",
        "tooltip-t-upload": "Prześlij pliki",
-       "tooltip-t-specialpages": "Lista wszystkich specjalnych stron",
+       "tooltip-t-specialpages": "Lista wszystkich stron specjalnych",
        "tooltip-t-print": "Wersja do wydruku",
        "tooltip-t-permalink": "Stały link do tej wersji strony",
        "tooltip-ca-nstab-main": "Zobacz stronę treści",
        "show-big-image-preview": "Rozmiar podglądu – $1.",
        "show-big-image-preview-differ": "Wielkość pliku podglądu $3 dla pliku $2: $1",
        "show-big-image-other": "{{PLURAL:$2|Inna rozdzielczość|Inne rozdzielczości}}: $1.",
-       "show-big-image-size": "$1 x $2 pikseli",
+       "show-big-image-size": "$1 × $2 pikseli",
        "file-info-gif-looped": "zapętlony",
        "file-info-gif-frames": "$1 {{PLURAL:$1|klatka|klatki|klatek}}",
        "file-info-png-looped": "zapętlony",
        "passwordpolicies-policy-maximalpasswordlength": "Hasło musi mieć mniej niż $1 {{PLURAL:$1|znak|znaki|znaków}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Hasło nie może być {{PLURAL:$1|popularne|na liście $1 popularnych haseł}}",
        "passwordpolicies-policy-passwordnotinlargeblacklist": "Hasło nie może znajdować się na liście 100 000 najczęściej używanych haseł.",
+       "easydeflate-invaliddeflate": "Dostarczona zawartość nie jest poprawnie skompresowana",
        "unprotected-js": "Ze względów bezpieczeństwa kod JavaScript nie może zostać załadowany z niezabezpieczonych stron. Prosimy dodawać JavaScript w przestrzeni MediaWiki lub jako podstronę strony użytkownika."
 }
index a7adeb9..9527fb8 100644 (file)
        "prefs-editor": "سمونگر",
        "prefs-preview": "مخليدنه",
        "prefs-advancedrc": "پرمختللې خوښنې",
-       "prefs-opt-out": "د پرمختګونو څخه لرې کول",
        "prefs-advancedrendering": "پرمختللې خوښنې",
        "prefs-advancedsearchoptions": "پرمختللې خوښنې",
        "prefs-advancedwatchlist": "پرمختللې خوښنې",
index c15990f..2835539 100644 (file)
        "tog-newpageshidepatrolled": "Ocultar páginas patrulhadas da lista de páginas novas",
        "tog-hidecategorization": "Ocultar a categorização das páginas",
        "tog-extendwatchlist": "Expandir a lista de páginas vigiadas para mostrar todas as mudanças, não apenas as mais recentes",
-       "tog-usenewrc": "Agrupar alterações por páginas nas mudanças recentes e nas páginas vigiadas",
+       "tog-usenewrc": "Agrupar alterações por páginas nas mudanças recentes e na lista de páginas vigiadas",
        "tog-numberheadings": "Auto-numerar cabeçalhos",
        "tog-editondblclick": "Editar páginas no clique duplo",
-       "tog-editsectiononrightclick": "Habilitar edição de seção por clique com o botão direito no título da seção (requer JavaScript)",
-       "tog-watchcreations": "Adicionar as páginas e arquivos que \neu criar à minha lista de páginas vigiadas",
-       "tog-watchdefault": "Adicionar as páginas e arquivos que eu editar à minha lista de páginas vigiadas",
-       "tog-watchmoves": "Adicionar as páginas e arquivos que eu mover à minha lista de páginas vigiadas",
-       "tog-watchdeletion": "Adicionar as páginas e arquivos que eu eliminar à minha lista de páginas vigiadas",
-       "tog-watchuploads": "Adicionar arquivos que envio para minha lista de vigiados",
-       "tog-watchrollback": "Adicionar páginas onde fiz uma reversão às minhas páginas vigiadas",
+       "tog-editsectiononrightclick": "Habilitar edição de seção por clique com o botão direito no título da seção",
+       "tog-watchcreations": "Adicionar páginas e arquivos que eu criar à minha lista de páginas vigiadas",
+       "tog-watchdefault": "Adicionar páginas e arquivos que eu editar à minha lista de páginas vigiadas",
+       "tog-watchmoves": "Adicionar páginas e arquivos que eu mover à minha lista de páginas vigiadas",
+       "tog-watchdeletion": "Adicionar páginas e arquivos que eu eliminar à minha lista de páginas vigiadas",
+       "tog-watchuploads": "Adicionar arquivos que eu carregar à minha lista de páginas vigiadas",
+       "tog-watchrollback": "Adicionar páginas onde fiz uma reversão à minha lista de páginas vigiadas",
        "tog-minordefault": "Marcar todas as edições como menores por padrão",
        "tog-previewontop": "Mostrar previsão antes da caixa de edição",
        "tog-previewonfirst": "Mostrar previsão na primeira edição",
        "tog-enotifwatchlistpages": "Notificar-me por e-mail quando uma página ou um arquivo vigiado for alterado",
-       "tog-enotifusertalkpages": "Receber email quando minha página de discussão for editada",
+       "tog-enotifusertalkpages": "Receber e-mail quando minha página de discussão for editada",
        "tog-enotifminoredits": "Notificar-me por e-mail também sobre edições menores de páginas ou arquivos",
-       "tog-enotifrevealaddr": "Revelar meu endereço de email nas mensagens de notificação",
+       "tog-enotifrevealaddr": "Revelar meu endereço de e-mail nas mensagens de notificação",
        "tog-shownumberswatching": "Mostrar o número de usuários que estão vigiando",
        "tog-oldsig": "Assinatura atual:",
        "tog-fancysig": "Tratar assinatura como wikitexto (sem ligação automática)",
        "tog-uselivepreview": "Mostrar visualizações sem recarregar a página",
        "tog-forceeditsummary": "Avisar-me ao introduzir um sumário de edição vazio",
-       "tog-watchlisthideown": "Ocultar as minhas edições da lista de páginas vigiadas",
-       "tog-watchlisthidebots": "Ocultar edições de bots da lista de páginas vigiadas",
+       "tog-watchlisthideown": "Ocultar minhas edições da lista de páginas vigiadas",
+       "tog-watchlisthidebots": "Ocultar edições de robôs da lista de páginas vigiadas",
        "tog-watchlisthideminor": "Ocultar edições menores da lista de páginas vigiadas",
        "tog-watchlisthideliu": "Ocultar edições de usuários autenticados da lista de páginas vigiadas",
        "tog-watchlistreloadautomatically": "Recarregar a lista de páginas vigiadas automaticamente sempre que um filtro for alterado (requer JavaScript)",
        "tog-ccmeonemails": "Receber cópias de e-mails que eu enviar a outros usuários",
        "tog-diffonly": "Não mostrar o conteúdo da página ao comparar duas edições",
        "tog-showhiddencats": "Exibir categorias ocultas",
-       "tog-norollbackdiff": "Omitir diferenças após desfazer edições em bloco",
+       "tog-norollbackdiff": "Omitir diferenças após fazer uma reversão",
        "tog-useeditwarning": "Avisar-me quando eu deixar uma janela de edição sem ter salvo as alterações",
        "tog-prefershttps": "Usar sempre uma conexão segura enquanto estiver conectado",
        "underline-always": "Sempre",
        "category-empty": "<em>No momento, esta categoria não possui nenhuma página ou arquivo multimídia.</em>",
        "hidden-categories": "{{PLURAL:$1|Categoria oculta|Categorias ocultas}}",
        "hidden-category-category": "Categorias ocultas",
-       "category-subcat-count": "{{PLURAL:$2|Esta categoria possui apenas a seguinte subcategoria.|Esta categoria possui as seguintes $1 subcategorias, de um total de $2.}}",
-       "category-subcat-count-limited": "Esta categoria possui {{PLURAL:$1|a seguinte sub-categoria|as $1 sub-categorias a seguir}}.",
-       "category-article-count": "{{PLURAL:$2|Esta categoria contém apenas a seguinte página.|As seguintes $1 páginas pertencem a esta categoria, de um total de $2.}}",
+       "category-subcat-count": "{{PLURAL:$2|Esta categoria possui apenas a seguinte subcategoria.|Esta categoria possui {{PLURAL:$1|a seguinte subcategoria|as seguintes $1 subcategorias}}, de um total de $2.}}",
+       "category-subcat-count-limited": "Esta categoria possui {{PLURAL:$1|a seguinte subcategoria|as $1 subcategorias a seguir}}.",
+       "category-article-count": "{{PLURAL:$2|Esta categoria contém apenas a seguinte página.|{{PLURA:$1|A seguinte página pertence|As seguintes $1 páginas pertencem}} a esta categoria, de um total de $2.}}",
        "category-article-count-limited": "Esta categoria possui {{PLURAL:$1|a seguinte página|as $1 páginas a seguir}}.",
        "category-file-count": "{{PLURAL:$2|Esta categoria possui apenas o seguinte arquivo.|Esta categoria possui {{PLURAL:$1|o seguinte arquivo|os $1 arquivos a seguir}}, de um total de $2.}}",
        "category-file-count-limited": "Esta categoria possui {{PLURAL:$1|um arquivo|$1 arquivos}}.",
        "listingcontinuesabbrev": "cont.",
        "index-category": "Páginas indexadas",
        "noindex-category": "Páginas não indexadas",
-       "broken-file-category": "Páginas com links inválidos para arquivos",
+       "broken-file-category": "Páginas com ligações inválidas para arquivos",
        "categoryviewer-pagedlinks": "($1) ($2)",
        "category-header-numerals": "$1–$2",
        "about": "Sobre",
        "article": "Página de conteúdo",
        "newwindow": "(abre numa nova janela)",
        "cancel": "Cancelar",
-       "moredotdotdot": "Mais...",
-       "morenotlisted": "Esta lista está incompleta.",
+       "moredotdotdot": "Mais",
+       "morenotlisted": "Esta lista pode estar incompleta.",
        "mypage": "Página",
        "mytalk": "Discussão",
        "anontalk": "Discussão",
        "and": "&#32;e",
        "faq": "Perguntas frequentes",
        "actions": "Ações",
-       "namespaces": "Domínios",
+       "namespaces": "Espaços nominais",
        "variants": "Variantes",
        "navigation-heading": "Menu de navegação",
        "errorpagetitle": "Erro",
        "tagline": "De {{SITENAME}}",
        "help": "Ajuda",
        "search": "Pesquisa",
-       "search-ignored-headings": " #<!-- deixe esta linha exatamente como está --> <pre>\n# Subtítulos que serão ignorados pela busca.\n# Mudanças feitas aqui têm efeito quando a página com o subtítulo é indexada.\n# Você pode forçar a reindexação realizando uma edição nula.\n# A sintaxe é a seguinte:\n#   * Tudo a partir do caractere \"#\" até o final da linha é um comentário\n#   * Cada linha não vazia é o título exato a ser ignorado, inclusive no uso de maiúsculas\nReferências\nLigações externas\nVer também\n #</pre> <!-- deixe esta linha exatamente como está -->",
+       "search-ignored-headings": " #<!-- deixe esta linha exatamente como está --> <pre>\n# Cabeçalhos que serão ignorados pela busca.\n# Mudanças feitas aqui têm efeito quando a página com o cabeçalho é indexada.\n# Você pode forçar a reindexação realizando uma edição nula.\n# A sintaxe é a seguinte:\n#   * Tudo a partir do caractere \"#\" até o final da linha é um comentário.\n#   * Cada linha não vazia é o título exato a ser ignorado, inclusive no uso de maiúsculas.\nReferências\nLigações externas\nVer também\n #</pre> <!-- deixe esta linha exatamente como está -->",
        "searchbutton": "Pesquisar",
        "go": "Ir",
        "searcharticle": "Ir",
        "history": "Histórico da página",
        "history_short": "Histórico",
-       "history_small": "Histórico",
+       "history_small": "histórico",
        "updatedmarker": "atualizado desde a minha última visita",
        "printableversion": "Versão para impressão",
        "permalink": "Ligação permanente",
        "print": "Imprimir",
-       "view": "Ver",
+       "view": "Visualizar",
        "view-foreign": "Ver em $1",
        "edit": "Editar",
        "edit-local": "Editar descrição local",
        "create-local": "Adicionar descrição local",
        "delete": "Eliminar",
        "undelete_short": "Restaurar {{PLURAL:$1|uma edição|$1 edições}}",
-       "viewdeleted_short": "Ver {{PLURAL:$1|uma edição eliminada|$1 edições eliminadas}}",
+       "viewdeleted_short": "Ver {{PLURAL:$1|a edição eliminada|as $1 edições eliminadas}}",
        "protect": "Proteger",
        "protect_change": "alterar",
        "unprotect": "Alterar a proteção",
        "redirectedfrom": "(Redirecionado de $1)",
        "redirectpagesub": "Página de redirecionamento",
        "redirectto": "Redirecionar para:",
-       "lastmodifiedat": "Esta página foi modificada pela última vez em $1, às $2",
+       "lastmodifiedat": "Esta página foi modificada pela última vez em $1, às $2.",
        "viewcount": "Esta página foi acessada {{PLURAL:$1|uma vez|$1 vezes}}.",
        "protectedpage": "Página protegida",
        "jumpto": "Ir para:",
        "pool-timeout": "Tempo limite de espera para o bloqueio excedido",
        "pool-queuefull": "A fila de processos está cheia",
        "pool-errorunknown": "Erro desconhecido",
-       "pool-servererror": "O servidor de contador do pool não está disponível ($1).",
+       "pool-servererror": "O servidor de contador de processos não está disponível ($1).",
        "poolcounter-usage-error": "Erro de uso: $1",
        "aboutsite": "Sobre {{SITENAME}}",
        "aboutpage": "Project:Sobre",
        "copyright": "Conteúdo disponível sob $1, salvo indicação em contrário.",
-       "copyrightpage": "{{ns:project}}:Direitos_de_autor",
+       "copyrightpage": "{{ns:project}}:Direitos de autor",
        "currentevents": "Eventos atuais",
        "currentevents-url": "Project:Eventos atuais",
        "disclaimers": "Termo de responsabilidade",
        "privacy": "Política de privacidade",
        "privacypage": "Project:Política de privacidade",
        "badaccess": "Erro de permissão",
-       "badaccess-group0": "Você não está autorizado a executar a ação requisitada.",
+       "badaccess-group0": "Você não tem autorização para executar a ação requisitada.",
        "badaccess-groups": "A ação que você tentou executar está limitada a usuários {{PLURAL:$2|do grupo|de um dos seguintes grupos}}: $1.",
        "versionrequired": "É necessária a versão $1 do MediaWiki",
        "versionrequiredtext": "Esta página requer a versão $1 do MediaWiki para ser utilizada.\nVeja a [[Special:Version|página sobre a versão do sistema]].",
        "pagetitle": "$1 - {{SITENAME}}",
        "pagetitle-view-mainpage": "{{SITENAME}}",
        "backlinksubtitle": "← $1",
-       "retrievedfrom": "Disponível em \"$1\"",
+       "retrievedfrom": "Disponível em “$1”",
        "youhavenewmessages": "{{PLURAL:$3|Você tem}} $1 ($2).",
        "youhavenewmessagesfromusers": "{{PLURAL:$4|Você tem}} $1 de {{PLURAL:$3|outro usuário|$3 usuários}} ($2).",
        "youhavenewmessagesmanyusers": "Você tem $1 de muitos usuários ($2).",
        "hidetoc": "ocultar",
        "collapsible-collapse": "Ocultar",
        "collapsible-expand": "Expandir",
-       "confirmable-confirm": "{{GENDER:$1|Tem}} certeza?",
+       "confirmable-confirm": "{{GENDER:$1|Tem}} certeza?",
        "confirmable-yes": "Sim",
        "confirmable-no": "Não",
        "thisisdeleted": "Ver ou restaurar $1?",
        "viewdeleted": "Ver $1?",
        "restorelink": "{{PLURAL:$1|uma edição eliminada|$1 edições eliminadas}}",
-       "feedlinks": "Feed:",
-       "feed-invalid": "Tipo inválido de inscrição de feeds.",
+       "feedlinks": "''Feed'':",
+       "feed-invalid": "Tipo inválido de inscrição de ''feed''.",
        "feed-unavailable": "Os \"feeds\" não se encontram disponíveis",
        "site-rss-feed": "Feed RSS $1",
        "site-atom-feed": "Feed Atom $1",
        "databaseerror-function": "Função: $1",
        "databaseerror-error": "Erro: $1",
        "transaction-duration-limit-exceeded": "Para evitar a criação de lag replicação alta, esta operação foi abortada porque a duração de gravação ($1) excedeu o limite de $2 {{PLURAL:$2|segundo|segundos}}. Se você está mudando muitos itens de uma vez, tente fazer várias operações menores em vez disso.",
-       "laggedslavemode": "Aviso: a página poderá não conter atualizações recentes.",
-       "readonly": "Banco de dados disponível no modo \"somente leitura\"",
+       "laggedslavemode": "<strong>Aviso:</strong> a página poderá não conter atualizações recentes.",
+       "readonly": "Banco de dados trancado",
        "enterlockreason": "Entre com um motivo para trancá-lo, incluindo uma estimativa de quando poderá novamente ser destrancado",
        "readonlytext": "O banco de dados está atualmente bloqueado para novos artigos e outras modificações, provavelmente por uma manutenção de rotina de banco de dados, após o que estará de volta ao normal.\n\nO administrador do sistema que fez o bloqueio oferece a seguinte explicação: $1",
        "missing-article": "O banco de dados não encontrou o texto de uma página que deveria ter encontrado, com o nome \"$1\" $2.\n\nIsso normalmente é causado ao acessar um link de diferença (dif) desatualizado ou para o histórico de uma página que foi apagada.\n\nSe este não for o caso, você pode ter encontrado um defeito (bug) no software.\nAnote a URL e reporte o ocorrido a um [[Special:ListUsers/sysop|administrador]].",
        "nonwrite-api-promise-error": "O cabeçalho HTTP \"Promise-Non-Write-API-Action\" foi enviado, mas a requisição era para um módulo de escrita de API.",
        "internalerror": "Erro interno",
        "internalerror_info": "Erro interno: $1",
-       "internalerror-fatal-exception": "Excepção fatal do tipo \"$1\"",
-       "filecopyerror": "Não foi possível copiar o arquivo \"$1\" para \"$2\".",
-       "filerenameerror": "Não foi possível renomear o arquivo \"$1\" para \"$2\".",
-       "filedeleteerror": "Não foi possível eliminar o arquivo \"$1\".",
-       "directorycreateerror": "Não foi possível criar o diretório \"$1\".",
-       "directoryreadonlyerror": "Diretorio \"$1\" é somente leitura.",
-       "directorynotreadableerror": "O diretório \"$1\" não é legível.",
-       "filenotfound": "Não foi possível encontrar o arquivo \"$1\".",
-       "unexpected": "Valor não esperado: \"$1\"=\"$2\".",
-       "formerror": "Erro: Não foi possível enviar o formulário",
+       "internalerror-fatal-exception": "Exceção fatal do tipo “$1”",
+       "filecopyerror": "Não foi possível copiar o arquivo “$1” para “$2”.",
+       "filerenameerror": "Não foi possível renomear o arquivo “$1” para “$2”.",
+       "filedeleteerror": "Não foi possível eliminar o arquivo “$1”.",
+       "directorycreateerror": "Não foi possível criar o diretório “$1”.",
+       "directoryreadonlyerror": "O diretorio “$1” é somente leitura.",
+       "directorynotreadableerror": "O diretório “$1”\" não é legível.",
+       "filenotfound": "Não foi possível encontrar o arquivo “$1”.",
+       "unexpected": "Valor não esperado: “$1”=“$2”.",
+       "formerror": "Erro: Não foi possível enviar o formulário.",
        "badarticleerror": "Esta ação não pode ser realizada nesta página.",
-       "cannotdelete": "Não foi possível eliminar a página ou arquivo $1.\nÉ possível que ele já tenha sido eliminado por outra pessoa.",
-       "cannotdelete-title": "Não é possível eliminar a página \"$1\"",
-       "delete-scheduled": "A página \"$1\" está agendada para eliminação.\nAguarde a mesma, por favor.",
-       "delete-hook-aborted": "A eliminação foi cancelada por um \"hook\".\nNão foi dada nenhuma explicação.",
-       "no-null-revision": "Não foi possível criar nova revisão nula para a página \"$1\"",
+       "cannotdelete": "Não foi possível eliminar a página ou arquivo “$1”.\nÉ possível que ele já tenha sido eliminado por outra pessoa.",
+       "cannotdelete-title": "Não é possível eliminar a página “$1”",
+       "delete-scheduled": "A página “$1” está agendada para eliminação.\nAguarde a mesma, por favor.",
+       "delete-hook-aborted": "A eliminação foi cancelada por um ''hook''.\nNão foi dada nenhuma explicação.",
+       "no-null-revision": "Não foi possível criar nova revisão nula para a página “$1”",
        "badtitle": "Título inválido",
        "badtitletext": "O título de página solicitado era inválido, vazio, ou um link interlínguas ou interwikis incorreto.\nTalvez contenha um ou mais caracteres que não podem ser usados em títulos.",
        "title-invalid-empty": "O título da página solicitada está vazio ou contém somente o nome do espaço de nomes.",
        "shown-title": "Mostrar $1 {{PLURAL:$1|resultado|resultados}} por página",
        "viewprevnext": "Ver ($1 {{int:pipe-separator}} $2) ($3)",
        "searchmenu-exists": "<strong>Há uma página com o nome \"[[:$1]]\" nesta wiki.</strong> {{PLURAL:$2|0=|Veja também os outros resultados da pesquisa encontrados.}}",
-       "searchmenu-new": "<strong>Criar a página \"[[:$1]]\" nesta wiki!</strong> {{PLURAL:$2|0=|Veja também a página encontrada com sua pesquisa.|Veja também os resultados da pesquisa encontrados.}}",
+       "searchmenu-new": "<strong>Crie a página “[[:$1]]” nesta wiki!</strong> {{PLURAL:$2|0=|Veja também a página encontrada com sua pesquisa.|Veja também os resultados da pesquisa encontrados.}}",
        "searchprofile-articles": "Páginas de conteúdo",
        "searchprofile-images": "Multimídia",
        "searchprofile-everything": "Tudo",
        "timezonelegend": "Fuso horário:",
        "localtime": "Horário local:",
        "timezoneuseserverdefault": "Utilizar padrão da wiki ($1)",
-       "timezoneuseoffset": "Outro (especificar desvio horário)",
+       "timezoneuseoffset": "Outro (especificar desvio horário abaixo)",
+       "timezone-useoffset-placeholder": "Exemplo de valores: \"-07:00\" ou \"01:00\"",
        "servertime": "Horário do servidor:",
        "guesstimezone": "Preencher a partir do navegador",
        "timezoneregion-africa": "África",
        "prefs-editor": "Editor",
        "prefs-preview": "Pré-visualizar",
        "prefs-advancedrc": "Opções avançadas",
-       "prefs-opt-out": "Excluir melhorias",
        "prefs-advancedrendering": "Opções avançadas",
        "prefs-advancedsearchoptions": "Opções avançadas",
        "prefs-advancedwatchlist": "Opções avançadas",
index 1559cb4..84c33e2 100644 (file)
        "prefs-editor": "Editor",
        "prefs-preview": "Antevisão",
        "prefs-advancedrc": "Opções avançadas",
-       "prefs-opt-out": "Excluir de melhoramentos",
        "prefs-advancedrendering": "Opções avançadas",
        "prefs-advancedsearchoptions": "Opções avançadas",
        "prefs-advancedwatchlist": "Opções avançadas",
index 182dc42..4cbe2e5 100644 (file)
        "edit-gone-missing": "Used as error message.\n\nSee also:\n* {{msg-mw|edit-hook-aborted}}\n* {{msg-mw|edit-conflict}}\n* {{msg-mw|edit-no-change}}\n* {{msg-mw|edit-already-exists}}",
        "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.\n\nSee also:\n* {{msg-mw|edit-hook-aborted}}\n* {{msg-mw|edit-gone-missing}}\n* {{msg-mw|edit-no-change}}\n* {{msg-mw|edit-already-exists}}",
        "edit-no-change": "Used as error message.\n\nSee also:\n* {{msg-mw|edit-hook-aborted}}\n* {{msg-mw|edit-gone-missing}}\n* {{msg-mw|edit-conflict}}\n* {{msg-mw|edit-already-exists}}",
+       "edit-slots-cannot-add": "An error message shown when trying to save an edit, if the edit tries to add a {{Identical|slot}} that is not allowed on the page.\n* $1 - the number of slots\n* $2 - the slots that were attempted to be added but are not allowed",
+       "edit-slots-cannot-remove": "An error message shown when trying to save an edit, if the edit tries to remove a {{Identical|slot}} that is required on the page.\n* $1 - the number of slots\n* $2 - the slots that were attempted to be removed but are required",
+       "edit-slots-missing": "An error message shown when trying to save an edit, if the edit is missing some required {{Identical|slot}}, which could not be inherited from a parent revision.\n* $1 - the number of slots\n* $2 - the slots that are required but missing from the new revision",
        "postedit-confirmation-created": "{{gender}}\nShown after a user creates a new page. Parameters:\n* $1 - the current user, for GENDER support",
        "postedit-confirmation-restored": "{{gender}}\nShown after a user restores a page to a previous revision. Parameters:\n* $1 - the current user, for GENDER support",
        "postedit-confirmation-saved": "{{gender}}\nShown after a user saves a page. Parameters:\n* $1 - the current user, for GENDER support",
        "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.\n\nParameters:\n* $1 – content model, any one of the following messages:\n** {{msg-mw|Content-model-wikitext}}\n** {{msg-mw|Content-model-javascript}}\n** {{msg-mw|Content-model-css}}\n** {{msg-mw|Content-model-json}}\n** {{msg-mw|Content-model-text}}\n* $2 – content format as MIME type (e.g. <code>text/css</code>)\n* $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.\n* $1 - the human readable name of the content model: {{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-json}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}\n* $2 - the title of the page in question",
+       "content-not-allowed-here": "Error message indicating that the desired content model is not supported in given localtion.\n* $1 - the human readable name of the content model: {{msg-mw|Content-model-wikitext}}, {{msg-mw|Content-model-javascript}}, {{msg-mw|Content-model-json}}, {{msg-mw|Content-model-css}} or {{msg-mw|Content-model-text}}\n* $2 - the title of the page in question\n* $3 - the role name of the slot the content is not allowed in",
        "editwarning-warning": "Uses {{msg-mw|Prefs-editing}}",
        "editpage-invalidcontentmodel-title": "Title of error page shown when using an unrecognized content model on EditPage",
        "editpage-invalidcontentmodel-text": "Error message shown when using an unrecognized content model on EditPage. $1 is the user's invalid input",
        "localtime": "Used as label in [[Special:Preferences#mw-prefsection-datetime|preferences]].",
        "timezoneuseserverdefault": "[[Special:Preferences]] > Date and time > Time zone\n\nThis option lets your time zone setting use the one that is used on the wiki (often UTC).\n\nParameters:\n* $1 - timezone name, or timezone offset (in \"%+03d:%02d\" format)",
        "timezoneuseoffset": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.",
+       "timezone-useoffset-placeholder": "Used in \"Time zone\" text input field as placeholder in [[Special:Preferences#mw-prefsection-datetime|preferences]]",
        "servertime": "Used as label in [[Special:Preferences#mw-prefsection-datetime|preferences]].",
        "guesstimezone": "Option to fill in the timezone from the browser setting",
        "timezoneregion-africa": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
        "prefs-editor": "Used in [[Special:Preferences]], tab \"Editing\" ({{int:prefs-editing}}).\n\n{{Identical|Editor}}",
        "prefs-preview": "Used in [[Special:Preferences]], tab \"Editing\".\n{{Identical|Preview}}",
        "prefs-advancedrc": "Used in [[Special:Preferences]], tab \"Recent changes\".\n{{Identical|Advanced options}}",
-       "prefs-opt-out": "Used in [[Special:Preferences]], tabs \"Recent changes\" and \"Watchlist\".",
        "prefs-advancedrendering": "Used in [[Special:Preferences]], tab \"Appearence\".\n{{Identical|Advanced options}}",
        "prefs-advancedsearchoptions": "Used in [[Special:Preferences]], tab \"Search options\".\n{{Identical|Advanced options}}",
        "prefs-advancedwatchlist": "Used in [[Special:Preferences]], tab \"Watchlist\".\n{{Identical|Advanced options}}",
index 7e22928..cf548cc 100644 (file)
        "passwordtooshort": "Parola trebuie să aibă cel puțin {{PLURAL:$1|1 caracter|$1 caractere|$1 de caractere}}.",
        "passwordtoolong": "Parolele nu pot fi mai lungi de {{PLURAL:$1|un caracter|$1 caractere|$1 de caractere}}.",
        "passwordtoopopular": "Parolele comune nu pot fi utilizate. Alegeți o parolă mai greu de ghicit.",
+       "passwordinlargeblacklist": "Parola introdusă este inclusă într-o listă de parole des folosite. Vă rugăm să alegeți o parolă diferită.",
        "password-name-match": "Parola dumneavoastră trebuie să fie diferită de numele de utilizator.",
        "password-login-forbidden": "Utilizarea acestui nume de utilizator și a acestei parole este interzisă.",
        "mailmypassword": "Resetează parola",
        "prefs-editor": "Editor",
        "prefs-preview": "Previzualizare",
        "prefs-advancedrc": "Opțiuni avansate",
-       "prefs-opt-out": "Dezactivați îmbunătățirile",
        "prefs-advancedrendering": "Opțiuni avansate",
        "prefs-advancedsearchoptions": "Opțiuni avansate",
        "prefs-advancedwatchlist": "Opțiuni avansate",
        "prefs-displayrc": "Opțiuni de afișare",
        "prefs-displaywatchlist": "Opțiuni de afișare",
+       "prefs-pageswatchlist": "Pagini urmărite",
        "prefs-tokenwatchlist": "Jeton",
        "prefs-diffs": "Diferențe",
        "prefs-help-prefershttps": "Această preferință va avea efect la următoarea autentificare.",
index a3b97b9..1c7ea98 100644 (file)
        "passwordtooshort": "Le password onne a essere almene {{PLURAL:$1|1 carattere|$1 carattere}}.",
        "passwordtoolong": "Le password non ge ponne essere cchiù longhe de {{PLURAL:$1|1 carattere}}.",
        "passwordtoopopular": "Password comuni non ge ponne essere ausate. Scacchie 'na password cchiù difficile da 'nduvenà.",
+       "passwordinlargeblacklist": "'A passuord mise ste jndr'à l'elenghe de le passuord ausate de cchiù. Pe piacere scacchie 'na passuord cchiù secure.",
        "password-name-match": "'A password toje adda essere diverse da 'u nome utende tue.",
        "password-login-forbidden": "L'ause de stu nome utende e passuord onne state vietate.",
        "mailmypassword": "Azzere 'a passuord",
        "changepassword-throttled": "Tu è pruvate 'nu sacche de vote a trasè.\nPe piacere aspitte $1 apprime de pruvà arrete.",
        "botpasswords": "Password d'u bot",
        "botpasswords-disabled": "Le passuord bot so disabbilitate.",
+       "botpasswords-no-central-id": "Pe ausà 'na passuor bot, a trasè a 'nu utende cendralizzate.",
        "botpasswords-existing": "Passuord de le bot esistende",
        "botpasswords-createnew": "Ccreje 'na passuord nove pu bot",
        "botpasswords-editexisting": "Cange 'na passuord d'u bot ca esiste ggià",
        "timezonelegend": "Orarie d'a zone:",
        "localtime": "Orarie lochele:",
        "timezoneuseserverdefault": "Ause 'u valore de default de uicchi ($1)",
-       "timezoneuseoffset": "Otre (specifiche 'a distanze)",
+       "timezoneuseoffset": "Otre (specifiche 'a distanze aqqà sotte)",
+       "timezone-useoffset-placeholder": "Valore de esembie: \"-07:00\" o \"01:00\"",
        "servertime": "Orarie d'u server:",
        "guesstimezone": "Jnghie da 'u browser",
        "timezoneregion-africa": "Africa",
        "timezoneregion-indian": "Oceano Indiane",
        "timezoneregion-pacific": "Oceano Pacifiche",
        "allowemail": "Abbilite l'otre utinde a mannarme 'na mail",
+       "email-allow-new-users-label": "Permette email da utinde nuève",
        "prefs-searchoptions": "Cirche",
        "prefs-namespaces": "Namespaces",
        "default": "defolt",
        "prefs-editor": "Cangiatore",
        "prefs-preview": "Andeprime",
        "prefs-advancedrc": "Opzione avanzate",
-       "prefs-opt-out": "Disattivazzione de le miglioraminde",
        "prefs-advancedrendering": "Opzione avanzate",
        "prefs-advancedsearchoptions": "Opzione avanzate",
        "prefs-advancedwatchlist": "Opzione avanzate",
        "booksources-search": "Cirche",
        "booksources-text": "Sotte stè 'na liste de collegaminde a otre site ca vennene libbre nuève e ausete e puà pure acchià cchiù 'mbormaziune sus a le libbre ca tu ste cirche:",
        "booksources-invalid-isbn": "L'ISBN ca è mise non ge pare ca ète corrette; verifiche ce è commesse quacche errore quanne ste cupiave quidde origginale.",
+       "magiclink-tracking-rfc": "Pàggene ca ausane le collegaminde maggece RFC",
+       "magiclink-tracking-pmid": "Pàggene ca ausane le collegaminde maggece PMID",
+       "magiclink-tracking-isbn": "Pàggene ca ausane le collegaminde maggece ISBN",
        "specialloguserlabel": "'Mblemendatore:",
        "speciallogtitlelabel": "Destinazione (titole o {{ns:user}}:nome de l'utende pe l'utende):",
        "log": "Archivije",
        "confirm-unwatch-button": "OK",
        "confirm-unwatch-top": "Vuè ccu live sta pàgene da chidde condrollate?",
        "confirm-rollback-button": "OK",
+       "confirm-mcrrestore-title": "Repristine 'a revisione",
        "confirm-mcrundo-title": "Annulle 'u cangiamende",
        "mcrundofailed": "Annullamende fallite",
        "semicolon-separator": ";&#32;",
        "tag-mw-contentmodelchange-description": "Cangiaminde ca [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel cangiane 'u modelle de le condenute] de 'na pàgene",
        "tag-mw-new-redirect": "Reindirizzamende nuève",
        "tag-mw-replace": "Sostituite",
+       "tag-mw-rollback": "Annulle",
        "tag-mw-undo": "Annulle",
        "tags-title": "Tag",
        "tags-intro": "Sta pàgene elenghe le tag ca 'u software pò marcà cu 'nu cangiamende e 'u lore significate.",
        "log-action-filter-newusers-create": "Ccrejazzione da 'utende senza nome",
        "log-action-filter-newusers-create2": "Ccrejazzione da 'utende reggistrate",
        "log-action-filter-newusers-autocreate": "Ccrejazione automateche",
+       "log-action-filter-protect-protect": "Protezzione",
+       "log-action-filter-protect-modify": "Cangiamende d'a protezzione",
+       "log-action-filter-protect-unprotect": "Sprotette",
+       "log-action-filter-protect-move_prot": "Protezzione spustate",
        "log-action-filter-rights-rights": "Cangiamende a màne",
        "log-action-filter-rights-autopromote": "Cangiamende automateche",
        "log-action-filter-suppress-event": "Soppressione de l'archivije",
index b34945e..73e36c1 100644 (file)
        "passwordtooshort": "Пароль должен состоять не менее, чем из $1 {{PLURAL:$1|символа|символов}}.",
        "passwordtoolong": "Пароль не может содержать более {{PLURAL:$1|1=$1 символа|$1 символов}}.",
        "passwordtoopopular": "Часто выбираемые пароли не могут быть использованы. Пожалуйста, выберите пароль, который сложнее угадать.",
+       "passwordinlargeblacklist": "Введённый пароль является одним из часто используемых. Пожалуйста, выберите другой.",
        "password-name-match": "Введённый пароль должен отличаться от имени участника.",
        "password-login-forbidden": "Использование этого имени участника и пароля запрещено.",
        "mailmypassword": "Сбросить пароль",
        "timezonelegend": "Часовой пояс:",
        "localtime": "Местное время:",
        "timezoneuseserverdefault": "Использовать настройки сервера ($1)",
-       "timezoneuseoffset": "Иное (укажите смещение)",
+       "timezoneuseoffset": "Иное (ниже укажите смещение)",
+       "timezone-useoffset-placeholder": "Например: «-07:00» или «01:00»",
        "servertime": "Время сервера:",
        "guesstimezone": "Заполнить из браузера",
        "timezoneregion-africa": "Африка",
        "prefs-editor": "Редактор",
        "prefs-preview": "Предварительный просмотр",
        "prefs-advancedrc": "Расширенные настройки",
-       "prefs-opt-out": "Отказ от улучшений",
        "prefs-advancedrendering": "Расширенные настройки",
        "prefs-advancedsearchoptions": "Расширенные настройки",
        "prefs-advancedwatchlist": "Расширенные настройки",
        "right-block": "Блокировка редактирования другими участниками",
        "right-blockemail": "Блокировка на отправку электронной почты",
        "right-hideuser": "Запрет имени участника и его сокрытие",
-       "right-ipblock-exempt": "обход блокировок по IP, автоблокировок и блокировок диапазонов",
+       "right-ipblock-exempt": "Ð\9eбход блокировок по IP, автоблокировок и блокировок диапазонов",
        "right-unblockself": "Разблокирование себя самого",
        "right-protect": "Изменение уровня защиты страниц и правка каскадно защищённых страниц",
        "right-editprotected": "Правка страниц, защищённых как «{{int:protect-level-sysop}}»",
        "listgrouprights-members": "(список участников)",
        "listgrouprights-right-display": "<span class=\"listgrouprights-granted\">$1 (<code>$2</code>)</span>",
        "listgrouprights-right-revoked": "<span class=\"listgrouprights-revoked\">$1 (<code>$2</code>)</span>",
-       "listgrouprights-addgroup": "добавление в {{PLURAL:$2|1=группу|группы}}: $1",
-       "listgrouprights-removegroup": "исключение из {{PLURAL:$2|1=группы|групп}}: $1",
-       "listgrouprights-addgroup-all": "добавление во все группы",
-       "listgrouprights-removegroup-all": "исключение из всех групп",
+       "listgrouprights-addgroup": "Ð\94обавление в {{PLURAL:$2|1=группу|группы}}: $1",
+       "listgrouprights-removegroup": "Ð\98сключение из {{PLURAL:$2|1=группы|групп}}: $1",
+       "listgrouprights-addgroup-all": "Ð\94обавление во все группы",
+       "listgrouprights-removegroup-all": "Ð\98сключение из всех групп",
        "listgrouprights-addgroup-self": "добавление своей учётной записи в {{PLURAL:$2|1=группу|группы}}: $1",
-       "listgrouprights-removegroup-self": "исключение своей учётной записи из {{PLURAL:$2|1=группы|групп}}: $1",
+       "listgrouprights-removegroup-self": "Ð\98сключение своей учётной записи из {{PLURAL:$2|1=группы|групп}}: $1",
        "listgrouprights-addgroup-self-all": "Может добавлять все группы к своей учётной записи",
        "listgrouprights-removegroup-self-all": "может удалять все группы со своей учётной записи",
        "listgrouprights-namespaceprotection-header": "Ограничения пространства имён",
        "tooltip-whatlinkshere-invert": "Установите этот флажок, чтобы Скрыть ссылки от страниц в выбранном пространстве имен.",
        "namespace_association": "Связанное пространство",
        "tooltip-namespace_association": "Установите эту отметку, чтобы также включить пространство имён обсуждения (или предметное), связанное с выбранным пространством имён",
-       "blanknamespace": "(основное)",
+       "blanknamespace": "(Ð\9eсновное)",
        "contributions": "Вклад {{GENDER:$1|участника|участницы}}",
        "contributions-title": "Вклад {{GENDER:$1|участника|участницы}} $1",
        "mycontris": "Вклад",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Пароль не может совпадать ни с одним паролем, внесённым в чёрный список",
        "passwordpolicies-policy-maximalpasswordlength": "Пароль должен быть короче $1 {{PLURAL:$1|символа|символов}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Пароль не может соответствовать {{PLURAL:$1|самому часто используемому паролю|какому-либо из $1 самых часто используемых паролей}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Пароль не может соответствовать какому-либо из 100 000 самых часто используемых паролей.",
        "easydeflate-invaliddeflate": "Предоставленное содержимое не спущено надлежащим образом",
        "unprotected-js": "По соображениям безопасности JavaScript нельзя загружать с незащищенных страниц. Пожалуйста, создавайте скрипты только в пространстве имён MediaWiki: или как подстраницы участника."
 }
index 6e8fad7..790adba 100644 (file)
        "prefs-editor": "Эрэдээктэр",
        "prefs-preview": "Инники көрүү",
        "prefs-advancedrc": "Дириҥэтиллибит туруоруулар",
-       "prefs-opt-out": "Тупсарыыттан батыныы",
        "prefs-advancedrendering": "Дириҥэтиллибит туруоруулар",
        "prefs-advancedsearchoptions": "Дириҥэтиллибит туруоруулар",
        "prefs-advancedwatchlist": "Дириҥэтиллибит туруоруулар",
index 8f166b7..dcbd6f7 100644 (file)
        "grant-uploadfile": "လူတ်ႇၶိုၼ်ႈ ၾၢႆႇဢၼ်မႂ်ႇ",
        "grant-basic": "သုၼ်ႇပိုၼ်ႉထၢၼ်",
        "grant-viewdeleted": "တူၺ်း ၾၢႆႇလႄႈ ၼႃႈလိၵ်ႈ ၸိူဝ်းမွတ်ႇပႅတ်ႈယဝ်ႉ။",
-       "grant-viewmywatchlist": "တူၺ်း သဵၼ်ႈမၢႆပႂ်ႉတူၺ်း ႁင်းၶွင်ၵဝ်ႇ",
+       "grant-viewmywatchlist": "á\80\90á\80°á\81ºá\80ºá\80¸ á\80\9eá\80µá\81¼á\80ºá\82\88á\80\99á\81¢á\82\86á\80\95á\82\82á\80ºá\82\89á\80\90á\80°á\81ºá\80ºá\80¸ á\82\81á\80\84á\80ºá\80¸á\81¶á\80½á\80\84á\80ºá\81¸á\80\9dá\80ºá\82\88á\81µá\80\9dá\80ºá\82\87",
        "newuserlogpage": "သၢႆမၢႆလွင်ႈၵေႃႇသၢင်ႈ ၽူႈၸႂ်ႉတိုဝ်း",
        "newuserlogpagetext": "ဢၼ်ၼႆႉပဵၼ် သဵၼ်ႈမၢႆ လွင်ႈၵေႃႇသၢင်ႈ ၽူႈၸႂ်ႉတိုဝ်း။",
        "rightslog": "သဵၼ်ႈမၢႆ သုၼ်ႇလႆႈ ၽူႈၸႂ်ႉတိုဝ်း",
index 1890bf8..cf33426 100644 (file)
        "prefs-editor": "Používateľ",
        "prefs-preview": "Náhľad",
        "prefs-advancedrc": "Rozšírené možnosti",
-       "prefs-opt-out": "Nepoužívať vylepšenia",
        "prefs-advancedrendering": "Rozšírené možnosti",
        "prefs-advancedsearchoptions": "Rozšírené možnosti",
        "prefs-advancedwatchlist": "Rozšírené možnosti",
index d3fa68b..aa8f6ee 100644 (file)
        "timezonelegend": "Časovni pas",
        "localtime": "Krajevni čas:",
        "timezoneuseserverdefault": "Uporabi privzeti wiki čas ($1)",
-       "timezoneuseoffset": "Drugo (navedite izravnavo)",
+       "timezoneuseoffset": "Drugo (spodaj navedite odmik)",
+       "timezone-useoffset-placeholder": "Primera vrednosti: »-07:00« ali »01:00«",
        "servertime": "Strežniški čas:",
        "guesstimezone": "Izpolni iz brskalnika",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Urejevalnik",
        "prefs-preview": "Predogled",
        "prefs-advancedrc": "Napredne možnosti",
-       "prefs-opt-out": "Izključite se iz izboljšav",
        "prefs-advancedrendering": "Napredne možnosti",
        "prefs-advancedsearchoptions": "Napredne možnosti",
        "prefs-advancedwatchlist": "Napredne možnosti",
index edcb84a..0290b54 100644 (file)
        "navigation-heading": "Мени за навигацију",
        "errorpagetitle": "Грешка",
        "returnto": "Назад на страницу „$1”.",
-       "tagline": "Извор: {{SITENAME}}",
+       "tagline": "Из {{GRAMMAR:генитив|{{SITENAME}}}}",
        "help": "Помоћ",
        "search": "Претрага",
        "search-ignored-headings": " #<!-- не мењајте ништа у овом реду --> <pre>\n# Наслови који ће бити занемарени при претрази.\n# Промене су видљиве одмах након што се страница са насловом индексира.\n# Можете изнудити поновно индексирање „нултом” изменом.\n# Синтакса је следећа:\n#  * Сваки ред који започиње знаком „#” је коментар.\n#  * Сваки не празни ред је тачан наслов који ће бити занемарен, с тим да се разликују мала и велика слова и све остало\nРеференце\nСпољашње везе\nТакође погледајте\n #</pre> <!-- не мењајте ништа у овом реду -->",
        "lastmodifiedat": "Ова страница је последњи пут уређена на датум $1 у $2 ч.",
        "viewcount": "Овој страници је приступљено {{PLURAL:$1|једанпут|$1 пута}}.",
        "protectedpage": "Заштићена страница",
-       "jumpto": "Ð\98ди на:",
+       "jumpto": "Ð\9fÑ\80еÑ\92и на:",
        "jumptonavigation": "навигацију",
        "jumptosearch": "претрагу",
        "view-pool-error": "Сервери су тренутно преоптерећени.\nПревише корисника покушава да види ову страницу.\nСачекајте неко време пре него што поново покушате да јој приступите.\n\n$1",
        "pool-errorunknown": "Непозната грешка",
        "pool-servererror": "Услуга бројача редова није доступна ($1).",
        "poolcounter-usage-error": "Грешка при употреби: $1",
-       "aboutsite": "О пројекту {{SITENAME}}",
-       "aboutpage": "Project:О_пројекту_{{SITENAME}}",
+       "aboutsite": "О {{GRAMMAR:датив|{{SITENAME}}}}",
+       "aboutpage": "Project:О_{{GRAMMAR:датив|{{SITENAME}}}}",
        "copyright": "Садржај је доступан под лиценцом $1 осим ако је другачије наведено.",
        "copyrightpage": "{{ns:project}}:Ауторска права",
        "currentevents": "Актуелности",
        "password-change-forbidden": "Не можете да промените лозинку на овом викију.",
        "externaldberror": "Дошло је до грешке при потврди идентитета базе података или вам није дозвољено да ажурирате свој спољни налог.",
        "login": "Пријава",
-       "login-security": "Ð\9fоÑ\82вÑ\80да Ð²Ð°Ñ\88ег индентитета",
+       "login-security": "Ð\92еÑ\80иÑ\84икаÑ\86иÑ\98а индентитета",
        "nav-login-createaccount": "Пријавите се / отворите налог",
        "logout": "Одјава",
        "userlogout": "Одјава",
        "notloggedin": "Нисте пријављени",
        "userlogin-noaccount": "Немате налог?",
-       "userlogin-joinproject": "Придружите се пројекту {{SITENAME}}",
+       "userlogin-joinproject": "Придружите се {{GRAMMAR:датив|{{SITENAME}}}}",
        "createaccount": "Отварање налога",
        "userlogin-resetpassword-link": "Заборавили сте лозинку?",
        "userlogin-helplink2": "Помоћ при пријављивању",
        "userlogin-loggedin": "Већ сте пријављени као {{GENDER:$1|$1}}.\nКористите доњи образац да бисте се пријавили као други корисник.",
-       "userlogin-reauth": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ñ\81е Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ñ\80иÑ\98авиÑ\82е Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð¿Ð¾Ñ\82вÑ\80дили да сте {{GENDER:$1|$1}}.",
+       "userlogin-reauth": "Ð\9cоÑ\80аÑ\82е Ð´Ð° Ñ\81е Ð¿Ð¾Ð½Ð¾Ð²Ð¾ Ð¿Ñ\80иÑ\98авиÑ\82е Ð´Ð° Ð±Ð¸Ñ\81Ñ\82е Ð²ÐµÑ\80иÑ\84иковали да сте {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Отвори још један налог",
        "createacct-emailrequired": "Имејл-адреса",
        "createacct-emailoptional": "Имејл-адреса (опционално)",
        "passwordtooshort": "Лозинка мора имати најмање {{PLURAL:$1|један знак|$1 знака|$1 знакова}}.",
        "passwordtoolong": "Лозинке не могу бити дуже од {{PLURAL:$1|$1 знака|$1 знакова}}.",
        "passwordtoopopular": "Није могуће користити често одабране лозинке. Одаберите лозинку коју је теже погодити.",
+       "passwordinlargeblacklist": "Унесена лозинка је на листи веома често коришћених лозинки. Одаберите јединственију лозинку.",
        "password-name-match": "Лозинка се мора разликовати од корисничког имена.",
        "password-login-forbidden": "Коришћење овог корисничког имена и лозинке је забрањено.",
        "mailmypassword": "Ресетуј лозинку",
-       "passwordremindertitle": "{{SITENAME}} — привремена лозинка",
+       "passwordremindertitle": "Нова привремена лозинка за {{GRAMMAR:акузатив|{{SITENAME}}}}",
        "passwordremindertext": "Неко са IP адресе $1 је затражио нову лозинку на викију {{SITENAME}} ($4).\nСтворена је привремена лозинка за {{GENDER:$2|корисника|корисницу|корисника}} $2 која гласи $3.\nУколико је ово ваш захтев, сада се пријавите и поставите нову лозинку.\nПривремена лозинка истиче за {{PLURAL:$5|један дан|$5 дана}}.\n\nАко је неко други затражио промену лозинке, или сте се сетили ваше лозинке и не желите да је мењате, занемарите ову поруку.",
        "noemail": "Не постоји имејл-адреса за {{GENDER:$1|корисника|корисницу}} $1.",
        "noemailcreate": "Морате да наведете важећу имејл-адресу.",
        "updated": "(ажурирано)",
        "note": "<strong>Напомена:</strong>",
        "previewnote": "<strong>Не заборавите да је ово само претпреглед.</strong>\nВаше промене још нису сачуване!",
-       "continue-editing": "Ð\98ди Ð½Ð° Ñ\83Ñ\80еÑ\92иваÑ\87ки Ð¾ÐºÐ²Ð¸Ñ\80",
+       "continue-editing": "Ð\9fÑ\80еÑ\92и Ð½Ð° Ð¾Ð±Ð°Ñ\81Ñ\82 Ñ\83Ñ\80еÑ\92иваÑ\9aа",
        "previewconflict": "Овај преглед осликава како ће изгледати текст у текстуалном оквиру.",
        "session_fail_preview": "Извињавамо се! Нисмо могли да обрадимо вашу измену због губитка података сесије.\n\nМожда сте одјављени. <strong>Проверите да ли сте пријављени и покушајте поново</strong>.\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите, те проверите да ли су на вашем претраживачу дозвољени колачићи са овог сајта.",
        "session_fail_preview_html": "Нисмо могли да обрадимо вашу измену због губитка података сесије.\n\n<em>Будући да је на овом викију омогућен унос HTML ознака, преглед је сакривен као мера предострожности против напада преко јаваскрипта.</em>\n\n<strong>Ако сте покушали да направите праву измену, покушајте поново.<strong>\nАко и даље не ради, покушајте да се [[Special:UserLogout|одјавите]] и поново пријавите и проверите да ли ваш прегледач дозвољава колачиће са овог сајта.",
        "prefs-watchlist": "Списак надгледања",
        "prefs-editwatchlist": "Уређивање списка надгледања",
        "prefs-editwatchlist-label": "Уреди уносе на списку надгледања:",
-       "prefs-editwatchlist-edit": "пÑ\80икажи Ð¸ Ñ\83клони Ð½Ð°Ñ\81лове са списка надгледања",
-       "prefs-editwatchlist-raw": "уреди необрађени списак надгледања",
-       "prefs-editwatchlist-clear": "оÑ\87иÑ\81Ñ\82и Ñ\81пиÑ\81ак надгледања",
+       "prefs-editwatchlist-edit": "Ð\9fÑ\80иказ Ð¸ Ñ\83клаÑ\9aаÑ\9aе Ð½Ð°Ñ\81лова са списка надгледања",
+       "prefs-editwatchlist-raw": "Уређивање необрађеног списка надгледања",
+       "prefs-editwatchlist-clear": "ЧиÑ\88Ñ\9bеÑ\9aе Ñ\81пиÑ\81ка надгледања",
        "prefs-watchlist-days": "Број дана у списку надгледања:",
        "prefs-watchlist-days-max": "Највише $1 {{PLURAL:$1|дан|дана|дана}}",
        "prefs-watchlist-edits": "Највећи број промена приказаних на списку надгледања:",
        "prefs-watchlist-edits-max": "Највећи број: 1000",
        "prefs-watchlist-token": "Токен списка надгледања:",
-       "prefs-watchlist-managetokens": "УпÑ\80авÑ\99аÑ\98 токенима",
+       "prefs-watchlist-managetokens": "УпÑ\80авÑ\99аÑ\9aе токенима",
        "prefs-misc": "Разно",
-       "prefs-resetpass": "пÑ\80омени Ð»Ð¾Ð·Ð¸Ð½ÐºÑ\83",
-       "prefs-changeemail": "Ð\9fÑ\80омени Ð¸Ð»Ð¸ Ñ\83клони Ð¸Ð¼ÐµÑ\98л-адÑ\80еÑ\81Ñ\83",
-       "prefs-setemail": "Постави имејл-адресу",
+       "prefs-resetpass": "Ð\9fÑ\80омена Ð»Ð¾Ð·Ð¸Ð½ÐºÐµ",
+       "prefs-changeemail": "Ð\9fÑ\80омена Ð¸Ð»Ð¸ Ñ\83клаÑ\9aаÑ\9aе Ð¸Ð¼ÐµÑ\98л-адÑ\80еÑ\81е",
+       "prefs-setemail": "Постављање имејл-адресе",
        "prefs-email": "Опције имејла",
        "prefs-rendering": "Изглед",
        "saveprefs": "Сачувај",
        "searchresultshead": "Претрага",
        "stub-threshold": "Праг за форматирање веза као клице ($1):",
        "stub-threshold-sample-link": "пример",
-       "stub-threshold-disabled": "онемогућено",
+       "stub-threshold-disabled": "Ð\9eнемогућено",
        "recentchangesdays": "Број дана у скорашњим изменама:",
        "recentchangesdays-max": "Највише $1 {{PLURAL:$1|дан|дана}}",
        "recentchangescount": "Подразумевани број измена за приказ у скорашњим изменама, историјама страница и дневницима:",
        "savedrights": "Корисничке групе {{GENDER:$1|корисника|кориснице}} $1 су сачуване.",
        "timezonelegend": "Временска зона:",
        "localtime": "Локално време:",
-       "timezoneuseserverdefault": "подразумеване вредности ($1)",
-       "timezoneuseoffset": "друго (унесите одступање)",
+       "timezoneuseserverdefault": "Користи подразумеване вредности викија ($1)",
+       "timezoneuseoffset": "Друго (наведите одступање испод)",
+       "timezone-useoffset-placeholder": "Примери вредности: „-07:00” или „01:00”",
        "servertime": "Време на серверу:",
-       "guesstimezone": "попуни из прегледача",
+       "guesstimezone": "Ð\9fопуни из прегледача",
        "timezoneregion-africa": "Африка",
        "timezoneregion-america": "Америка",
        "timezoneregion-antarctica": "Антарктик",
        "email-blacklist-label": "Забрани примање имејлова од следећих корисника:",
        "prefs-searchoptions": "Претрага",
        "prefs-namespaces": "Именски простори",
-       "default": "подÑ\80азÑ\83мевана",
+       "default": "подÑ\80азÑ\83мевано",
        "prefs-files": "Датотеке",
        "prefs-custom-css": "прилагођени CSS",
        "prefs-custom-json": "Прилагођени JSON",
        "prefs-custom-js": "прилагођени JavaScript",
-       "prefs-common-config": "Дељени CSS/JSON/јаваскрипт за све теме:",
+       "prefs-common-config": "Дељени CSS/JSON/JavaScript за све теме:",
        "prefs-reset-intro": "Можете користити ову страницу да поново поставите своја подешавања на подразумеване вредности сајта.\nОво се не може опозвати.",
        "prefs-emailconfirm-label": "Потврда имејла:",
        "youremail": "Имејл:",
        "prefs-help-realname": "Право име је опционално.\nАко је наведено, биће коришћено за приписивање вашег рада.",
        "prefs-help-email": "Имејл адреса је опционална, али је потребна за ресетовање лозинке, ако је заборавите.",
        "prefs-help-email-others": "Такође можете изабрати да допустите другима да вас контактирају преко имејла путем везе на вашој корисничкој страници или страници за разговор.\nВаша имејл адреса неће бити приказана другим корисницима који вас контактирају.",
-       "prefs-help-email-required": "Ð\98меÑ\98л-адÑ\80еÑ\81а Ñ\98е Ð½ÐµÐ¾Ð¿Ñ\85одна.",
+       "prefs-help-email-required": "Ð\9fоÑ\82Ñ\80ебна Ñ\98е Ð¸Ð¼ÐµÑ\98л-адÑ\80еÑ\81а.",
        "prefs-info": "Основне информације",
        "prefs-i18n": "Интернационализација",
        "prefs-signature": "Потпис",
        "prefs-editor": "Уређивач",
        "prefs-preview": "Претпреглед",
        "prefs-advancedrc": "Напредне опције",
-       "prefs-opt-out": "Онемогућавање побољшања",
        "prefs-advancedrendering": "Напредне опције",
        "prefs-advancedsearchoptions": "Напредне опције",
        "prefs-advancedwatchlist": "Напредне опције",
        "tooltip-ca-move": "Преместите ову страницу",
        "tooltip-ca-watch": "Додајте ову страницу на списак надгледања",
        "tooltip-ca-unwatch": "Уклоните ову страницу са списка надгледања",
-       "tooltip-search": "Претражите пројекат {{SITENAME}}",
+       "tooltip-search": "Претражите {{GRAMMAR:акузатив|{{SITENAME}}}}",
        "tooltip-search-go": "Идите на страницу са тачно овим именом ако постоји",
        "tooltip-search-fulltext": "Претражите странице са овим текстом",
        "tooltip-p-logo": "Посетите главну страну",
        "imgmultipageprev": "← претходна страница",
        "imgmultipagenext": "следећа страница →",
        "imgmultigo": "Иди!",
-       "imgmultigoto": "Ð\98ди на страницу $1",
+       "imgmultigoto": "Ð\9fÑ\80еÑ\92и на страницу $1",
        "img-lang-opt": "$2 ($1)",
        "img-lang-default": "(подразумевани језик)",
        "img-lang-info": "Рендеруј ову слику у $1. $2",
        "diff-form-submit": "Прикажи разлике",
        "permanentlink": "Трајна веза",
        "permanentlink-revid": "ID измене",
-       "permanentlink-submit": "Ð\98ди на измену",
+       "permanentlink-submit": "Ð\9fÑ\80еÑ\92и на измену",
        "dberr-problems": "Дошло је до техничких проблема.",
        "dberr-again": "Сачекајте неколико минута и поново учитајте страницу.",
        "dberr-info": "(Не могу приступити бази података: $1)",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Лозинка се не може подударати са лозинкама на црном списку",
        "passwordpolicies-policy-maximalpasswordlength": "Лозинка мора да буде краћа од $1 {{PLURAL:$1|знака|знакова}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Лозинка не може да буде {{PLURAL:$1|популарна лозинка|на списку $1 популарних лозинки}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Лозинка не може да буде на листи 100.000 најчешће коришћених лозинки.",
        "unprotected-js": "Из безбедносних разлога, JavaScript не може да се учита са незаштићене странице. Само направите JavaScript у именском простору „Медијавики:” или као корисничку подстраницу"
 }
index eae87b8..fea088f 100644 (file)
@@ -38,7 +38,7 @@
        "tog-underline": "Podvlačenje veza:",
        "tog-hideminor": "Sakrij manje izmene sa spiska skorašnjih izmena",
        "tog-hidepatrolled": "Sakrij patrolirane izmene sa spiska skorašnjih izmena",
-       "tog-newpageshidepatrolled": "Sakrij patrolirane stranice sa liste novih stranica",
+       "tog-newpageshidepatrolled": "Sakrij patrolirane stranice sa spiska novih stranica",
        "tog-hidecategorization": "Sakrij kategorizaciju stranica",
        "tog-extendwatchlist": "Proširi spisak nadgledanja za prikaz svih promena, ne samo nedavnih",
        "tog-usenewrc": "Grupiši promene po stranici u skorašnjim izmenama i spisku nadgledanja",
        "newwindow": "(otvara se u novom prozoru)",
        "cancel": "Otkaži",
        "moredotdotdot": "Više…",
-       "morenotlisted": "Ova lista možda nije potpuna.",
+       "morenotlisted": "Ovaj spisak možda nije potpun.",
        "mypage": "Stranica",
        "mytalk": "Razgovor",
        "anontalk": "Razgovor",
        "updatedmarker": "ažurirano od moje poslednje posete",
        "printableversion": "Verzija za štampanje",
        "permalink": "Trajna veza",
-       "print": "Štampaj",
+       "print": "Štampanje",
        "view": "Prikaži",
        "view-foreign": "Prikaži na projektu $1",
        "edit": "Uredi",
        "lastmodifiedat": "Ova stranica je poslednji put uređena na datum $1 u $2 č.",
        "viewcount": "Ovoj stranici je pristupljeno {{PLURAL:$1|jedanput|$1 puta}}.",
        "protectedpage": "Zaštićena stranica",
-       "jumpto": "Idi na:",
+       "jumpto": "Pređi na:",
        "jumptonavigation": "navigaciju",
        "jumptosearch": "pretragu",
        "view-pool-error": "Serveri su trenutno preopterećeni.\nPreviše korisnika pokušava da vidi ovu stranicu.\nSačekajte neko vreme pre nego što ponovo pokušate da joj pristupite.\n\n$1",
        "pool-errorunknown": "Nepoznata greška",
        "pool-servererror": "Usluga brojača redova nije dostupna ($1).",
        "poolcounter-usage-error": "Greška pri upotrebi: $1",
-       "aboutsite": "O projektu {{SITENAME}}",
-       "aboutpage": "Project:O_projektu_{{SITENAME}}",
+       "aboutsite": "O {{GRAMMAR:dativ|{{SITENAME}}}}",
+       "aboutpage": "Project:O_{{GRAMMAR:dativ|{{SITENAME}}}}",
        "copyright": "Sadržaj je dostupan pod licencom $1 osim ako je drugačije navedeno.",
        "copyrightpage": "{{ns:project}}:Autorska prava",
        "currentevents": "Aktuelnosti",
        "nstab-category": "Kategorija",
        "mainpage-nstab": "Glavna strana",
        "nosuchaction": "Nema takve radnje",
-       "nosuchactiontext": "Radnja koja je navedena u URL-u nije važeća.\nMožda ste otkucali pogrešan URL-a ili ste pratili pokvarenu vezu.\nOvo takođe može da ukazuje na grešku u softveru koji koristi {{SITENAME}}.",
+       "nosuchactiontext": "Radnja koja je navedena u URL adresi nije važeća.\nMožda ste otkucali pogrešan URL-a ili ste pratili pokvarenu vezu.\nOvo takođe može da ukazuje na grešku u softveru koji koristi {{SITENAME}}.",
        "nosuchspecialpage": "Nema takve posebne stranice",
        "nospecialpagetext": "<strong>Zahtevali ste nevalidnu posebnu stranicu.</strong>\n\nSpisak validnih posebnih stranica može da se pronađe na „[[Special:SpecialPages|{{int:specialpages}}]]”.",
        "error": "Greška",
        "createacct-yourpasswordagain": "Potvrdite lozinku",
        "createacct-yourpasswordagain-ph": "Ponovo unesite lozinku",
        "userlogin-remembermypassword": "Ostavi me prijavljenog/u",
-       "userlogin-signwithsecure": "Koristite sigurnu konekciju",
+       "userlogin-signwithsecure": "Koristite bezbednu vezu",
        "cannotlogin-title": "Prijava nije moguća",
        "cannotlogin-text": "Prijava nije moguća",
        "cannotloginnow-title": "Prijava trenutno nije moguća",
        "password-change-forbidden": "Ne možete da promenite lozinku na ovom vikiju.",
        "externaldberror": "Došlo je do greške pri potvrdi identiteta baze podataka ili vam nije dozvoljeno da ažurirate svoj spoljni nalog.",
        "login": "Prijava",
-       "login-security": "Potvrda vašeg indentiteta",
+       "login-security": "Verifikacija indentiteta",
        "nav-login-createaccount": "Prijavite se / otvorite nalog",
        "logout": "Odjava",
        "userlogout": "Odjava",
        "notloggedin": "Niste prijavljeni",
        "userlogin-noaccount": "Nemate nalog?",
-       "userlogin-joinproject": "Pridružite se projektu {{SITENAME}}",
+       "userlogin-joinproject": "Pridružite se {{GRAMMAR:dativ|{{SITENAME}}}}",
        "createaccount": "Otvaranje naloga",
        "userlogin-resetpassword-link": "Zaboravili ste lozinku?",
        "userlogin-helplink2": "Pomoć pri prijavljivanju",
        "userlogin-loggedin": "Već ste prijavljeni kao {{GENDER:$1|$1}}.\nKoristite donji obrazac da biste se prijavili kao drugi korisnik.",
-       "userlogin-reauth": "Morate da se ponovo prijavite da biste potvrdili da ste {{GENDER:$1|$1}}.",
+       "userlogin-reauth": "Morate da se ponovo prijavite da biste verifikovali da ste {{GENDER:$1|$1}}.",
        "userlogin-createanother": "Otvori još jedan nalog",
        "createacct-emailrequired": "Imejl-adresa",
        "createacct-emailoptional": "Imejl-adresa (opcionalno)",
        "nocookiesforlogin": "{{int:nocookieslogin}}",
        "createacct-loginerror": "Nalog je uspešno napravljen, ali se ne možete automatski prijaviti. Pređite na [[Special:UserLogin|ručno prijavljivanje]].",
        "noname": "Niste naveli važeće korisničko ime.",
-       "loginsuccesstitle": "Prijavljen",
+       "loginsuccesstitle": "Uspešno prijavljivanje",
        "loginsuccess": "<strong>Prijavljeni ste na {{SITENAME}} kao „$1”.</strong>",
        "nosuchuser": "Ne postoji korisnik s imenom „$1“.\nKorisnička imena su osetljiva na mala i velika slova.\nProverite da li ste ga dobro uneli ili [[Special:CreateAccount|otvorite novi nalog]].",
        "nosuchusershort": "Korisnik s imenom „$1“ ne postoji.\nProverite da li ste pravilno napisali.",
        "passwordtooshort": "Lozinka mora imati najmanje {{PLURAL:$1|jedan znak|$1 znaka|$1 znakova}}.",
        "passwordtoolong": "Lozinke ne mogu biti duže od {{PLURAL:$1|$1 znaka|$1 znakova}}.",
        "passwordtoopopular": "Nije moguće koristiti često odabrane lozinke. Odaberite lozinku koju je teže pogoditi.",
+       "passwordinlargeblacklist": "Unesena lozinka je na listi veoma često korišćenih lozinki. Odaberite jedinstveniju lozinku.",
        "password-name-match": "Lozinka se mora razlikovati od korisničkog imena.",
        "password-login-forbidden": "Korišćenje ovog korisničkog imena i lozinke je zabranjeno.",
        "mailmypassword": "Resetuj lozinku",
        "headline_sample": "Tekst naslova",
        "headline_tip": "Podnaslov (nivo 2)",
        "nowiki_sample": "Ovde umetnite neoblikovan tekst",
-       "nowiki_tip": "Zanemari viki formatiranje",
+       "nowiki_tip": "Zanemari viki-oblikovanje",
        "image_sample": "Primer.jpg",
        "image_tip": "Ugrađivanje datoteke",
        "media_sample": "Primer.ogg",
        "anoneditwarning": "<strong>Upozorenje:</strong> Niste prijavljeni. Ako objavite stranicu, vaša IP adresa će biti javno vidljiva u njenoj istoriji izmena i drugde. Ako se <strong>[$1 prijavite]</strong> ili <strong>[$2 otvorite nalog]</strong>, pored ostalih pogodnosti koje dobijate vaše izmene će biti pripisivane vašem korisničkom imenu.",
        "anonpreviewwarning": "<em>Niste prijavljeni. Ako objavite stranicu, vaša IP adresa će biti javno vidljiva u njenoj istoriji izmena i drugde.</em>",
        "missingsummary": "<strong>Podsetnik:</strong> niste naveli opis izmene.\nAko ponovo kliknete na „$1”, vaša izmena će biti sačuvana bez njega.",
-       "selfredirect": "<strong>Upozorenje:</strong> Preusmeravate ovu stranicu na nju samu.\nMožda vam je odredišna stranica za preusmerenje pogrešna ili uređujete pogrešnu stranicu.\nAko još jednom pritisnete „$1”, preusmerenje će svejedno biti napravljeno.",
+       "selfredirect": "<strong>Upozorenje:</strong> Preusmeravate ovu stranicu na nju samu.\nMožda ste naveli pogrešnu odredišnu stranicu za preusmeravanje ili uređujete pogrešnu stranicu.\nAko ponovo kliknete na „$1”, preusmeravanje će svejedno biti napravljeno.",
        "missingcommenttext": "Molimo unesite komentar.",
        "missingcommentheader": "<strong>Napomena:</strong> Niste uneli naslov teme ovog komentara.\nAko ponovo kliknete na „$1”, izmena će biti sačuvana bez naslova.",
-       "summary-preview": "Pregled opisa izmene:",
+       "summary-preview": "Pretpregled opisa izmene:",
        "subject-preview": "Pregled teme:",
        "previewerrortext": "Došlo je do greške pri pokušaju pregleda promena.",
        "blockedtitle": "Korisnik je blokiran",
        "blocked-email-user": "<strong>Vašem korisničkom imenu je blokirano slanje imejlova. Još uvek možete da uređujete druge stranice na ovom vikiju.</strong> Možete da vidite potpune detalje blokade na [[Special:MyContributions|doprinosima naloga]].\n\nBlokadu je izvršio/la $1.\n\nNaveden je sledeći razlog: <em>$2</em>.\n\n* Početak blokade: $8\n* Istek blokade: $6\n* Namenjena korisniku/ci ili IP adresi: $7\n* ID blokade #$5",
        "blockedtext-partial": "<strong>Vašem korisničkom imenu ili IP adresi je blokirano pravljenje promena na ovoj stranici. Još uvek možete da uređujete druge stranice na ovom vikiju.</strong> Možete da vidite potpune detalje blokade na [[Special:MyContributions|doprinosima naloga]].\n\nBlokadu je izvršio/la $1.\n\nNaveden je sledeći razlog: <em>$2</em>.\n\n* Početak blokade: $8\n* Istek blokade: $6\n* Namenjena korisniku/ci ili IP adresi: $7\n* ID blokade #$5",
-       "blockedtext": "<strong>Vaše korisničko ime ili IP adresa je blokirana.</strong>\n\nBlokadu je {{GENDER:$4|izvršio|izvršila}} $1.\nRazlog je <em>$2</em>.\n\n* Početak blokade: $8\n* Istek blokade: $6\n* Blokirani: $7\n\nMožete da kontaktirate {{GENDER:$4|korisnika|korisnicu}} $1 ili drugog [[{{MediaWiki:Grouppage-sysop}}|administratora]] da biste diskutovali o blokadi.\nNe možete da koristite funkciju „{{int:emailuser}}” osim ako ste naveli validnu imejl-adresu u svojim [[Special:Preferences|podešavanjima naloga]] i niste blokirani od korišćenja iste.\nVaša trenutna IP adresa je $3, a ID blokade #$5.\nNavedite sve gornje detalje pri pravljenju bilo kakvih upita.",
+       "blockedtext": "<strong>Vaše korisničko ime ili IP adresa je blokirana.</strong>\n\nBlokiranje je {{GENDER:$4|izvršio|izvršila}} $1.\nRazlog je <em>$2</em>.\n\n* Početak blokiranja: $8\n* Istek blokiranja: $6\n* Blokirani: $7\n\nMožete da se obratite {{GENDER:$4|korisniku|korisnici}} $1 ili [[{{MediaWiki:Grouppage-sysop}}|administratoru]] radi diskusije o blokiranju.\nNe možete da koristite mogućnost „{{int:emailuser}}” osim ako ste uneli validnu imejl adresu u svojim [[Special:Preferences|podešavanjima]] naloga i niste blokirani od korišćenja iste.\nVaša trenutna IP adresa je $3, a ID blokiranja #$5.\nNavedite sve informacije odozgo pri stvaranju bilo kakvih upita.",
        "autoblockedtext": "Vaša IP adresa je automatski blokirana jer ju je koristio drugi korisnik, koga je {{GENDER:$4|blokirao|blokirala}} $1.\nRazlog:\n\n:<em>$2</em>\n\n* Početak blokade: $8\n* Kraj blokade: $6\n* Ime korisnika: $7\n\nMožete da kontaktirate {{GENDER:$4|korisnika|korisnicu}} $1 ili drugog [[{{MediaWiki:Grouppage-sysop}}|administratora]] da biste raspravljali o blokadi.\n\nZapamtite da ne možete da koristite funkciju „{{int:emailuser}}“ osim ako ste naveli važeću imejl-adresu u svojim [[Special:Preferences|podešavanjima]].\n\nVaša trenutna IP adresa je $3, a ID blokade $5.\nUključite sve gornje detalje pri pravljenju bilo kakvih upita.",
        "blockednoreason": "razlog nije naveden",
        "whitelistedittext": "$1 da biste uređivali stranice.",
        "updated": "(ažurirano)",
        "note": "<strong>Napomena:</strong>",
        "previewnote": "<strong>Ne zaboravite da je ovo samo pretpregled.</strong>\nVaše promene još nisu sačuvane!",
-       "continue-editing": "Idi na uređivački okvir",
+       "continue-editing": "Pređi na obast uređivanja",
        "previewconflict": "Ovaj pregled oslikava kako će izgledati tekst u tekstualnom okviru.",
        "session_fail_preview": "Izvinjavamo se! Nismo mogli da obradimo vašu izmenu zbog gubitka podataka sesije.\n\nMožda ste odjavljeni. <strong>Proverite da li ste prijavljeni i pokušajte ponovo</strong>.\nAko i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite, te proverite da li su na vašem pretraživaču dozvoljeni kolačići sa ovog sajta.",
        "session_fail_preview_html": "Nismo mogli da obradimo vašu izmenu zbog gubitka podataka sesije.\n\n<em>Budući da je na ovom vikiju omogućen unos HTML oznaka, pregled je sakriven kao mera predostrožnosti protiv napada preko javaskripta.</em>\n\n<strong>Ako ste pokušali da napravite pravu izmenu, pokušajte ponovo.<strong>\nAko i dalje ne radi, pokušajte da se [[Special:UserLogout|odjavite]] i ponovo prijavite i proverite da li vaš pregledač dozvoljava kolačiće sa ovog sajta.",
        "editpage-notsupportedcontentformat-text": "Format sadržaja $1 nije podržan za model sadržaja $2.",
        "content-model-wikitext": "vikitekst",
        "content-model-text": "čist tekst",
-       "content-model-javascript": "javaskript",
+       "content-model-javascript": "JavaScript",
        "content-model-css": "CSS",
        "content-model-json": "JSON",
        "content-json-empty-object": "Prazan objekat",
        "undo-summary-username-hidden": "Poništi izmenu $1 skrivenog korisnika",
        "cantcreateaccount-text": "Otvaranje naloga s ove IP adrese (<strong>$1</strong>) je blokirao/la [[User:$3|$3]].\n\nRazlog koji je naveo/la $3 je <em>$2</em>",
        "cantcreateaccount-range-text": "Otvaranje naloga sa IP adresa u rasponu <strong>$1</strong>, koji uključuje i vašu IP adresu (<strong>$4</strong>) je blokirao/la [[User:$3|$3]].\n\nRazlog koji je naveo/la $3 je <em>$2</em>",
-       "viewpagelogs": "Prikaži dnevnike ove stranice",
+       "viewpagelogs": "Dnevnici ove stranice",
        "nohistory": "Ne postoji istorija izmena ove stranice.",
        "currentrev": "Najnovija izmena",
        "currentrev-asof": "Najnovija izmena na datum $2 u $3",
        "revdelete-offender": "Autor izmene:",
        "suppressionlog": "Dnevnik sakrivanja",
        "suppressionlogtext": "Ispod se nalazi spisak brisanja i blokiranja koji uključuje sadržaj sakriven od administratora. Pogledajte [[Special:BlockList|spisak blokiranja]] za spisak trenutnih operacija zabrana i blokiranja.",
-       "mergehistory": "Spajanje istorija stranice",
-       "mergehistory-header": "Ova stranica vam omogućava da spojite izmene neke izvorne stranice u novu stranicu.\nZapamtite da će ova promena ostaviti nepromenjen sadržaj istorije stranice.",
-       "mergehistory-box": "Spoji izmene dve stranice:",
+       "mergehistory": "Objedinjavanje istorija stranice",
+       "mergehistory-header": "Ova stranica vam dopušta da objedinite istoriju izmena neke izvorne stranice u noviju stranicu.\nUverite se da će ova promena ostaviti nepromenjen sadržaj istorije stranice.",
+       "mergehistory-box": "Objedini izmene dveju stranica:",
        "mergehistory-from": "Izvorna stranica:",
        "mergehistory-into": "Odredišna stranica:",
-       "mergehistory-list": "Spojiva istorija izmena",
-       "mergehistory-merge": "Sledeće izmene stranice [[:$1]] mogu se spojiti sa [[:$2]].\nKoristite dugmiće u koloni da biste spojili izmene koje su napravljene pre navedenog vremena.\nKorišćenje navigacionih veza će poništiti ovu kolonu.",
-       "mergehistory-go": "Prikaži izmene koje se mogu spojiti",
-       "mergehistory-submit": "Spoji izmene",
-       "mergehistory-empty": "Nema izmena za spajanje.",
-       "mergehistory-done": "$3 {{PLURAL:$3|izmena stranice $1 je spojena|izmene stranice $1 su spojene|izmena stranice $1 je spojeno}} u [[:$2]].",
+       "mergehistory-list": "Objedinjiva istorija izmena",
+       "mergehistory-merge": "Sledeće izmene stranice [[:$1]] mogu da se objedne u [[:$2]].\nKoristite dugmiće u koloni da biste objedinili samo izmene napravljene pre navedenog vremena.\nZapamtite da će korišćenje veza za navigaciju resetovati ovu kolonu.",
+       "mergehistory-go": "Prikaži objedinjive izmene",
+       "mergehistory-submit": "Objedini izmene",
+       "mergehistory-empty": "Nema izmena za objedinjavanje.",
+       "mergehistory-done": "$3 {{PLURAL:$3|izmena stranice $1 je objedinjena|izmene stranice $1 su objedinjene|izmena stranice $1 je objedinjeno}} u [[:$2]].",
        "mergehistory-fail": "Nije moguće izvršiti spajanje istorije. Proverite stranicu i vremenske parametre.",
        "mergehistory-fail-bad-timestamp": "Vremenska oznaka je nevažeća.",
        "mergehistory-fail-invalid-source": "Izvorna stranica nije važeća.",
        "mergehistory-fail-invalid-dest": "Odredišna stranica je nevažeća.",
-       "mergehistory-fail-no-change": "Spajanje istorije nije spojilo nijednu izmenu. Proverite parametre stranice i vremena.",
-       "mergehistory-fail-permission": "Nemate ovlašćenje za spajanje istorije.",
+       "mergehistory-fail-no-change": "Objedinjavanje istorije nije objedinilo nijednu izmenu. Ponovo proverite parametre stranice i vremena.",
+       "mergehistory-fail-permission": "Nedovoljno dozvola za objedinjavanje istorije.",
        "mergehistory-fail-self-merge": "Izvorna i odredišna stranica su iste.",
        "mergehistory-fail-timestamps-overlap": "Izvorne izmene se preklapaju ili dolaze nakon odredišnih izmena.",
-       "mergehistory-fail-toobig": "Nije moguće izvršiti spajanje istorije jer će više od $1 {{PLURAL:$1|izmene biti premeštene|izmena biti premešteno}}.",
+       "mergehistory-fail-toobig": "Nije moguće izvršiti objedinjavanje istorije jer će više od $1 {{PLURAL:$1|izmene biti premeštene|izmena biti premešteno}}.",
        "mergehistory-no-source": "Izvorna stranica $1 ne postoji.",
        "mergehistory-no-destination": "Odredišna stranica $1 ne postoji.",
        "mergehistory-invalid-source": "Izvorna stranica mora imati validan naslov.",
        "mergehistory-invalid-destination": "Odredišna stranica mora da ima važeći naslov.",
-       "mergehistory-autocomment": "Stranica [[:$1]] je spojena u [[:$2]]",
+       "mergehistory-autocomment": "Stranica [[:$1]] je objedinjena u [[:$2]]",
        "mergehistory-comment": "Stranica [[:$1]] je spojena u [[:$2]]: $3",
        "mergehistory-same-destination": "Izvorna i odredišna stranica ne mogu biti iste",
        "mergehistory-reason": "Razlog:",
        "mergehistory-revisionrow": "$1 ($2) $3 . . $4 $5 $6",
-       "mergelog": "Dnevnik spajanja",
+       "mergelog": "Dnevnik objedinjavanja",
        "revertmerge": "rastavi",
-       "mergelogpagetext": "Ispod je spisak najskorijih spajanja istorija dveju stranica.",
+       "mergelogpagetext": "Ispod je spisak najnovijih objedinjavanja istorija jedne stranice u drugu.",
        "history-title": "Istorija izmena stranice „$1”",
        "difference-title": "Razlika između izmena na stranici „$1”",
        "difference-title-multipage": "Razlika između stranica „$1“ i „$2“",
        "prefs-watchlist": "Spisak nadgledanja",
        "prefs-editwatchlist": "Uređivanje spiska nadgledanja",
        "prefs-editwatchlist-label": "Uredi unose na spisku nadgledanja:",
-       "prefs-editwatchlist-edit": "prikaži i ukloni naslove sa spiska nadgledanja",
-       "prefs-editwatchlist-raw": "uredi neobrađeni spisak nadgledanja",
-       "prefs-editwatchlist-clear": "očisti spisak nadgledanja",
+       "prefs-editwatchlist-edit": "Prikaz i uklanjanje naslova sa spiska nadgledanja",
+       "prefs-editwatchlist-raw": "Uređivanje neobrađenog spiska nadgledanja",
+       "prefs-editwatchlist-clear": "Čišćenje spiska nadgledanja",
        "prefs-watchlist-days": "Broj dana u spisku nadgledanja:",
        "prefs-watchlist-days-max": "Najviše $1 {{PLURAL:$1|dan|dana|dana}}",
        "prefs-watchlist-edits": "Najveći broj promena prikazanih na spisku nadgledanja:",
        "prefs-watchlist-edits-max": "Najveći broj: 1000",
        "prefs-watchlist-token": "Token spiska nadgledanja:",
-       "prefs-watchlist-managetokens": "Upravljaj tokenima",
+       "prefs-watchlist-managetokens": "Upravljanje tokenima",
        "prefs-misc": "Razno",
-       "prefs-resetpass": "promeni lozinku",
-       "prefs-changeemail": "Promeni ili ukloni imejl-adresu",
-       "prefs-setemail": "Postavi imejl-adresu",
+       "prefs-resetpass": "Promena lozinke",
+       "prefs-changeemail": "Promena ili uklanjanje imejl-adrese",
+       "prefs-setemail": "Postavljanje imejl-adrese",
        "prefs-email": "Opcije imejla",
        "prefs-rendering": "Izgled",
        "saveprefs": "Sačuvaj",
        "searchresultshead": "Pretraga",
        "stub-threshold": "Prag za formatiranje veza kao klice ($1):",
        "stub-threshold-sample-link": "primer",
-       "stub-threshold-disabled": "onemogućeno",
+       "stub-threshold-disabled": "Onemogućeno",
        "recentchangesdays": "Broj dana u skorašnjim izmenama:",
        "recentchangesdays-max": "Najviše $1 {{PLURAL:$1|dan|dana}}",
        "recentchangescount": "Podrazumevani broj izmena za prikaz u skorašnjim izmenama, istorijama stranica i dnevnicima:",
        "savedrights": "Korisničke grupe {{GENDER:$1|korisnika|korisnice}} $1 su sačuvane.",
        "timezonelegend": "Vremenska zona:",
        "localtime": "Lokalno vreme:",
-       "timezoneuseserverdefault": "podrazumevane vrednosti ($1)",
-       "timezoneuseoffset": "drugo (unesite odstupanje)",
+       "timezoneuseserverdefault": "Koristi podrazumevane vrednosti vikija ($1)",
+       "timezoneuseoffset": "Drugo (navedite odstupanje ispod)",
+       "timezone-useoffset-placeholder": "Primeri vrednosti: „-07:00” ili „01:00”",
        "servertime": "Vreme na serveru:",
-       "guesstimezone": "popuni iz pregledača",
+       "guesstimezone": "Popuni iz pregledača",
        "timezoneregion-africa": "Afrika",
        "timezoneregion-america": "Amerika",
        "timezoneregion-antarctica": "Antarktik",
        "email-blacklist-label": "Zabrani primanje imejlova od sledećih korisnika:",
        "prefs-searchoptions": "Pretraga",
        "prefs-namespaces": "Imenski prostori",
-       "default": "podrazumevana",
+       "default": "podrazumevano",
        "prefs-files": "Datoteke",
        "prefs-custom-css": "prilagođeni CSS",
        "prefs-custom-json": "Prilagođeni JSON",
        "prefs-custom-js": "prilagođeni JavaScript",
-       "prefs-common-config": "Deljeni CSS/JSON/javaskript za sve teme:",
+       "prefs-common-config": "Deljeni CSS/JSON/JavaScript za sve teme:",
        "prefs-reset-intro": "Možete koristiti ovu stranicu da ponovo postavite svoja podešavanja na podrazumevane vrednosti sajta.\nOvo se ne može opozvati.",
        "prefs-emailconfirm-label": "Potvrda imejla:",
        "youremail": "Imejl:",
        "prefs-help-realname": "Pravo ime je opcionalno.\nAko je navedeno, biće korišćeno za pripisivanje vašeg rada.",
        "prefs-help-email": "Imejl adresa je opcionalna, ali je potrebna za resetovanje lozinke, ako je zaboravite.",
        "prefs-help-email-others": "Takođe možete izabrati da dopustite drugima da vas kontaktiraju preko imejla putem veze na vašoj korisničkoj stranici ili stranici za razgovor.\nVaša imejl adresa neće biti prikazana drugim korisnicima koji vas kontaktiraju.",
-       "prefs-help-email-required": "Imejl-adresa je neophodna.",
+       "prefs-help-email-required": "Potrebna je imejl-adresa.",
        "prefs-info": "Osnovne informacije",
        "prefs-i18n": "Internacionalizacija",
        "prefs-signature": "Potpis",
        "prefs-editor": "Uređivač",
        "prefs-preview": "Pretpregled",
        "prefs-advancedrc": "Napredne opcije",
-       "prefs-opt-out": "Onemogućavanje poboljšanja",
        "prefs-advancedrendering": "Napredne opcije",
        "prefs-advancedsearchoptions": "Napredne opcije",
        "prefs-advancedwatchlist": "Napredne opcije",
        "prefs-displayrc": "Podešavanja prikaza",
        "prefs-displaywatchlist": "Opcije prikaza",
+       "prefs-changesrc": "Prikazane promene",
+       "prefs-changeswatchlist": "Prikazane promene",
+       "prefs-pageswatchlist": "Nadgledane stranice",
        "prefs-tokenwatchlist": "Token",
        "prefs-diffs": "Razlike",
        "prefs-help-prefershttps": "Ova podešavanja će stupiti na snagu pri sledećoj prijavi.",
        "right-reupload": "zamenjivanje postojećih datoteka",
        "right-reupload-own": "zamenjivanje sopstvenih datoteka",
        "right-reupload-shared": "lokalno zamenjivanje datoteka na deljenom spremištu medija",
-       "right-upload_by_url": "Otpremanje datoteka sa veb-adrese",
+       "right-upload_by_url": "otpremanje datoteka sa URL adrese",
        "right-purge": "čišćenje keš memorije stranice bez potvrde",
        "right-autoconfirmed": "bez ograničavanja stavki za IP adrese",
        "right-bot": "smatranje izmena kao automatski proces",
        "right-autopatrol": "automatsko označavanje izmena patroliranim",
        "right-patrolmarks": "pregledanje oznaka za patroliranje unutar skorašnjih izmena",
        "right-unwatchedpages": "pregledanje spiska nenadgledanih stranica",
-       "right-mergehistory": "spajanje istorija stranica",
+       "right-mergehistory": "objedinjavanje istorija stranica",
        "right-userrights": "uređivanje svih korisničkih prava",
        "right-userrights-interwiki": "uređivanje korisničkih prava na drugim vikijima",
        "right-siteadmin": "zaključavanje i otključavanje baze podataka",
        "grant-editmywatchlist": "Uređivanje vašeg spiska nadgledanja",
        "grant-editpage": "Uređivanje postojećih stranica",
        "grant-editprotected": "Uređivanje zaštićenih stranica",
-       "grant-highvolume": "Masovno uređivanje",
+       "grant-highvolume": "Menjanje velikog obima",
        "grant-oversight": "Skrivanje korisnika i izmena",
        "grant-patrol": "Patroliranje promena na stranicama",
        "grant-privateinfo": "Pristupi privatnim informacijama",
        "action-upload": "otpremite ovu datoteku",
        "action-reupload": "zamenjujete ovu postojeću datoteku",
        "action-reupload-shared": "premostite ovu datoteku sa zajedničkog skladišta",
-       "action-upload_by_url": "otpremite ovu datoteku putem URL-a",
+       "action-upload_by_url": "otpremite ovu datoteku sa URL adrese",
        "action-writeapi": "koristite API za pisanje",
        "action-delete": "izbrišete ovu stranicu",
        "action-deleterevision": "brišete izmene",
        "action-patrol": "označite tuđe izmene kao patrolirane",
        "action-autopatrol": "označite sopstvene izmene kao patrolirane",
        "action-unwatchedpages": "pregledate spisak nenadgledanih stranica",
-       "action-mergehistory": "spajate istoriju ove stranice",
+       "action-mergehistory": "objedinite istoriju ove stranice",
        "action-userrights": "uređujete sva korisnička prava",
        "action-userrights-interwiki": "uređujete korisnička prava korisnika na drugim vikijima",
        "action-siteadmin": "zaključavate ili otključavate bazu podataka",
        "rcfilters-activefilters": "Aktivni filteri",
        "rcfilters-activefilters-hide": "Sakrij",
        "rcfilters-activefilters-show": "Prikaži",
-       "rcfilters-activefilters-hide-tooltip": "Sakrijte područje aktivnih filtera",
-       "rcfilters-activefilters-show-tooltip": "Prikažite područje aktivnih filtera",
+       "rcfilters-activefilters-hide-tooltip": "Sakrij oblast aktivnih filtera",
+       "rcfilters-activefilters-show-tooltip": "Prikaži oblast aktivnih filtera",
        "rcfilters-advancedfilters": "Napredni filteri",
        "rcfilters-limit-title": "Broj izmena za prikaz",
        "rcfilters-limit-and-date-label": "$1 {{PLURAL:$1|promena|promene|promena}}, $2",
        "rcfilters-savedqueries-already-saved": "Ovi filteri su već sačuvani. Promenite svoja podešavanja da biste napravili nove sačuvane filtere.",
        "rcfilters-restore-default-filters": "Vrati podrazumevane filtere",
        "rcfilters-clear-all-filters": "Obrišite sve filtere",
-       "rcfilters-show-new-changes": "Prikaži najnovije promene",
+       "rcfilters-show-new-changes": "Najnovije promene",
        "rcfilters-search-placeholder": "Filtrirajte promene (koristite meni ili pretragu za ime filtera)",
        "rcfilters-invalid-filter": "Nevažeći filter",
        "rcfilters-empty-filter": "Nema aktivnih filtera. Svi doprinosi su prikazani.",
        "rcfilters-watchlist-markseen-button": "Označi sve promene kao viđene",
        "rcfilters-watchlist-edit-watchlist-button": "Uredi spisak nadgledanih stranica",
        "rcfilters-watchlist-showupdated": "Promene na stranicama koje niste posetili od kada je izmena izvršena su <strong>podebljane</strong>, s ispunjenim oznakama.",
-       "rcfilters-preference-label": "Sakrij poboljšanu verziju skorašnjih izmena",
-       "rcfilters-preference-help": "Poništava redizajn interfejsa iz 2017. i sve alatke dodate tada i posle.",
-       "rcfilters-watchlist-preference-label": "Sakrij poboljšanu verziju spiska nadgledanja",
-       "rcfilters-watchlist-preference-help": "Uklanja redizajn interfejsa iz 2017. godine i sve alatke dodate tada i od tada.",
+       "rcfilters-preference-label": "Koristi interfejs bez JavaScript-a",
+       "rcfilters-preference-help": "Učitava skorašnje izmene bez filtera ili funkcionalnosti isticanja.",
+       "rcfilters-watchlist-preference-label": "Koristi interfejs bez JavaScript-a",
+       "rcfilters-watchlist-preference-help": "Učitava spisak nadgledanja bez filtera ili funkcionalnosti isticanja.",
        "rcfilters-filter-showlinkedfrom-label": "Prikaži promene na stranicama sa kojih dolaze veze",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Stranice sa kojih dolaze veze do</strong> izabrane stranice",
        "rcfilters-filter-showlinkedto-label": "Prikaži promene na stranicama ka kojima vode veze",
        "uploadwarning-text-nostash": "Re-otpremite datoteku, izmenite opis ispod i pokušajte ponovo.",
        "savefile": "Sačuvaj datoteku",
        "uploaddisabled": "Otpremanje je onemogućeno.",
-       "copyuploaddisabled": "Otpremanje putem veb-adrese je onemogućeno.",
+       "copyuploaddisabled": "Otpremanje sa URL adrese je onemogućeno.",
        "uploaddisabledtext": "Otpremanje datoteka je onemogućeno.",
        "php-uploaddisabledtext": "Otpremanje datoteka je onemogućeno u PHP-u.\nProverite podešavanja file_uploads.",
        "uploadscripted": "Datoteka sadrži HTML ili skriptni kod koji može biti pogrešno protumačen od strane pregledača.",
        "upload-scripted-pi-callback": "Datoteka koja sadrži instrukcije za obradu XML stilskog oblika se ne može otpremiti.",
-       "upload-scripted-dtd": "Nije moguće otpremiti SVG datoteke koje sadrže nestandardnu DTD deklaraciju.",
+       "upload-scripted-dtd": "Nije moguće otpremanje SVG datoteka koje sadrže nestandardnu DTD deklaraciju.",
        "uploaded-script-svg": "Pronađen skriptni elemenat „$1“ u postavljenoj SVG datoteci.",
        "uploaded-hostile-svg": "Pronađen nebezbedan CSS u stilskom elementu postavljene SVG datoteke.",
        "uploaded-event-handler-on-svg": "Nije dozvoljeno postavljanje atributa koji kontrolišu događaje <code>$1=\"$2\"</code> u SVG datotekama.",
        "uploadjava": "Datoteka je formata ZIP koji sadrži java .class element.\nSlanje java datoteka nije dozvoljeno jer one mogu izazvati zaobilaženje sigurnosnih ograničenja.",
        "upload-source": "Izvorna datoteka",
        "sourcefilename": "Naziv izvorne datoteke:",
-       "sourceurl": "Adresa izvora:",
+       "sourceurl": "URL adresa izvora:",
        "destfilename": "Naziv:",
        "upload-maxfilesize": "Maksimalna veličina datoteke: $1",
        "upload-description": "Opis datoteke",
        "filename-bad-prefix": "Naziv datoteke koju šaljete počinje sa <strong>„$1“</strong>, a njega obično dodeljuju digitalni fotoaparati.\nIzaberite naziv datoteke koji opisuje njen sadržaj.",
        "filename-prefix-blacklist": " #<!-- ostavite ovaj red onakvim kakav jeste --> <pre>\n# Sintaksa je sledeća:\n#   * Sve od tarabe pa do kraja reda je komentar\n#   * Svaki red označava prefiks tipičnih naziva datoteka koje dodeljivaju digitalni aparati\nCIMG # Kasio\nDSC_ # Nikon\nDSCF # Fudži\nDSCN # Nikon\nDUW # neki mobilni telefoni\nIMG # opšte\nJD # Dženoptik\nMGP # Pentaks\nPICT # razno\n #</pre> <!-- ostavite ovaj red onakvim kakav jeste -->",
        "upload-proto-error": "Nevažeći protokol",
-       "upload-proto-error-text": "Slanje sa spoljne lokacije zahteva adresu koja počinje sa <code>http://</code> ili <code>ftp://</code>.",
+       "upload-proto-error-text": "Udaljeno otpremanje zahteva URL adrese koje počinju sa <code>http://</code> ili <code>ftp://</code>.",
        "upload-file-error": "Unutrašnja greška",
        "upload-file-error-text": "Došlo je do unutrašnje greške pri otvaranju privremene datoteke na serveru.\nKontaktirajte [[Special:ListUsers/sysop|administratora]].",
        "upload-misc-error": "Nepoznata greška pri slanju datoteke",
        "upload-http-error": "Došlo je do HTTP greške: $1",
        "upload-copy-upload-invalid-domain": "Primerci otpremanja nisu dostupni na ovom domenu.",
        "upload-dialog-disabled": "Postavljanje datoteka pomoću ovog dijaloga je onemogućeno na ovom vikiju.",
-       "upload-dialog-title": "Otpremi datoteku",
+       "upload-dialog-title": "Otpremanje datoteke",
        "upload-dialog-button-cancel": "Otkaži",
        "upload-dialog-button-back": "Nazad",
        "upload-dialog-button-done": "Gotovo",
        "uploadstash-file-not-found-no-thumb": "Nije moguće pribaviti sličicu.",
        "uploadstash-file-not-found-no-local-path": "Nema lokalne putanje za umanjenu stavku.",
        "uploadstash-file-not-found-no-object": "Nije moguće napraviti lokalni datotečni objekat za sličicu.",
-       "uploadstash-file-not-found-no-remote-thumb": "Dobavljanje minijature nije uspelo: $1\nAdresa = $2",
+       "uploadstash-file-not-found-no-remote-thumb": "Dobavljanje sličice nije uspelo: $1\nURL adresa = $2",
        "uploadstash-file-not-found-missing-content-type": "Nedostaje zaglavlje za tip sadržaja.",
        "uploadstash-file-not-found-not-exists": "Ne mogu naći putanju ili ovo nije obična datoteka.",
        "uploadstash-file-too-large": "Ne mogu poslužiti datoteku veću od $1 {{PLURAL:$1|bajta|bajtova}}",
        "img-auth-streaming": "Učitavam „$1“...",
        "img-auth-public": "Svrha img_auth.php je da prosleđuje datoteke iz privatnih vikija.\nOvaj viki je postavljen kao javni.\nRadi sigurnosti, img_auth.php je onemogućen.",
        "img-auth-noread": "Korisnik nema pristup za čitanje „$1“.",
-       "http-invalid-url": "Nevažeći URL: $1",
+       "http-invalid-url": "Nevažeća URL adresa: $1",
        "http-invalid-scheme": "Adrese sa šemom „$1“ nisu podržane.",
        "http-request-error": "HTTP zahtev nije prošao zbog nepoznate greške.",
        "http-read-error": "HTTP greška pri čitanju.",
        "http-timed-out": "Zahtev HTTP je istekao.",
-       "http-curl-error": "Greška pri otvaranju adrese: $1",
+       "http-curl-error": "Greška pri dobavljanju URL adrese: $1",
        "http-bad-status": "Došlo je do problema tokom zahteva HTTP: $1 $2",
        "http-internal-error": "HTTP interna greška.",
        "upload-curl-error6": "Nije moguće pristupiti URL adresi",
        "nolicense": "Nije izabrano",
        "licenses-edit": "Uredi izbor licenci",
        "license-nopreview": "(pregled nije dostupan)",
-       "upload_source_url": "(vaša izabrana datoteka od važećih, javno dostupnih adresa)",
+       "upload_source_url": "(vaša odabrana datoteka od važećih, javno dostupnih URL adresa)",
        "upload_source_file": "(vaša odabrana datoteka sa računara)",
        "listfiles-delete": "izbriši",
        "listfiles-summary": "Ova posebna stranica prikazuje sve otpremljene datoteke.",
        "mimetype": "MIME tip:",
        "download": "preuzmi",
        "unwatchedpages": "Nenadgledane stranice",
-       "listredirects": "Spisak preusmerenja",
+       "listredirects": "Spisak preusmeravanja",
        "listduplicatedfiles": "Spisak datoteka sa duplikatima",
        "listduplicatedfiles-summary": "Ovo je spisak datoteka koje su duplikat nekih drugih datoteka. Samo lokalne datoteke su prikazane.",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] ima [[$3|{{PLURAL:$2|jedan duplikat|$2 duplikata}}]].",
        "randomincategory-category": "Kategorija:",
        "randomincategory-legend": "Slučajna stranica u kategoriji",
        "randomincategory-submit": "Idi",
-       "randomredirect": "Slučajno preusmerenje",
+       "randomredirect": "Slučajno preusmeravanje",
        "randomredirect-nopages": "Nema preusmerenja u imenskom prostoru „$1“.",
        "statistics": "Statistike",
        "statistics-header-pages": "Stranice",
        "pageswithprop-submit": "Idi",
        "pageswithprop-prophidden-long": "sakriveno dugo tekstualno svojstvo ($1)",
        "pageswithprop-prophidden-binary": "sakriveno dugo binarno svojstvo ($1)",
-       "doubleredirects": "Dvostruka preusmerenja",
-       "doubleredirectstext": "Ova stranica prikazuje stranice koje preusmeravaju na druga preusmerenja.\nSvaki red sadrži veze prema prvom i drugom preusmerenju, kao i odredišnu stranicu drugog preusmerenja koja je obično „pravi“ članak na koga prvo preusmerenje treba da upućuje.\n<del>Precrtani</del> unosi su već rešeni.",
+       "doubleredirects": "Dvostruka preusmeravanja",
+       "doubleredirectstext": "Ova stranica navodi stranice koje preusmeravaju na druga preusmeravanja.\nSvaki red sadrži veze prema prvom i drugom preusmeravanju, kao i odredišnu stranicu drugog preusmerenja koja je obično „pravi” članak na koga prvo preusmeravanje treba da upućuje.\n<del>Precrtani</del> unosi su već rešeni.",
        "double-redirect-fixed-move": "[[$1]] je premešten.\nAutomatski je ažurirano i sada preusmerava na [[$2]].",
        "double-redirect-fixed-maintenance": "Automatski ispravlja dvostruka preusmerenja iz [[$1]] u [[$2]] kao deo održavanja",
        "double-redirect-fixer": "Ispravljač preusmerenja",
-       "brokenredirects": "Pokvarena preusmerenja",
+       "brokenredirects": "Pokvarena preusmeravanja",
        "brokenredirectstext": "Sledeća preusmerenja vode na nepostojeće stranice:",
        "brokenredirects-edit": "uredi",
        "brokenredirects-delete": "izbriši",
        "mostinterwikis": "Stranice sa najviše međuvikija",
        "mostrevisions": "Stranice sa najviše izmena",
        "prefixindex": "Sve stranice sa prefiksom",
-       "prefixindex-namespace": "Sve stranice s predmetkom (imenski prostor $1)",
+       "prefixindex-namespace": "Sve stranice sa prefiksom (imenski prostor $1)",
        "prefixindex-submit": "Prikaži",
        "prefixindex-strip": "Sakrij prefiks u rezultatima",
        "shortpages": "Kratke stranice",
        "apisandbox-loading-results": "Prijem API rezultata...",
        "apisandbox-results-error": "Došlo je do greške prilikom učitavanja rezultata API upita: $1.",
        "apisandbox-request-selectformat-label": "Prikaži sahtevane podatke kao:",
-       "apisandbox-request-url-label": "Adresa zahteva:",
+       "apisandbox-request-url-label": "URL adresa zahteva:",
        "apisandbox-request-format-json-label": "JSON",
        "apisandbox-request-json-label": "Zatražite JSON:",
        "apisandbox-request-time": "Vreme za izvršavanje zahtjeva: {{PLURAL:$1|$1 milisekunda|$1 milisekunde|$1 milisekundi}}",
        "deletecomment": "Razlog:",
        "deleteotherreason": "Drugi/dodatni razlog:",
        "deletereasonotherlist": "Drugi razlog",
-       "deletereason-dropdown": "* Uobičajeni razlozi za brisanje\n** Nepoželjan sadržaj\n** Vandalizam\n** Kršenje autorskih prava\n** Zahtev autora\n** Pokvareno preusmerenje",
+       "deletereason-dropdown": "* Uobičajeni razlozi za brisanje\n** Nepoželjan sadržaj\n** Vandalizam\n** Kršenje autorskih prava\n** Zahtev autora\n** Prekinuto preusmeravanje",
        "delete-edit-reasonlist": "Uredi razloge brisanja",
        "delete-toobig": "Ova stranica ima veliku istoriju izmena, preko $1 {{PLURAL:$1|izmena|izmene|izmena}}.\nBrisanje takvih stranica je ograničeno da bi se sprečilo slučajno opterećenje servera.",
        "delete-warning-toobig": "Ova stranica ima veliku istoriju izmena, preko $1 {{PLURAL:$1|izmena|izmene|izmena}}.\nNjeno brisanje može da poremeti bazu podataka, stoga postupajte s oprezom.",
        "protect-cascadeon": "Ova stranica je trenutno zaštićena jer je uključena u {{PLURAL:$1|sledeću stranicu koja ima|sledeće stranice koje imaju}} uključenu prenosivu zaštitu.\nPromene nivoa zaštite ove stranice neće da utiču na prenosivu zaštitu.",
        "protect-default": "Dozvoljeno svim korisnicima",
        "protect-fallback": "Dozvoljeno samo korisnicima sa dozvolom „$1“",
-       "protect-level-autoconfirmed": "Dopušteno samo automatski potvrđenim korisnicima",
-       "protect-level-sysop": "Dopušteno samo administratorima",
+       "protect-level-autoconfirmed": "Dozvoljeno samo automatski potvrđenim korisnicima",
+       "protect-level-sysop": "Dozvoljeno samo administratorima",
        "protect-summary-desc": "[$1=$2] ($3)",
        "protect-summary-cascade": "prenosiva zaštita",
        "protect-expiring": "ističe $1 (UTC)",
        "lockedbyandtime": "(od $1 dana $2 u $3)",
        "move-page": "Premeštanje stranice „$1”",
        "move-page-legend": "Premeštanje stranice",
-       "movepagetext": "Donji obrazac će preimenovati stranicu, premeštajući celu istoriju na novo ime.\nStari naslov postaće preusmerenje na novi.\nMožete ažurirati preusmerenja koja vode do izvornog naslova;\npogledajte [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|pokvarena]] preusmerenja.\nNa vama je odgovornost da veze i dalje idu tamo gde treba.\n\nStranica <strong>neće</strong> biti premeštena ako već postoji stranica s tim imenom (osim ako je prazna, sadrži preusmerenje ili nema istoriju izmena).\nTo znači da možete vratiti stranicu na prethodno ime ako pogrešite, ali ne možete ''prepisati'' postojeću.\n\n<strong>Napomena:</strong>\nOvo može predstavljati drastičnu i neočekivanu izmenu za popularnu stranicu;\ndobro razmislite o posledicama pre nego što nastavite.",
-       "movepagetext-noredirectfixer": "Donji obrazac će preimenovati stranicu, premeštajući celu istoriju na novo ime.\nStari naslov postaće preusmerenje na novi.\nPogledajte [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|pokvarena]] preusmerenja.\nNa vama je odgovornost da veze i dalje idu tamo gde treba.\n\nStranica <strong>neće</strong> biti premeštena ako već postoji stranica s tim imenom (osim ako je prazna, sadrži preusmerenje ili nema istoriju izmena).\nTo znači da možete vratiti stranicu na prethodno ime ako pogrešite, ali ne možete ''prepisati'' postojeću.\n\n<strong>Napomena:</strong>\nOvo može predstavljati drastičnu i neočekivanu izmenu za popularnu stranicu;\ndobro razmislite o posledicama pre nego što nastavite.",
-       "movepagetalktext": "Ako ste označili ovaj kvadratić, odgovarajuća stranica za razgovor biće automatski premeštena na novi naslov, osim ako već postoji stranica za razgovor sa istim naslovom.\n\nU tom slučaju, moraćete ručno da je premestite ili spojite, ako ima potrebe za tim.",
+       "movepagetext": "Korišćenje obrasca ispod preimenovaće stranicu, premeštajući celu njenu istoriju na novo ime.\nStari naslov postaće preusmeravanje na novi.\nAutomatski možete ažurirati preusmeravanja koja vode na originalni naslov.\nAko se odlučite da ne želite, obavezno proverite da li postoje [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|pokvarena]] preusmeravanja.\nOdgovorni ste da osigurate da veze nastave da vode tamo gde treba.\n\nZapamtite da stranica <strong>neće</strong> biti premeštena ako već postoji stranica na novom naslovu, osim ako je ova druga preusmeravanje i nema raniju istoriju izmena.\nTo znači da možete da preimenujete stranicu natrag odakle je preimenovana ako napravite grešku, ali ne možete prepisati postojeću stranicu.\n\n<strong>Napomena:</strong>\nOvo može predstavljati drastičnu i neočekivanu promenu za popularnu stranicu;\nbudite sigurni da razumete posledice ovoga pre nego što nastavite.",
+       "movepagetext-noredirectfixer": "Korišćenje obrasca ispod preimenovaće stranicu, premeštajući celu njenu istoriju na novo ime.\nStari naslov postaće preusmeravanje na novi.\nObavezno proverite da li postoje [[Special:DoubleRedirects|dvostruka]] ili [[Special:BrokenRedirects|pokvarena]] preusmeravanja.\nOdgovorni ste da osigurate da veze nastave da vode tamo gde treba.\n\nZapamtite da stranica <strong>neće</strong> biti premeštena ako već postoji stranica na novom naslovu, osim ako je ona preusmeravanje i nema raniju istoriju izmena.\nTo znači da možete da preimenujete stranicu natrag odakle je preimenovana ako napravite grešku, ali ne možete prepisati postojeću stranicu.\n\n<strong>Napomena:</strong>\nOvo može predstavljati drastičnu i neočekivanu promenu za popularnu stranicu;\nbudite sigurni da razumete posledice ovoga pre nego što nastavite.",
+       "movepagetalktext": "Ako potvrdite izbor u ovom polju za potvrdu, povezana stranica za razgovor biće automatski premeštena na novi naslov, osim ako ovde već postoji stranica za razgovor sa istim naslovom koja nije prazna.\n\nU tom slučaju, moraćete ručno da je premestite ili objedinite, ako ima potrebe za tim.",
        "moveuserpage-warning": "'''Upozorenje:''' na putu ste da premestite korisničku stranicu. Imajte u vidu da će samo stranica biti premeštena, a sam korisnik ''neće'' biti preimenovan.",
        "movecategorypage-warning": "<strong>Upozorenje:</strong> premeštate stranicu kategorije. Imajte na umu da će samo stranica biti premeštena i da sve stranice u staroj kategoriji <em>neće</em> biti rekategorisane u novu kategoriju.",
        "movenologintext": "Morate da budete registrovani i [[Special:UserLogin|prijavljeni]] da biste premeštali stranice.",
        "movepagebtn": "Premesti stranicu",
        "pagemovedsub": "Uspešno premeštanje",
        "movepage-moved": "<strong>Stranica „$1“ je premeštena na naslov „$2“</strong>",
-       "movepage-moved-redirect": "Preusmerenje je napravljeno.",
+       "movepage-moved-redirect": "Preusmeravanje je napravljeno.",
        "movepage-moved-noredirect": "Stvaranje preusmerenja je onemogućeno.",
        "movepage-delete-first": "Ciljna stranica ima previše izmena za brisanje kao deo premeštanja stranice.  Prvo ručno izbrišite stranicu, pa pokušajte ponovo.",
        "articleexists": "Stranica sa tim imenom već postoji ili ime koje ste odabrali nije važeće.\nOdaberite drugo.",
        "imagetypemismatch": "Proširenje nove datoteke se ne poklapa s njenim tipom.",
        "imageinvalidfilename": "Ciljano ime datoteke je nevažeće",
        "fix-double-redirects": "Ažurirajte sva preusmerenja koja vode do prvobitnog naslova",
-       "move-leave-redirect": "Ostavi preusmerenje",
+       "move-leave-redirect": "Ostavi preusmeravanje",
        "protectedpagemovewarning": "'''Upozorenje:''' Ova stranica je zaštićena, tako da samo korisnici sa administratorskim ovlašćenjima mogu da je premeste.\nNajnoviji unos u dnevniku je naveden ispod kao referenca:",
        "semiprotectedpagemovewarning": "<strong>Napomena:</strong> Ova stranica je zaštićena, tako da samo automatski potvrđeni korisnici mogu da je premeste.\nNajnoviji unos u dnevniku je naveden ispod kao referenca:",
        "move-over-sharedrepo": "[[:$1]] se nalazi na deljenom skladištu. Ako premestite datoteku na ovaj naslov, to će zameniti deljenu datoteku.",
        "tooltip-ca-nstab-category": "Pogledajte stranicu kategorije",
        "tooltip-minoredit": "Označite ovu izmenu kao manju",
        "tooltip-save": "Sačuvajte svoje promene",
-       "tooltip-publish": "Objavite svoje izmene",
+       "tooltip-publish": "Objavite promene",
        "tooltip-preview": "Pregledajte promene. Koristite ovo dugme pre čuvanja.",
        "tooltip-diff": "Pogledajte koje promene ste napravili na tekstu",
        "tooltip-compareselectedversions": "Pogledajte razlike između dve izabrane izmene ove stranice",
        "creditspage": "Autori stranice",
        "nocredits": "Ne postoje podaci o autoru ove stranice.",
        "spamprotectiontitle": "Filter za zaštitu od nepoželjnih poruka",
-       "spamprotectiontext": "Filtera protiv neželjenih poruka je blokirao čuvanje ove stranice.\nOvo je verovatno izazvano vezom do spoljašnjeg sajta koji se nalazi na crnoj listi.",
+       "spamprotectiontext": "Filter nepoželjnog sadržaja blokirao je tekst koji ste želeli da sačuvate.\nOvo je verovatno izazvano vezom do spoljašnjeg sajta koji se nalazi na crnom spisku.",
        "spamprotectionmatch": "Sledeći tekst je aktivirao naš filter za neželjene poruke: $1",
        "spambot_username": "Čišćenje nepoželjnih poruka u Medijavikiji",
        "spam_reverting": "Vraćam na poslednju izmenu koja ne sadrži veze do $1",
        "exif-usageterms": "Pravila korišćenja",
        "exif-webstatement": "Izjava o autorskom pravu",
        "exif-originaldocumentid": "Jedinstveni ID izvornog dokumenta",
-       "exif-licenseurl": "Adresa licence za autorska prava",
+       "exif-licenseurl": "URL adresa licence za autorska prava",
        "exif-morepermissionsurl": "Rezervni podaci o licenciranju",
        "exif-attributionurl": "Pri ponovnom korišćenju ovog rada, koristite vezu do",
        "exif-preferredattributionname": "Pri ponovnom korišćenju ovog rada, postavite zasluge",
        "exif-contentwarning": "Upozorenje o sadržaju",
        "exif-giffilecomment": "Komentar na datoteku GIF",
        "exif-intellectualgenre": "Tip stavke",
-       "exif-subjectnewscode": "Kod predmeta",
+       "exif-subjectnewscode": "Kod teme",
        "exif-scenecode": "IPTC kod scene",
        "exif-event": "Prikazani događaj",
        "exif-organisationinimage": "Prikazana organizacija",
        "imgmultipageprev": "← prethodna stranica",
        "imgmultipagenext": "sledeća stranica →",
        "imgmultigo": "Idi!",
-       "imgmultigoto": "Idi na stranicu $1",
+       "imgmultigoto": "Pređi na stranicu $1",
        "img-lang-opt": "$2 ($1)",
        "img-lang-default": "(podrazumevani jezik)",
        "img-lang-info": "Renderuj ovu sliku u $1. $2",
        "table_pager_empty": "Nema rezultata",
        "autosumm-blank": "Uklonjen celokupan sadržaj stranice",
        "autosumm-replace": "Zamenjen sadržaj stranice sa „$1“",
-       "autoredircomment": "Preusmerenje na [[$1]]",
-       "autosumm-removed-redirect": "Uklonjeno preusmerenje ka [[$1]]",
+       "autoredircomment": "Preusmerena stranica na [[$1]]",
+       "autosumm-removed-redirect": "Uklonjeno preusmeravanje na [[$1]]",
        "autosumm-changed-redirect-target": "Promenjena odredišna stranica u preusmerenju iz [[$1]] u [[$2]]",
        "autosumm-new": "Nova stranica: $1",
        "autosumm-newblank": "Napravljena prazna stranica",
        "version-software": "Instalirani softver",
        "version-software-product": "Proizvod",
        "version-software-version": "Verzija",
-       "version-entrypoints": "Adrese ulazne tačke",
+       "version-entrypoints": "URL adrese ulazne tačke",
        "version-entrypoints-header-entrypoint": "Ulazna tačka",
-       "version-entrypoints-header-url": "Adresa",
+       "version-entrypoints-header-url": "URL adresa",
        "version-entrypoints-articlepath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgArticlePath Article path]",
        "version-entrypoints-scriptpath": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Manual:$wgScriptPath Script path]",
        "version-libraries": "Instalirane biblioteke",
        "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|oznaka|oznake}}]]: $2",
        "tag-mw-contentmodelchange": "promena modela sadržaja",
        "tag-mw-contentmodelchange-description": "Izmene koje [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel menjaju model sadržaja] stranice",
-       "tag-mw-new-redirect": "novo preusmerenje",
-       "tag-mw-new-redirect-description": "Izmene kojima je napravljeno novo preusmerenje ili je stranica izmenjena da bude preusmerenje",
-       "tag-mw-removed-redirect": "uklonjeno preusmerenje",
-       "tag-mw-removed-redirect-description": "Izmene koje menjaju postojeće preusmerenje u stranicu bez preusmerenja",
+       "tag-mw-new-redirect": "novo preusmeravanje",
+       "tag-mw-new-redirect-description": "Izmene kojima je napravljeno novo preusmeravanje ili je stranica promenjena u preusmeravanje",
+       "tag-mw-removed-redirect": "uklonjeno preusmeravanje",
+       "tag-mw-removed-redirect-description": "Izmene koje menjaju postojeće preusmeravanje u nepreusmeravanje",
        "tag-mw-changed-redirect-target": "promenjeno odredište preusmerenja",
        "tag-mw-changed-redirect-target-description": "Izmene koje menjaju odredište preusmerenja",
        "tag-mw-blank": "stranica ispražnjena",
        "diff-form-submit": "Prikaži razlike",
        "permanentlink": "Trajna veza",
        "permanentlink-revid": "ID izmene",
-       "permanentlink-submit": "Idi na izmenu",
+       "permanentlink-submit": "Pređi na izmenu",
        "dberr-problems": "Došlo je do tehničkih problema.",
        "dberr-again": "Sačekajte nekoliko minuta i ponovo učitajte stranicu.",
        "dberr-info": "(Ne mogu pristupiti bazi podataka: $1)",
        "htmlform-user-not-exists": "<strong>$1</strong> ne postoji.",
        "htmlform-user-not-valid": "<strong>$1</strong> nije validno korisničko ime.",
        "logentry-delete-delete": "$1 je {{GENDER:$2|izbrisao|izbrisala}} stranicu $3",
-       "logentry-delete-delete_redir": "$1 je {{GENDER:$2|izbrisao|izbrisala}} preusmerenje $3 prepisivanjem",
+       "logentry-delete-delete_redir": "$1 je {{GENDER:$2|izbrisao|izbrisala}} preusmeravanje $3 prepisivanjem",
        "logentry-delete-restore": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3 ($4)",
        "logentry-delete-restore-nocount": "$1 je {{GENDER:$2|vratio|vratila}} stranicu $3",
        "restore-count-revisions": "{{PLURAL:$1|1 izmena|$1 izmene|$1 izmena}}",
        "logentry-block-unblock": "$1 je {{GENDER:$2|deblokirao|deblokirala}} {{GENDER:$4|$3}}",
        "logentry-block-reblock": "$1 je {{GENDER:$2|promenio|promenila}} podešavanja za blokiranje {{GENDER:$4|korisnika|korisnice}} {{GENDER:$4|$3}} u trajanju od $5 $6",
        "logentry-partialblock-block": "$1 je {{GENDER:$2|blokirao|blokirala}} uređivanje {{PLURAL:$8|stranice|stranica}} $7 {{GENDER:$4|korisniku|korisnici|korisniku/ci}} $3 sa vremenom isteka od $5 $6",
-       "logentry-non-editing-block-block": "$1 je {{GENDER:$2|blokirao|blokirala}} neuređivačke radnje {{GENDER:$4|korisniku|korisnici|korisniku/ci}} $3 sa vremenom isteka od $5 $6",
-       "logentry-non-editing-block-reblock": "$1 je {{GENDER:$2|promenio|promenila}} podešavanja blokade neuređivačkih radnji {{GENDER:$4|korisniku|korisnici|korisniku/ci}} $3 sa vremenom isteka od $5 $6",
+       "logentry-non-editing-block-block": "$1 je {{GENDER:$2|blokirao|blokirala}} određene neuređivačke radnje {{GENDER:$4|korisniku|korisnici|korisniku/ci}} $3 sa vremenom isteka od $5 $6",
+       "logentry-non-editing-block-reblock": "$1 je {{GENDER:$2|promenio|promenila}} podešavanja blokade određenih neuređivačkih radnji {{GENDER:$4|korisniku|korisnici|korisniku/ci}} $3 sa vremenom isteka od $5 $6",
        "logentry-suppress-block": "$1 je {{GENDER:$2|blokirao|blokirala}} {{GENDER:$4|$3}} u trajanju od $5 $6",
        "logentry-suppress-reblock": "$1 je {{GENDER:$2|promenio|promenila}} podešavanja za blokiranje {{GENDER:$4|korisnika|korisnice}} {{GENDER:$4|$3}} u trajanju od $5 $6",
        "logentry-import-upload": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 otpremanjem datoteke",
        "logentry-import-upload-details": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 otpremanjem datoteke ($4 {{PLURAL:$4|izmena|izmene|izmena}})",
        "logentry-import-interwiki": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 s drugog vikija",
        "logentry-import-interwiki-details": "$1 je {{GENDER:$2|uvezao|uvezla}} $3 iz $5 ($4 {{PLURAL:$4|izmena|izmene|izmena}})",
-       "logentry-merge-merge": "$1 je {{GENDER:$2|spojio|spojila}} $3 u $4 (sve do izmene $5)",
+       "logentry-merge-merge": "$1 je {{GENDER:$2|objedinio|objedinila}} $3 u $4 (sve do izmene $5)",
        "logentry-move-move": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4",
        "logentry-move-move-noredirect": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4 bez ostavljanja preusmerenja",
        "logentry-move-move_redir": "$1 je {{GENDER:$2|premestio|premestila}} stranicu $3 na $4 preko preusmerenja",
        "feedback-close": "Gotovo",
        "feedback-external-bug-report-button": "Arhiviraj tehnički zadatak",
        "feedback-dialog-title": "Slanje povratnih informacija",
+       "feedback-dialog-intro": "Možete da koristite jednostavni obrazac ispod kako biste poslali povratne informacije. Vaš komentar će biti dodat na stranicu „$1”, zajedno sa vašim korisničim imenom.",
        "feedback-error1": "Greška: neprepoznat rezultat od API-ja",
        "feedback-error2": "Greška: uređivanje nije uspelo",
        "feedback-error3": "Greška: nema odgovora od API-ja",
        "special-characters-title-endash": "crtica",
        "special-characters-title-emdash": "duga crta",
        "special-characters-title-minus": "znak za minus",
-       "mw-widgets-abandonedit": "Da li ste sigurni da želite da se vratite na prikaz bez prethodnog čuvanja?",
-       "mw-widgets-abandonedit-discard": "Zanemari izmene",
+       "mw-widgets-abandonedit": "!!FUZZY!!Želite li zaista da napustite režim uređivanja bez prethodnog čuvanja izmena?",
+       "mw-widgets-abandonedit-discard": "!!FUZZY!!Odbaci izmene",
        "mw-widgets-abandonedit-keep": "Nastavi sa uređivanjem",
        "mw-widgets-abandonedit-title": "Jeste li sigurni?",
        "mw-widgets-dateinput-no-date": "Datum nije izabran",
        "pagedata-bad-title": "Nevalidan naslov: $1.",
        "unregistered-user-config": "Iz bezbedonosnih razloga JavaScript, CSS i JSON korisničke podstranice ne mogu biti učitane za neregistrovane korisnike.",
        "passwordpolicies": "Pravila za lozinke",
-       "passwordpolicies-summary": "Ovo je lista efikasnih smernica za lozinke za korisničke grupe definisane na ovom vikiju.",
+       "passwordpolicies-summary": "Ovo je spisak efikasnih smernica za lozinke za korisničke grupe definisane na ovom vikiju.",
        "passwordpolicies-group": "Grupa",
        "passwordpolicies-policies": "Pravila",
        "passwordpolicies-policy-display": "<span class=\"passwordpolicies-policy\">$1 <code>($2)</code></span>",
        "passwordpolicies-policy-minimalpasswordlength": "Lozinka mora da ima najmanje {{PLURAL:$1|jedan znak|$1 znaka|$1 znakova}}",
        "passwordpolicies-policy-minimumpasswordlengthtologin": "Lozinka mora sadržati najmanje $1 {{PLURAL:$1|karakter|karaktera}} da bi ste mogli da se prijavite.",
        "passwordpolicies-policy-passwordcannotmatchusername": "Lozinka ne može da bude ista kao korisničko ime",
-       "passwordpolicies-policy-passwordcannotmatchblacklist": "Lozinka se ne može podudarati sa lozinkama na crnoj listi",
+       "passwordpolicies-policy-passwordcannotmatchblacklist": "Lozinka se ne može podudarati sa lozinkama na crnom spisku",
        "passwordpolicies-policy-maximalpasswordlength": "Lozinka mora da bude kraća od $1 {{PLURAL:$1|znaka|znakova}}",
        "passwordpolicies-policy-passwordcannotbepopular": "Lozinka ne može da bude {{PLURAL:$1|popularna lozinka|na spisku $1 popularnih lozinki}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Lozinka ne može da bude na listi 100.000 najčešće korišćenih lozinki.",
        "unprotected-js": "Iz bezbednosnih razloga, JavaScript ne može da se učita sa nezaštićene stranice. Samo napravite JavaScript u imenskom prostoru „Medijaviki:” ili kao korisničku podstranicu"
 }
index 57a0005..adeede7 100644 (file)
        "prefs-editor": "Éditor",
        "prefs-preview": "Pratayang",
        "prefs-advancedrc": "Pilihan lengkep",
-       "prefs-opt-out": "Nyisihkeun ropéaan",
        "prefs-advancedrendering": "Pilihan lengkep",
        "prefs-advancedsearchoptions": "Pilihan lengkep",
        "prefs-advancedwatchlist": "Pilihan lengkep",
        "filehist-filesize": "Ukuran berkas",
        "filehist-comment": "Kamandang",
        "imagelinks": "Pamakéan berkas",
-       "linkstoimage": "Kaca ieu  {{PLURAL:$1|numbu|$1 numbu}} ka gambar ieu :",
-       "linkstoimage-more": "Leuwih ti $1 {{PLURAL:$1|kaca nutumbu|kaca nutumbu}} ka ieu berkas.\nBéréndélan di handap némbongkeun {{PLURAL:$1|tutumbu kaca kahiji|$1 tutumbu kaca kahiji}} ka ieu berkas hungkul.\n[[Special:WhatLinksHere/$2|Béréndélan lengkepna]] ogé aya.",
-       "nolinkstoimage": "Teu aya kaca anu nutumbu ka ieu berkas.",
+       "linkstoimage": "Ieu berkas dipaké ku {{PLURAL:$1|kaca|$1 kaca}} di handap:",
+       "linkstoimage-more": "Leuwih ti $1 {{PLURAL:$1|kaca|kaca}} nu maké ieu berkas.\nBéréndélan di handap némbongkeun {{PLURAL:$1|kaca kahiji|$1 kaca mimiti}} nu maké ieu berkas hungkul.\n[[Special:WhatLinksHere/$2|Béréndélan lengkepna]] ogé aya.",
+       "nolinkstoimage": "Euweuh kaca anu maké ieu berkas.",
        "morelinkstoimage": "Témbong [[Special:WhatLinksHere/$1|tutumbu lianna]] ka ieu berkas.",
        "linkstoimage-redirect": "$1 (pangalihan berkas) $2",
        "sharedupload": "Ieu berkas téh ti $1 jeung meureun dipaké ku proyék-proyék séjén.",
index 401459c..e4ed687 100644 (file)
        "passwordtooshort": "Lösenord måste innehålla minst {{PLURAL:$1|$1 tecken}}.",
        "passwordtoolong": "Lösenord kan inte vara längre än {{PLURAL:$1|1 tecken|$1 tecken}}.",
        "passwordtoopopular": "Vanliga lösenord kan inte användas. Välj ett lösenord som är svårare att gissa.",
+       "passwordinlargeblacklist": "Det angivna lösenordet är med i en lista över mycket vanliga lösenord. Välj ett unikare lösenord.",
        "password-name-match": "Ditt lösenord måste vara olikt ditt användarnamn.",
        "password-login-forbidden": "Användningen av dessa användarnamn och lösenord har förbjudits.",
        "mailmypassword": "Återställ lösenord",
        "timezonelegend": "Tidszon:",
        "localtime": "Lokal tid:",
        "timezoneuseserverdefault": "Använd wikins standard ($1)",
-       "timezoneuseoffset": "Annan (specificera skillnad)",
+       "timezoneuseoffset": "Annan (specificera skillnad nedan)",
+       "timezone-useoffset-placeholder": "Exempelvärden: \"-07:00\" eller \"01:00\"",
        "servertime": "Serverns tid:",
        "guesstimezone": "Fyll i från webbläsare",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Redigerare",
        "prefs-preview": "Förhandsvisa",
        "prefs-advancedrc": "Avancerade alternativ",
-       "prefs-opt-out": "Välj bort förbättringar",
        "prefs-advancedrendering": "Avancerade alternativ",
        "prefs-advancedsearchoptions": "Avancerade alternativ",
        "prefs-advancedwatchlist": "Avancerade alternativ",
        "rcfilters-watchlist-markseen-button": "Markera alla ändringar som sedda",
        "rcfilters-watchlist-edit-watchlist-button": "Redigera din lista över bevakade sidor",
        "rcfilters-watchlist-showupdated": "Sidor som har ändrats sedan ditt senaste besök visas i <strong>fetstil</strong> med färgmarkering.",
-       "rcfilters-preference-label": "Dölj den förbättrade versionen av Senaste ändringar",
-       "rcfilters-preference-help": "Stänger det nydesignade gränssnittet från 2017 och alla verktyg som lades till från och med då.",
-       "rcfilters-watchlist-preference-label": "Dölj det förbättrade versionen av bevakningslistan",
-       "rcfilters-watchlist-preference-help": "Rullar tillbaka det omdesignade gränssnittet från 2017 och alla verktyg som lades till då och efteråt.",
+       "rcfilters-preference-label": "Använd gränssnitt som inte använder JavaScript",
+       "rcfilters-preference-help": "Läser in senaste ändringarna utan filter eller markeringsfunktionalitet.",
+       "rcfilters-watchlist-preference-label": "Använd gränssnitt som inte använder JavaScript",
+       "rcfilters-watchlist-preference-help": "Läser in bevakningslistan utan filter eller markeringsfunktionalitet.",
        "rcfilters-filter-showlinkedfrom-label": "Visa ändringar på sidor som länkas från",
        "rcfilters-filter-showlinkedfrom-option-label": "<strong>Sidor som länkas från</strong> den valda sidan",
        "rcfilters-filter-showlinkedto-label": "Visa ändringar på sidor som länkar till",
        "logentry-block-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningar för {{GENDER:$4|$3}} med en varaktighet på $5 $6",
        "logentry-partialblock-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} från att redigera {{PLURAL:$8||sidorna}} $7 med en varaktighet på $5 $6",
        "logentry-partialblock-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningarna för {{GENDER:$4|$3}} som förhindrar redigeringar på {{PLURAL:$8||sidorna}} $7 med en varaktighet på $5 $6",
-       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} från icke-redigerande handlingar med en varaktighet på $5 $6",
-       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningarna för {{GENDER:$4|$3}} för icke-redigerande handlingar med en varaktighet på $5 $6",
+       "logentry-non-editing-block-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} från specificerade icke-redigerande handlingar med en varaktighet på $5 $6",
+       "logentry-non-editing-block-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningarna för {{GENDER:$4|$3}} för specificerade icke-redigerande handlingar med en varaktighet på $5 $6",
        "logentry-suppress-block": "$1 {{GENDER:$2|blockerade}} {{GENDER:$4|$3}} med en varaktighet på $5 $6",
        "logentry-suppress-reblock": "$1 {{GENDER:$2|ändrade}} blockeringsinställningar för {{GENDER:$4|$3}} med en varaktighet på $5 $6",
        "logentry-import-upload": "$1 {{GENDER:$2|importerade}} $3 genom filuppladdning",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "Lösenordet kan inte matcha specifikt svartlistade lösenord",
        "passwordpolicies-policy-maximalpasswordlength": "Lösenordet måste vara högst $1 {{PLURAL:$1|tecken}} långt",
        "passwordpolicies-policy-passwordcannotbepopular": "Lösenordet kan inte vara {{PLURAL:$1|det populäraste lösenordet|i listan över de $1 populäraste lösenorden}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "Lösenordet kan inte vara med i listan över de 100 000 vanligaste lösenorden.",
        "easydeflate-invaliddeflate": "Innehåll som tillhandahålls är inte helt komprimerat",
        "unprotected-js": "Av säkerhetsskäl kan inte JavaScript läsas in från oskyddade sidor. Skapa endast JavaScript i namnrymden MediaWiki: eller som en användarundersida."
 }
index fa77b2b..f22f0f5 100644 (file)
        "wrongpasswordempty": "ಖಾಲಿ ಪ್ರವೇಶ ಪದ ಕೊರ್ತರ್. ನನ ಒರ ಪ್ರಯತ್ನ ಮಲ್ಪುಲೆ.",
        "passwordtooshort": "ಪ್ರವೇಶ ಪದಟ್ ಕನಿಷ್ಟ {{PLURAL:$1|೧ ಅಕ್ಷರ|$1 ಅಕ್ಷರರೊಳೆನ್}} ಉಪ್ಪೊಡ್",
        "passwordtoolong": "ಪ್ರವೇಸೊ ಪದೊಟು ಕನಿಸ್ಟೊ {{PLURAL:$1|೧ ಅಕ್ಷರ|$1 ಅಕ್ಷರರೊಲು}} ಉಪ್ಪೊಡ್",
+       "passwordinlargeblacklist": "ಸೇರಾಯಿನ ಪ್ರವೇಶಪದ ಅತಿ ಸಾಮಾನ್ಯವಾದ್ ಬಳಕೆ ಮಲ್ಪುನ ಪ್ರವೇಶಪದೊಕುಲೆನ ಒಂಜಿ ಪಟ್ಟಿಡ್ ಉಂಡು.ದಯಮಲ್ತ್ ಬೇತೆ ಅನನ್ಯ ಪ್ರವೇಶಪದೊನು ಆಯ್ಕೆ ಮಲ್ಪುಲೆ.",
        "password-name-match": "ಇರೆನ್ ಪ್ರವೇಶಪದ ಬಳಕೆದಾರೆನ ಪುದರ್‘ಡ್‘ದ್ ಬೇತೆ ಉಪ್ಪೊಡು",
        "password-login-forbidden": "ಈ ಪ್ರವೇಶಪದ ಬೊಕ್ಕ ಬಳಕೆದಾರೆರೆನ ಪುದರ್‘ನ್ ನಿಷಿದ್ಧ ಮಲ್ತ್‘ದ್ಂಡ್",
        "mailmypassword": "ಪ್ರವೇಸೊ ಪದೊನ್ ಪಿರ ಸ್ತಾಪನೆ ಮಲ್ಪುಲೆ",
        "mw-widgets-usersmultiselect-placeholder": "ನನಾತ್ ಸೇರಲೇ...",
        "date-range-from": "ತಾರಿಕ್‌ಡ್ದ್:",
        "date-range-to": "ತಾರಿಕ್ ಮುಟ:",
-       "randomrootpage": "ಒವ್ವಾಂಡಲ ಮೂಲಪುಟೊ"
+       "randomrootpage": "ಒವ್ವಾಂಡಲ ಮೂಲಪುಟೊ",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "ಪ್ರವೇಶಪದ ಅತಿ ಸಾಮಾನ್ಯವಾದ್ ಬಳಕೆ ಮಲ್ಪುನ ೧೦೦,೦೦೦ ಪದೊಕುಲೆನ ಪಟ್ಟಿಡ್ ಉಪ್ಪರೆ ಬಲ್ಲಿ."
 }
index 7683075..0d8a411 100644 (file)
        "prefs-editor": "రచయిత",
        "prefs-preview": "మునుజూపు",
        "prefs-advancedrc": "ఉన్నత ఎంపికలు",
-       "prefs-opt-out": "మెరుగుదలల నుండి తప్పుకోండి",
        "prefs-advancedrendering": "ఉన్నత ఎంపికలు",
        "prefs-advancedsearchoptions": "ఉన్నత ఎంపికలు",
        "prefs-advancedwatchlist": "ఉన్నత ఎంపికలు",
index b64d777..6856062 100644 (file)
        "prefs-editor": "ตัวแก้ไข",
        "prefs-preview": "การแสดงตัวอย่าง",
        "prefs-advancedrc": "ตัวเลือกขั้นสูง",
-       "prefs-opt-out": "เลือกไม่ปรับปรุง",
        "prefs-advancedrendering": "ตัวเลือกขั้นสูง",
        "prefs-advancedsearchoptions": "ตัวเลือกขั้นสูง",
        "prefs-advancedwatchlist": "ตัวเลือกขั้นสูง",
index aab8a07..7b329b9 100644 (file)
        "localtime": "Yerel saat:",
        "timezoneuseserverdefault": "Viki varsayılanını kullanın ($1)",
        "timezoneuseoffset": "Diğer (ofset belirtin)",
+       "timezone-useoffset-placeholder": "Örnek değerler: \"-07:00\" veya \"01:00\"",
        "servertime": "Sunucu saati:",
        "guesstimezone": "Tarayıcınız sizin yerinize doldursun",
        "timezoneregion-africa": "Afrika",
        "prefs-editor": "Editör",
        "prefs-preview": "Önizleme",
        "prefs-advancedrc": "Gelişmiş seçenekler",
-       "prefs-opt-out": "İyileştirmeleri devre dışı bırak",
        "prefs-advancedrendering": "Gelişmiş seçenekler",
        "prefs-advancedsearchoptions": "Gelişmiş seçenekler",
        "prefs-advancedwatchlist": "Gelişmiş seçenekler",
        "prefs-displayrc": "Görüntüleme seçenekleri",
        "prefs-displaywatchlist": "Görüntüleme seçenekleri",
+       "prefs-pageswatchlist": "İzlenen sayfalar",
        "prefs-tokenwatchlist": "Anahtar",
        "prefs-diffs": "Farklar",
        "prefs-help-prefershttps": "Bu tercih bir sonraki girişinizde etkili olacaktır.",
        "grant-group-file-interaction": "Medya ile etkileşim kur",
        "grant-group-watchlist-interaction": "İzleme listenle etkileşim kur",
        "grant-group-email": "E-posta gönder",
+       "grant-group-high-volume": "Yüksek hacimli etkinlik gerçekleştir",
        "grant-group-customization": "Özelleştirme ve tercihler",
        "grant-group-private-information": "Sizinle ilgili özel verilere erişme",
        "grant-group-other": "Çeşitli aktivite",
        "rcfilters-filter-watchlistactivity-unseen-label": "Görülmemiş değişiklikler",
        "rcfilters-filter-watchlistactivity-unseen-description": "Değişiklikler gerçekleştiğinden beri ziyaret etmediğiniz sayfalardaki değişiklikler.",
        "rcfilters-filter-watchlistactivity-seen-label": "Görülmüş değişiklikler",
+       "rcfilters-filter-watchlistactivity-seen-description": "Değişiklikler gerçekleştiğinden beri ziyaret ettiğiniz sayfalardaki değişiklikler",
        "rcfilters-filtergroup-changetype": "Değişiklik türü",
        "rcfilters-filter-pageedits-label": "Sayfa düzenlemeleri",
        "rcfilters-filter-pageedits-description": "Viki içeriği, tartışmalar, kategori açıklamalarındaki düzenlemeler...",
        "uploadstash-badtoken": "İşlemin gerçekleştirilmesi başarısız oldu, muhtemelen düzenleme yetkileriniz zaman aşımına uğradı. Lütfen yeniden deneyin.",
        "uploadstash-errclear": "Dosyaların silinmesi başarısız oldu.",
        "uploadstash-refresh": "Dosya listelerini yenile",
+       "uploadstash-thumbnail": "küçük resmi görüntüle",
        "uploadstash-bad-path-unknown-type": "Bilinmeyen tür \"$1\".",
        "uploadstash-bad-path-unrecognized-thumb-name": "Tanınmayan başparmak adı.",
        "invalid-chunk-offset": "Geçersiz öbek ofset",
index 63a9e59..015d275 100644 (file)
        "prefs-editor": "Мөхәррир",
        "prefs-preview": "Алдан карау",
        "prefs-advancedrc": "Киңәйтелгән көйләүләр",
-       "prefs-opt-out": "Яхшыртулардан баш тарту",
        "prefs-advancedrendering": "Киңәйтелгән көйләүләр",
        "prefs-advancedsearchoptions": "Киңәйтелгән көйләүләр",
        "prefs-advancedwatchlist": "Киңәйтелгән көйләүләр",
index 6191408..406b1b9 100644 (file)
        "timezonelegend": "Часовий пояс:",
        "localtime": "Місцевий час:",
        "timezoneuseserverdefault": "Використовувати стандартне налаштування вікі ($1)",
-       "timezoneuseoffset": "Інше (зазначте зміщення)",
+       "timezoneuseoffset": "Інше (нижче зазначте зміщення)",
+       "timezone-useoffset-placeholder": "Наприклад: «-07:00» або «01:00»",
        "servertime": "Час сервера:",
        "guesstimezone": "Заповнити з браузера",
        "timezoneregion-africa": "Африка",
        "prefs-editor": "Редактор",
        "prefs-preview": "Попередній перегляд",
        "prefs-advancedrc": "Розширені налаштування",
-       "prefs-opt-out": "Відмовитись від покращень",
        "prefs-advancedrendering": "Розширені налаштування",
        "prefs-advancedsearchoptions": "Розширені налаштування",
        "prefs-advancedwatchlist": "Розширені налаштування",
        "move-watch": "Спостерігати за цією сторінкою",
        "movepagebtn": "Перейменувати сторінку",
        "pagemovedsub": "Перейменування виконано",
-       "cannotmove": "СÑ\82оÑ\80Ñ\96нка Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ñ\83Ñ\82и Ð¿ÐµÑ\80ейменована Ð· {{PLURAL:$1|1=Ñ\82акоÑ\8a причини|таких причин}}:",
+       "cannotmove": "СÑ\82оÑ\80Ñ\96нка Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð±Ñ\83Ñ\82и Ð¿ÐµÑ\80ейменована Ð· {{PLURAL:$1|1=Ñ\82акоÑ\97 причини|таких причин}}:",
        "movepage-moved": "'''Сторінка «$1» перейменована на «$2»'''",
        "movepage-moved-redirect": "Створено перенаправлення.",
        "movepage-moved-noredirect": "Створення перенаправлення було заборонене.",
index 0a857dc..df7817d 100644 (file)
        "userlogin-createanother": "دوسرا کھاتہ تخلیق کریں",
        "createacct-emailrequired": "ای میل پتہ",
        "createacct-emailoptional": "برقی ڈاک پتا (اختیاری)",
-       "createacct-email-ph": "اپنا برقی پتہ لکھیں",
+       "createacct-email-ph": "اپنا برقی ڈاک پتا لکھیں",
        "createacct-another-email-ph": "برقی ڈاک پتا لکھیں",
        "createaccountmail": "عارضی پاسورڈ استعمال کریں اور اسے متعینہ برقی ڈاک پتہ پر ارسال کریں",
        "createaccountmail-help": "پاس ورڈ معلوم کیے بغیر کسی دوسرے شخص کا کھاتہ بنانے کے لیے اسے استعمال کیا جا سکتا ہے۔",
        "mailmypassword": "پاسورڈ تبدیل کریں",
        "passwordremindertitle": "نیا عارضی کلمۂ شناخت برائے {{SITENAME}}",
        "passwordremindertext": "(IP پتہ $1 سے) کسی (یا شاید آپ) نے {{SITENAME}} ($4)\nکے لیے نئے پاس ورڈ کی درخواست کی ہے۔ لہذا صارف \"$2\" کے لیے ایک عارضی پاس ورڈ \"$3\" بنا دیا گیا ہے۔\nاگر یہ اقدام بالارادہ تھا تو اب آپ لاگ ان ہونے کے بعد نیا پاس ورڈ رکھیں۔\nآپ کا درج بالا عارضی پاس ورڈ {{PLURAL:$5|ایک دِن|$5 دِنوں}} کے بعد ناکارہ ہوجائے گا۔\n\nاگر کسی اَور نے یہ درخواست کی ہے، یا آپ کو اپنا پاس ورڈ یاد آگیا ہے اور آپ اسے تبدیل نہیں کرنا چاہتے تو آپ یہ پیغام نظر انداز کرکے اپنے پرانے پاس ورڈ کا استعمال جاری رکھ سکتے ہیں۔",
-       "noemail": "صارف \"$1\" کیلئے کوئی برقی پتہ درج نہیں کیا گیا.",
-       "noemailcreate": "صحیح برقی پتہ مہیّا کریں",
+       "noemail": "صارف \"$1\" کا کوئی برقی ڈاک پتا درج نہیں کیا گیا۔",
+       "noemailcreate": "صحیح برقی ڈاک پتا فراہم کریں۔",
        "passwordsent": "ایک نیا کلمۂ شناخت \"$1\" کے نام سے بننے والی برقی ڈاک کے پتے کیلیے بھیج دیا گیا ہے۔\nجب وہ موصول ہو جاۓ تو براہ کرم اسکے ذریعے دوبارہ داخل ہوں۔",
        "blocked-mailpassword": "آپ کے آئی پی پتے کی ترمیم کاری پر پابندی لگا دی گئی ہے۔ غلط استعمال سے بچنے کے لیے اس آئی پی پتے سے پاس ورڈ کی بازیابی کی اجازت منسوخ کر دی گئی ہے۔",
-       "eauthentsent": "ایک تصدیقی برقی خط نامزد کیے گئے برقی پتہ پر ارسال کردیا گیا ہے۔\nآپ کو موصول ہوئے برقی خط میں ہدایات پر عمل کرکے اس بات کی توثیق کرلیں کہ مذکورہ برقی پتہ آپ کا ہی ہے۔",
+       "eauthentsent": "ایک تصدیقی برقی خط درج کردہ برقی ڈاک پتے پر ارسال کردیا گیا ہے۔\nآپ کو موصول شدہ برقی خط میں موجود ہدایات پر عمل کرکے اس بات کی توثیق کرلیں کہ مذکورہ برقی ڈاک پتا آپ کا ہی ہے۔",
        "throttled-mailpassword": "گزشتہ {{PLURAL:$1|گھنٹے|$1 گھنٹوں}} کے دوران پہلے سے ہی پاسورڈ کی تبدیلی کے لیے برقی خط بھیجا گيا ہے۔\nناجائز استعمال کے سدّباب کے لیے، {{PLURAL:$1|گھنٹہ|$1 گھنٹوں}} کے دوران صرف ایک برقی خط بھیجا جا سکتا ہے۔",
        "mailerror": "مسلہ دوران ترسیل خط:$1",
        "acct_creation_throttle_hit": "آپکی آئی پی کے ذریعے اِس ویکی پر آنے والے صارفین نے پچھلے $2 میں {{PLURAL:$1|1 کھاتہ بنایا ہے|$1 کھاتے بنائے ہیں}} جو اس مدت کے لیے کافی ہیں۔\nلہٰذا آپ کی آئی پی استعمال کرنے والے صارفین اِس وقت مزید کھاتے نہیں بنا سکتے۔",
        "emailauthenticated": "آپ کے برقی ڈاک پتہ کی تصدیق مورخہ $2 بوقت $3 بجے ہوئی۔",
-       "emailnotauthenticated": "آپ کے برقی پتہ کی ابھی تصدیق نہیں ہوئی ہے۔\nدرج ذیل میں سے کسی بھی چیز کیلئے آپ کے برقی پتہ پر برقی ڈاک ارسال نہیں کی جائے گی۔",
+       "emailnotauthenticated": "آپ کے برقی ڈاک پتے کی ابھی تصدیق نہیں ہوئی ہے۔\nدرج ذیل میں سے کسی بھی چیز کے لیے آپ کے برقی ڈاک پتے پر برقی ڈاک ارسال نہیں کی جائے گی۔",
        "noemailprefs": "اِن خصائص کو کام میں لانے کیلئے اپنے ترجیحات میں برقی ڈاک کا پتہ متعین کیجئے.",
-       "emailconfirmlink": "اپنے برقی پتہ کی تصدیق کیجئے",
-       "invalidemailaddress": "برقی پتہ قبول نہیں کیا جاسکتا کیونکہ یہ غلط شکل میں ہے.\nبراہِ کرم! ایک برقی پتہ صحیح شکل میں درج کیجئے یا جگہ کو خالی چھوڑ دیجئے.",
-       "cannotchangeemail": "کھاتے کا برقی پتہ اس ویکی سے پر رہتے ہوئے نہیں تبدیل کیا جا سکتا۔",
+       "emailconfirmlink": "اپنے برقی ڈاک پتے کی تصدیق کریں",
+       "invalidemailaddress": "برقی ڈاک پتا قبول نہیں کیا جاسکتا کیونکہ یہ غلط شکل میں ہے۔\nبراہِ کرم اپنا برقی ڈاک پتا صحیح شکل میں درج کریں یا اس جگہ کو خالی چھوڑ دیں۔",
+       "cannotchangeemail": "اس ویکی پر کھاتے کا برقی ڈاک پتا تبدیل کیا جا سکتا۔",
        "emaildisabled": "اس سائٹ سے برقی خط نہیں بھیجے جاسکتے",
        "accountcreated": "تخلیقِ کھاتہ",
        "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|تبادلۂ خیال]]) کا صارف کھاتہ بن چکا ہے۔",
        "createaccount-title": "کھاتہ سازی برائے {{SITENAME}}",
-       "createaccount-text": "کسی نے {{SITENAME}} ($4) پر «$2» کے نام سے اور \"$3\" پاسورڈ کے ساتھ آپ کا برقی پتہ استعمال کرتے ہوئے کھاتہ بنایا ہے۔\nآپ کو چاہیے کہ ابھی لاگ ان ہو کر اپنا پاسورڈ تبدیل کر دیں۔\n\nاگر یہ کھاتہ غلطی سے بنا ہے، تو آپ یہ پیغام نظر انداز کر دیں۔",
+       "createaccount-text": "کسی نے {{SITENAME}} ($4) پر «$2» کے نام سے اور \"$3\" پاس ورڈ کے ساتھ آپ کا برقی ڈاک پتا استعمال کرتے ہوئے کھاتہ بنایا ہے۔\nچنانچہ آپ ابھی لاگ ان ہو کر اپنا پاس ورڈ تبدیل کر دیں۔\n\nاگر یہ کھاتہ غلطی سے بنا ہے، تو آپ اس پیغام کو نظر انداز کر سکتے ہیں۔",
        "login-throttled": "آپ نے حال ہی میں متعدد مرتبہ لاگ ان ہونے کی کوشش کی ہے۔\nدوبارہ کوشش کرنے سے پہلے $1 انتظار فرمائیے۔",
        "login-abort-generic": "لاگ ان ناکام - منسوخ شد",
        "login-migrated-generic": "آپ کا کھاتہ منتقل کر دیا گیا، اب اس ویکی پر آپ کا صارف نام موجود نہیں۔",
        "subject-preview": "عنوان/شہ سرخی کی نمائش:",
        "previewerrortext": "آپ کی تبدیلیوں کی نمائش دکھانے کے دوران میں کوئی نقص واقع ہو گیا ہے۔",
        "blockedtitle": "صارف مسدود ہے",
-       "blockedtext": "<strong>آپ کے صارف نام یا آئی پی پتہ پر پابندی لگائی جا چکی ہے۔</strong>\n\n$1 نے پابندی عائد کی اور یہ وجہ درج کی: <em>$2</em>\n\n* پابندی کی ابتدا : $8\n* پابندی کا اختتام : $6\n* ممنوع صارف: $7\n\nآپ $1 یا کسی دوسرے [[{{MediaWiki:Grouppage-sysop}}|منتظم]] سے رابطہ کر کے اس پابندی پر گفت و شنید کر سکتے ہیں۔\nواضح رہے کہ آپ «{{int:emailuser}}» کی سہولت اُس وقت تک استعمال نہیں کر سکتے جب تک آپ اپنے [[Special:Preferences|کھاتہ کی ترجیحات]] میں درست برقی پتا درج نہ کریں اور آپ کو اِسے استعمال کرنے سے روک نہ دیا گیا ہو۔\nآپ کا موجودہ آئی پی پتہ $3 ہے اور پابندی کا شناختی نمبر #$5 ہے۔\nاگر آپ پابندی سے متعلق کہیں استفسار کریں تو براہِ مہربانی اس میں درج بالا تمام تفصیلات شامل کریں۔",
-       "autoblockedtext": "آپ کے آئی پی پتے پر خودکار طور پر پابندی لگا دی گئی ہے کیونکہ اسے ایک ایسے صارف نے استعمال کیا تھا جس پر $1 نے پابندی لگا رکھی ہے۔\nپابندی کی وجہ یہ درج کی گئی:\n\n:<em>$2</em>\n\n*پابندی کی ابتدا: $8\n*پابندی کا اختتام: $6\n*ممنوع صارف: $7\n\nآپ $1 سے یا دوسرے [[{{MediaWiki:Grouppage-sysop}}|منتظمین]] سے رابطہ کر کے اس پابندی پر گفت و شنید کر سکتے ہیں۔\n\nیاد رکھیں کہ «{{int:emailuser}}» کی خاصیت اُس وقت تک استعمال نہیں کرسکتے جب تک آپ اپنے [[Special:Preferences|کھاتے کی ترجیحات]] میں صحیح برقی پتہ درج نہ کریں اور آپ کو اِسے استعمال کرنے سے روک نہ دیا گیا ہو۔\n\nآپ کا موجودہ آئی پی پتہ $3 ہے، اور پابندی کی شناخت #$5 ہے۔\nبراہِ مہربانی کسی بھی قسم کے استفسار میں درج بالا تمام تفصیلات شامل کریں۔",
+       "blockedtext": "<strong>آپ کے صارف نام یا آئی پی پتہ پر پابندی لگائی جا چکی ہے۔</strong>\n\n$1 نے پابندی عائد کی اور یہ وجہ درج کی: <em>$2</em>\n\n* پابندی کی ابتدا : $8\n* پابندی کا اختتام : $6\n* ممنوع صارف: $7\n\nآپ $1 یا کسی دوسرے [[{{MediaWiki:Grouppage-sysop}}|منتظم]] سے رابطہ کر کے اس پابندی پر گفت و شنید کر سکتے ہیں۔\nواضح رہے کہ آپ «{{int:emailuser}}» کی سہولت اُس وقت تک استعمال نہیں کر سکتے جب تک آپ اپنے [[Special:Preferences|کھاتہ کی ترجیحات]] میں درست برقی ڈاک پتا درج نہ کریں اور آپ کو اِسے استعمال کرنے سے روک نہ دیا گیا ہو۔\nآپ کا موجودہ آئی پی پتہ $3 ہے اور پابندی کا شناختی نمبر #$5 ہے۔\nاگر آپ پابندی سے متعلق کہیں استفسار کریں تو براہِ مہربانی اس میں درج بالا تمام تفصیلات شامل کریں۔",
+       "autoblockedtext": "آپ کے آئی پی پتے پر خودکار طور پر پابندی لگا دی گئی ہے کیونکہ اسے ایک ایسے صارف نے استعمال کیا تھا جس پر $1 نے پابندی لگا رکھی ہے۔\nپابندی کی وجہ یہ درج کی گئی:\n\n:<em>$2</em>\n\n*پابندی کی ابتدا: $8\n*پابندی کا اختتام: $6\n*ممنوع صارف: $7\n\nآپ $1 سے یا دیگر [[{{MediaWiki:Grouppage-sysop}}|منتظمین]] سے رابطہ کر کے اس پابندی پر گفت و شنید کر سکتے ہیں۔\n\nیاد رکھیں کہ آپ «{{int:emailuser}}» کی خاصیت اُس وقت تک استعمال نہیں کرسکتے جب تک آپ اپنے [[Special:Preferences|کھاتے کی ترجیحات]] میں صحیح برقی ڈاک پتا درج نہ کریں اور آپ کو اِسے استعمال کرنے سے روک نہ دیا گیا ہو۔\n\nآپ کا موجودہ آئی پی پتہ $3 ہے اور پابندی کا شناختی نمبر #$5 ہے۔\nبراہِ مہربانی کسی بھی قسم کے استفسار میں درج بالا تمام تفصیلات ضرور شامل کریں۔",
        "systemblockedtext": "آپ کے صارف نام یا آئی پی پتے پر میڈیاویکی کی جانب سے خودکار طریقے سے پابندی لگا دی گئی ہے۔\nاور وجہ یہ درج کی گئی ہے کہ:\n<em>$2</em>\n\n*پابندی کی ابتدا: $8\n*پابندی کا اختتام: $6\n*ممنوع صارف: $7\n\nآپ کا موجودہ آئی پی پتہ $3 ہے۔\nبراہِ مہربانی کسی بھی قسم کے استفسار میں درج بالا تمام تفصیلات شامل کریں۔",
        "blockednoreason": "کوئی وجہ نہیں دی گئی",
        "whitelistedittext": "ترمیم کیلئے $1 ضروری ہے.",
-       "confirmedittext": "صفحات میں ترمیم کرنے سے پہلے آپ اپنے برقی پتہ کی تصدیق کریں.\nبرائے مہربانی! اپنی [[Special:Preferences|ترجیحات]] کے ذریعے اپنا برقی پتہ کا تعیّن اور تصدیق کیجئے.",
+       "confirmedittext": "صفحات میں ترمیم کرنے سے پہلے آپ اپنے برقی ڈاک پتے کی تصدیق کریں۔\nبراہ مہربانی کھاتے کی [[Special:Preferences|ترجیحات]] میں اپنا برقی ڈاک پتا درج اور اس کی تصدیق کریں۔",
        "nosuchsectiontitle": "قطعہ نہیں ملا",
        "nosuchsectiontext": "آپ نے ایسے قطعہ میں ترمیم کی کوشش کی ہے جو کہ موجود نہیں.\nہوسکتا ہے کہ جب آپ صفحہ ملاحظہ فرمارہے تھے اُسی اثناء مذکورہ قطعہ کو منتقل یا حذف کردیا گیا ہو.",
        "loginreqtitle": "داخلہ / اندراج لازم",
        "cantcreateaccount-text": "[[User:$3|$3]] نے اس آئی پی پتہ (<strong>$1</strong>) کی کھاتہ سازی پر پابندی لگا رکھی ہے۔\n\n$3 نے «<em>$2</em>» وجہ بیان کی ہے",
        "cantcreateaccount-range-text": "[[User:$3|$3]] نے <strong>$1</strong> رینج کے آئی پی پتوں پر جس میں آپ کا آئی پی پتہ (<strong>$4</strong>) بھی موجود ہے پر پابندی لگا دی ہے۔\n\n$3 نے «<em>$2</em>» وجہ بیان کی ہے",
        "viewpagelogs": "اس صفحہ کے نوشتے دیکھیں",
-       "nohistory": "اِس صفحہ کیلئے کوئی تدوینی تاریخچہ موجود نہیں ہے.",
+       "nohistory": "اس صفحہ کا ترمیمی تاریخچہ موجود نہیں ہے۔",
        "currentrev": "تازہ ترین نسخہ",
        "currentrev-asof": "حالیہ نسخہ بمطابق $1",
        "revisionasof": "نسخہ بمطابق $1",
        "history-feed-title": "تاریخچہ ترمیم",
        "history-feed-description": "ویکی پر اِس صفحہ کا تاریخچۂ نظرثانی",
        "history-feed-item-nocomment": "بہ $2 $1",
-       "history-feed-empty": "درخواست شدہ صفحہ موجود نہیں.\nیا تو یہ ویکی سے حذف کیا گیا ہے اور یا اِس کا نام تبدیل کردیا گیا ہے.\nآپ متعلقہ نئے صفحات کیلئے [[Special:Search|ویکی پر تلاش]] کرسکتے ہیں.",
+       "history-feed-empty": "درخواست کردہ صفحہ موجود نہیں۔\nممکن ہے کہ اسے ویکی سے حذف کر دیا گیا ہو یا اِس کا نام تبدیل کردیا گیا ہو۔\nآپ متعلقہ نئے صفحات کو [[Special:Search|ویکی پر تلاش]] کرسکتے ہیں۔",
        "history-edit-tags": "منتخب نظرثانیوں کے ٹیگوں میں ترمیم کریں",
        "rev-deleted-comment": "(تبصرہ حذف کی گيا ہے)",
        "rev-deleted-user": "(صارف نام حذف کیا گيا ہے)",
        "prefs-watchlist-edits": "زیر نظر فہرست میں نظر آنے والی تبدیلیوں کی زیادہ سے زیادہ تعداد:",
        "prefs-watchlist-edits-max": "زیادہ سے زیادہ تعداد: 1000",
        "prefs-watchlist-token": "زیر نظر فہرست کی کلید:",
+       "prefs-watchlist-managetokens": "انتظام ٹوکن",
        "prefs-misc": "دیگر",
        "prefs-resetpass": "پاس ورڈ تبدیل کریں",
        "prefs-changeemail": "برقی ڈاک پتا تبدیل یا حذف کریں",
-       "prefs-setemail": "برقی پتہ دیں",
+       "prefs-setemail": "برقی ڈاک پتا درج کریں",
        "prefs-email": "برقی خط کے اختیارات",
        "prefs-rendering": "ظاہریت",
        "saveprefs": "محفوظ",
        "recentchangescount": "حالیہ تبدیلیوں، تاریخچوں اور نوشتوں میں دکھائی جانے والی ترامیم کی تعداد:",
        "prefs-help-recentchangescount": "زیادہ سے زیادہ تعداد: 1000",
        "prefs-help-watchlist-token2": "یہ آپ کی زیر نظر فہرست کے ویب فیڈ کی خفیہ کلید ہے۔\nاسے خفیہ رکھیں، تاکہ کوئی دوسرا شخص آپ کی زیر نظر فہرست نہ دیکھ سکے۔\nاگر آپ کو کلید تبدیل کرنی ہو تو [[Special:ResetTokens|یہاں کلک کریں]]۔",
+       "prefs-help-tokenmanagement": "آپ کی زیر نظر فہرست کی ویب فیڈ تک رسائی کے لیے اپنے کھاتے کی خفیہ کلید آپ یہاں دیکھ اور بدل سکتے ہیں۔ جس کے پاس یہ کلید ہوگی وہ آپ کی زیر نظر فہرست کو دیکھ سکتا ہے، لہذا اس کلید کو خفیہ رکھیں۔",
        "savedprefs": "آپ کی ترجیحات محفوظ ہوگئیں۔",
        "savedrights": "{{GENDER:$1|$1}} کے اختیارات محفوظ ہو گئے۔",
        "timezonelegend": "منطقۂ وقت:",
        "prefs-editor": "خانہ ترمیم",
        "prefs-preview": "نمائش",
        "prefs-advancedrc": "اضافی اختیارات",
-       "prefs-opt-out": "اصلاحات سے گریز",
        "prefs-advancedrendering": "اضافی اختیارات",
        "prefs-advancedsearchoptions": "اعلی اختیارات",
        "prefs-advancedwatchlist": "اضافی اختیارات",
        "prefs-displayrc": "نمائش کے اختیارات",
        "prefs-displaywatchlist": "نمائش کے اختیارات",
+       "prefs-changesrc": "دکھائی جانے والی تبدیلیاں",
+       "prefs-changeswatchlist": "دکھائی جانے والی تبدیلیاں",
+       "prefs-pageswatchlist": "زیر نظر صفحات",
        "prefs-tokenwatchlist": "ٹوکن",
        "prefs-diffs": "فرق",
        "prefs-help-prefershttps": "یہ ترجیح آپ کے اگلے لاگ ان پر اثر انداز ہوگی۔",
        "emailuser-title-notarget": "ای میل صارف",
        "emailpagetext": "درج ذیل فارم کے ذریعہ آپ اس {{GENDER:$1|صارف}} کو برقی پیغام بھیج سکتے ہیں۔ جو برقی ڈاک پتا آپ نے [[Special:Preferences|اپنی ترجیحات]] میں دیا ہے وہ یہاں \"از\" کے طور پر نظر آئے گا، تاکہ وصول کنندہ براہ راست آپ کو جواب دے سکے۔",
        "defemailsubject": "{{SITENAME}} سے برقی خط",
-       "usermaildisabled": "صارف برقی پتہ غیر فعال ہے",
+       "usermaildisabled": "صارف کا برقی ڈاک پتا غیر فعال ہے",
        "usermaildisabledtext": "آپ اس ویکی پر رہتے ہوئے دوسرے صارف کو برقی خط ارسال نہيں کر سکتے",
-       "noemailtitle": "کوئی برقی پتہ نہیں ہے",
+       "noemailtitle": "کوئی برقی ڈاک پتا نہیں ہے",
        "noemailtext": "اس صارف نے کوئی درست برقی ڈاک پتا نہیں دیا ہے۔",
        "nowikiemailtext": "اس صارف نے دیگر صارفین سے برقی خط وصول نہ کرنے کا فیصلہ کیا ہے۔",
        "emailnotarget": "وصول کنندہ موجود نہیں یا صارف نام نادرست ہے۔",
        "exif-urgency-other": "صارف کی وضاحت کردہ ترجیح ($1)",
        "namespacesall": "تمام",
        "monthsall": "تمام",
-       "confirmemail": "اپنے برقی پتہ کی تصدیق کریں",
+       "confirmemail": "اپنے برقی ڈاک پتے کی تصدیق کریں",
        "confirmemail_noemail": "آپ نے [[Special:Preferences|اپنی ترجیحات]] میں درست برقی ڈاک پتا نہیں دیا ہے۔",
        "confirmemail_text": "{{SITENAME}} میں موجود برقی خط کی سہولتوں کو استعمال کرنے کے لیے آپ کے برقی ڈاک پتے کی تصدیق ضروری ہے۔\nاپنے پتے پر تصدیقی ڈاک روانہ کرنے کے لیے ذیل میں موجود بٹن پر کلک کریں۔\nموصولہ برقی خط میں آپ کو کوڈ پر مشتمل ایک ربط نظر آئے گا۔\nچنانچہ اپنے بڑقی ڈاک پتے کی تصدیق کے لیے اس ربط کو اپنے براؤزر میں کھولیں۔",
        "confirmemail_pending": "آپ کو تصدیقی کوڈ پہلے ہی روانہ کیا جا چکا ہے۔\nاگر آپ نے ابھی اپنا کھاتہ بنایا ہے تو نئے کوڈ کی درخواست دینے سے قبل اس کے موصول ہونے کا کچھ دیر انتظار کر لیں۔",
index 4e9ec64..6cc95fc 100644 (file)
@@ -15,7 +15,8 @@
                        "Ximik1991",
                        "Bmansurov",
                        "Fitoschido",
-                       "ديفيد"
+                       "ديفيد",
+                       "Malikxan"
                ]
        },
        "tog-underline": "Havolaning tagiga chizish:",
        "view": "Koʻrish",
        "view-foreign": "$1da koʻrish",
        "edit": "Tahrirlash",
+       "edit-local": "Mahalliy izohni tahrirlash",
        "create": "Yaratish",
        "create-local": "Mahalliy tavsifini qoʻshish",
        "delete": "O‘chirish",
        "disclaimers": "Masʼuliyatdan voz kechish",
        "disclaimerpage": "Project:Masʼuliyatdan voz kechish",
        "edithelp": "Tahrirlash yordami",
+       "helppage-top-gethelp": "Yordam",
        "mainpage": "Bosh sahifa",
        "mainpage-description": "Bosh sahifa",
        "policy-url": "Project:Qoida",
        "myprivateinfoprotected": "Sizda shaxsiy maʻlumotlaringizni tahrirlashga ruxsat mavjud emas.",
        "mypreferencesprotected": "Sizda afzalliklarni tahrirlashga ruxsat mavjud emas.",
        "ns-specialprotected": "\"{{ns:special}}\" nomfazosi sahifalari tahrirlanishi mumkin emas.",
+       "invalidtitle": "Yaroqsiz sarlavha",
        "exception-nologin": "Siz tizimda o'zingizni tanishtirmadingiz",
        "exception-nologin-text": "Bu sahifani koʻrish yoki soʻralgan amalni bajarish uchun tizimga kirishingiz lozim.",
        "virus-badscanner": "Moslamada xato. Noma'lum virus aniqlovchi: ''$1''",
index 50cb787..301980c 100644 (file)
        "prefs-editor": "Trình soạn",
        "prefs-preview": "Xem trước",
        "prefs-advancedrc": "Tùy chọn nâng cao",
-       "prefs-opt-out": "Quyết định không sử dụng các cải thiện",
        "prefs-advancedrendering": "Tùy chọn nâng cao",
        "prefs-advancedsearchoptions": "Tùy chọn nâng cao",
        "prefs-advancedwatchlist": "Tùy chọn nâng cao",
index d226bf9..75be32d 100644 (file)
        "json-error-syntax": "語法錯咗",
        "json-error-utf8": "字符引導失敗,因為有非法UTF-8代碼。",
        "headline-anchor-title": "連結到呢一節",
-       "special-characters-group-latin": "拉丁",
-       "special-characters-group-latinextended": "Latin擴展左",
+       "special-characters-group-latin": "拉丁字母擴展",
+       "special-characters-group-latinextended": "拉丁字母擴展",
        "special-characters-group-ipa": "IPA",
        "special-characters-group-symbols": "符號",
        "special-characters-group-greek": "希臘文",
index 4253652..e0fcc4b 100644 (file)
        "explainconflict": "其他用户在您开始编辑后更改了该页面。上面的文字区含有该页面当前的文字。下面的文字区显示您的更改。您必须把您的更改合并至现有文字。<strong>只有</strong>当您单击“$1”后,上面的文字区中的文字才会被保存。",
        "yourtext": "您的文字",
        "storedversion": "已保存的版本",
-       "editingold": "<strong>警告:您正在编辑的是本页面的旧版本。</strong>如果您保存该编辑,该版本后的所有更改都会丢失。",
+       "editingold": "<strong>警告:您正在编辑的是本页面的旧版本。</strong>如果您提交该更改,该版本后的所有更改都会丢失。",
        "unicode-support-fail": "看起来您的浏览器不支持Unicode。需要Unicode才能编辑页面,所以您的编辑无法保存。",
        "yourdiff": "差异",
        "copyrightwarning": "请注意您对{{SITENAME}}的所有贡献都被认为是在$2下发布,请查看在$1的细节。如果您不希望您的文字被任意修改和再散布,请不要提交。<br />\n您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源。<strong>不要在未获授权的情况下发表!</strong>",
        "timezonelegend": "时区:",
        "localtime": "当地时间:",
        "timezoneuseserverdefault": "使用wiki默认值($1)",
-       "timezoneuseoffset": "其(指定时差)",
+       "timezoneuseoffset": "其(指定时差)",
        "servertime": "服务器时间:",
        "guesstimezone": "使用浏览器设置",
        "timezoneregion-africa": "非洲",
        "prefs-editor": "编辑",
        "prefs-preview": "预览",
        "prefs-advancedrc": "高级选项",
-       "prefs-opt-out": "关闭改进功能",
        "prefs-advancedrendering": "高级选项",
        "prefs-advancedsearchoptions": "高级选项",
        "prefs-advancedwatchlist": "高级选项",
        "tags": "有效的更改标签",
        "tag-filter": "[[Special:Tags|标签]]过滤器:",
        "tag-filter-submit": "过滤器",
-       "tag-list-wrapper": "[[Special:Tags|$1个标签]]:$2",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|标签}}]]:$2",
        "tag-mw-contentmodelchange": "内容模型更改",
        "tag-mw-contentmodelchange-description": "更改页面[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel 内容模型]的编辑",
        "tag-mw-new-redirect": "新重定向",
index af948bf..ff37b8e 100644 (file)
        "passwordtooshort": "您的密碼至少需要 $1 個字元。",
        "passwordtoolong": "密碼不能超過 {{PLURAL:$1|1 個字元|$1 個字元}}。",
        "passwordtoopopular": "不能使用普遍選擇的密碼。請選擇更難猜出的密碼",
+       "passwordinlargeblacklist": "所輸入密碼被列在常用密碼的清單裡,請改用較獨特的密碼。",
        "password-name-match": "您的密碼不可以跟使用者名稱相同。",
        "password-login-forbidden": "此使用者名稱和密碼已被禁止使用。",
        "mailmypassword": "重設密碼",
        "explainconflict": "在您開始編輯之後已有其他人儲存了此頁面。\n上方的文字框內顯示了目前頁面中的文字內容,\n您所變更的文字內容顯示在下方文字框中。\n您須要將您所變更的文字內容合併到已儲存的文字內容當中。\n若您直接點選 \"$1\" <strong>只有</strong> 上方文字框中的內容會被儲存。",
        "yourtext": "您的文字",
        "storedversion": "已儲存修訂",
-       "editingold": "<strong>警告:您目前正編輯頁面的舊修訂版本。</strong>\n若您儲存,在此修訂之後變更的任何內容將會遺失。",
+       "editingold": "<strong>警告:您目前正編輯頁面的舊修訂版本。</strong>若您儲存,在此修訂之後變更的任何內容將會遺失。",
        "unicode-support-fail": "看起來您的瀏覽器不支援Unicode。需要Unicode才能編輯頁面,所以您的編輯無法儲存。",
        "yourdiff": "差異",
        "copyrightwarning": "請注意,所有於 {{SITENAME}} 所做的貢獻會依據 $2 授權條款發佈 (詳情請見 $1)。\n若您不希望您的著作被任意修改與散佈,請勿在此發表文章。<br />\n您同時向我們保証在此的著作內容是您自行撰寫,或是取自不受版權保護的公開領域或自由資源。\n<strong>請勿在未經授權的情況下發表文章!</strong>",
        "timezonelegend": "時區:",
        "localtime": "當地時間:",
        "timezoneuseserverdefault": "使用 Wiki 預設值 ($1)",
-       "timezoneuseoffset": "其他 (指定時差)",
+       "timezoneuseoffset": "其它(以下指定時差)",
+       "timezone-useoffset-placeholder": "範例:\"-07:00\" 或 \"01:00\"",
        "servertime": "伺服器時間:",
        "guesstimezone": "使用瀏覽器設定值",
        "timezoneregion-africa": "非洲",
        "prefs-editor": "編輯器",
        "prefs-preview": "預覽",
        "prefs-advancedrc": "進階選項",
-       "prefs-opt-out": "關閉改進功能",
        "prefs-advancedrendering": "進階選項",
        "prefs-advancedsearchoptions": "進階選項",
        "prefs-advancedwatchlist": "進階選項",
        "tags": "有效變更標籤",
        "tag-filter": "[[Special:Tags|標籤]]搜尋:",
        "tag-filter-submit": "篩選器",
-       "tag-list-wrapper": "[[Special:Tags|$1 個標籤]]:$2",
+       "tag-list-wrapper": "[[Special:Tags|{{PLURAL:$1|標籤}}]]:$2",
        "tag-mw-contentmodelchange": "內容模型變更",
        "tag-mw-contentmodelchange-description": "[https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel 更改頁面的內容模型]的編輯。",
        "tag-mw-new-redirect": "新重新導向",
        "passwordpolicies-policy-passwordcannotmatchblacklist": "密碼不可以同於被列入黑名單的特定密碼",
        "passwordpolicies-policy-maximalpasswordlength": "密碼必須小於 $1 個{{PLURAL:$1|字元|字元}}長度",
        "passwordpolicies-policy-passwordcannotbepopular": "密碼不可以是{{PLURAL:$1|常用密碼內容|在清單中的編號 $1 常用密碼}}",
+       "passwordpolicies-policy-passwordnotinlargeblacklist": "不能採用列在 100000 個最常用到密碼清單當中的密碼。",
        "easydeflate-invaliddeflate": "提供的內容未被正常的壓縮",
        "unprotected-js": "基於安全因素,JavaScript 不能從未保護的頁面來載入。建立 JavaScript 請僅在 MediaWiki 的:命名空間或使用者子頁面"
 }
index 6a2e41d..6646122 100644 (file)
@@ -113,7 +113,6 @@ $specialPageAliases = [
        'Myuploads'                 => [ 'Moje_soubory', 'Mé_soubory' ],
        'Newimages'                 => [ 'Nové_obrázky', 'Galerie_nových_obrázků', 'Nove_obrazky' ],
        'Newpages'                  => [ 'Nové_stránky', 'Nove_stranky', 'Nejnovější_stránky', 'Nejnovejsi_stranky' ],
-       'PasswordReset'             => [ 'Reset_hesla', 'Resetovat_heslo' ],
        'PagesWithProp'             => [ 'Stránky_s_vlastností', 'Stránky_s_vlastnostmi' ],
        'PasswordReset'             => [ 'Reset_hesla', 'Resetovat_heslo', 'Obnova_hesla', 'Obnovit_heslo' ],
        'PermanentLink'             => [ 'Trvalý_odkaz' ],
diff --git a/maintenance/archives/patch-drop-ct_tag.sql b/maintenance/archives/patch-drop-ct_tag.sql
new file mode 100644 (file)
index 0000000..2f5881a
--- /dev/null
@@ -0,0 +1,10 @@
+-- T185355
+ALTER TABLE /*_*/change_tag MODIFY ct_tag_id int unsigned NOT NULL;
+
+DROP INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag;
+DROP INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag;
+DROP INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag;
+DROP INDEX /*i*/change_tag_tag_id ON /*_*/change_tag;
+
+ALTER TABLE /*_*/change_tag DROP COLUMN ct_tag;
+
diff --git a/maintenance/mssql/archives/patch-drop-ct_tag.sql b/maintenance/mssql/archives/patch-drop-ct_tag.sql
new file mode 100644 (file)
index 0000000..5498a1c
--- /dev/null
@@ -0,0 +1,22 @@
+-- T185355
+ALTER TABLE /*_*/change_tag ALTER COLUMN ct_tag INTEGER NOT NULL
+
+DECLARE @sql nvarchar(max),
+       @id sysname;--
+
+SET @sql = 'ALTER TABLE /*_*/change_tag DROP CONSTRAINT ';--
+
+SELECT @id = df.name
+FROM sys.default_constraints df
+JOIN sys.columns c
+       ON c.object_id = df.parent_object_id
+       AND c.column_id = df.parent_column_id
+WHERE
+       df.parent_object_id = OBJECT_ID('/*_*/change_tag')
+       AND c.name = 'ct_tag';--
+
+SET @sql = @sql + @id;--
+
+EXEC sp_executesql @sql;--
+
+ALTER TABLE /*_*/change_tag DROP COLUMN ct_tag;
index ec2f1fa..fd2fae7 100644 (file)
@@ -1398,24 +1398,17 @@ CREATE TABLE /*_*/change_tag (
   ct_log_id int NULL REFERENCES /*_*/logging(log_id),
   -- REVID for the change
   ct_rev_id int NULL REFERENCES /*_*/revision(rev_id),
-  -- Tag applied
-  ct_tag nvarchar(255) NOT NULL default '',
   -- Parameters for the tag, presently unused
   ct_params nvarchar(max) NULL,
   -- Foreign key to change_tag_def row
-  ct_tag_id int NULL CONSTRAINT ctd_tag_id__fk FOREIGN KEY REFERENCES /*_*/change_tag_def(ctd_id)
+  ct_tag_id int NOT NULL CONSTRAINT ctd_tag_id__fk FOREIGN KEY REFERENCES /*_*/change_tag_def(ctd_id)
 );
 
-CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
-CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
-CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
-
 CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
 CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
 CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
 
 -- Covering index, so we can pull all the info only out of the index.
-CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 -- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT
diff --git a/maintenance/oracle/archives/patch-drop-ct_tag.sql b/maintenance/oracle/archives/patch-drop-ct_tag.sql
new file mode 100644 (file)
index 0000000..4c5d128
--- /dev/null
@@ -0,0 +1,9 @@
+-- T185355
+ALTER TABLE &mw_prefix.change_tag MODIFY &mw_prefix.ct_tag_id NUMBER NOT NULL;
+
+DROP INDEX &mw_prefix.change_tag_i03;
+DROP INDEX &mw_prefix.change_tag_i04;
+DROP INDEX &mw_prefix.change_tag_i05;
+DROP INDEX &mw_prefix.change_tag_i01;
+
+ALTER TABLE &mw_prefix.change_tag DROP COLUMN &mw_prefix.ct_tag;
index 1ccaabf..4c36fe1 100644 (file)
@@ -935,21 +935,15 @@ CREATE TABLE &mw_prefix.change_tag (
   ct_rc_id NUMBER NULL,
   ct_log_id NUMBER NULL,
   ct_rev_id NUMBER NULL,
-  ct_tag VARCHAR2(255) DEFAULT '///invalid///' NOT NULL,
   ct_params BLOB NULL,
-  ct_tag_id NUMBER NULL
+  ct_tag_id NUMBER NOT NULL
 );
 ALTER TABLE &mw_prefix.change_tag ADD CONSTRAINT &mw_prefix.change_tag_pk PRIMARY KEY (ct_id);
 
-CREATE INDEX &mw_prefix.change_tag_i03 ON &mw_prefix.change_tag (ct_rc_id,ct_tag);
-CREATE INDEX &mw_prefix.change_tag_i04 ON &mw_prefix.change_tag (ct_log_id,ct_tag);
-CREATE INDEX &mw_prefix.change_tag_i05 ON &mw_prefix.change_tag (ct_rev_id,ct_tag);
-
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u04 ON &mw_prefix.change_tag (ct_rc_id,ct_tag_id);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u05 ON &mw_prefix.change_tag (ct_log_id,ct_tag_id);
 CREATE UNIQUE INDEX &mw_prefix.change_tag_u06 ON &mw_prefix.change_tag (ct_rev_id,ct_tag_id);
 
-CREATE INDEX &mw_prefix.change_tag_i01 ON &mw_prefix.change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 CREATE INDEX &mw_prefix.change_tag_i02 ON &mw_prefix.change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 CREATE TABLE &mw_prefix.tag_summary (
index 7bec25a..9594137 100644 (file)
@@ -42,16 +42,6 @@ class PopulateChangeTagDef extends LoggedUpdateMaintenance {
                $this->addOption( 'set-user-tags-only', 'Only update ctd_user_defined from valid_tag table' );
        }
 
-       public function execute() {
-               global $wgChangeTagsSchemaMigrationStage;
-               if ( $wgChangeTagsSchemaMigrationStage === MIGRATION_OLD ) {
-                       // Return "success", but don't flag it as done so the next run will retry
-                       $this->output( '... Not run, $wgChangeTagsSchemaMigrationStage === MIGRATION_OLD' . "\n" );
-                       return true;
-               }
-               return parent::execute();
-       }
-
        protected function doDBUpdates() {
                $this->lbFactory = MediaWiki\MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
                $this->setBatchSize( $this->getOption( 'batch-size', $this->getBatchSize() ) );
diff --git a/maintenance/postgres/archives/patch-drop-ct_tag.sql b/maintenance/postgres/archives/patch-drop-ct_tag.sql
new file mode 100644 (file)
index 0000000..cbef6c9
--- /dev/null
@@ -0,0 +1,10 @@
+-- T185355
+ALTER TABLE /*_*/change_tag ALTER COLUMN ct_tag_id SET NOT NULL;
+
+DROP INDEX /*i*/change_tag_rc_tag_nonuniq;
+DROP INDEX /*i*/change_tag_log_tag_nonuniq;
+DROP INDEX /*i*/change_tag_rev_tag_nonuniq;
+DROP INDEX /*i*/change_tag_tag_id;
+
+ALTER TABLE /*_*/change_tag DROP COLUMN ct_tag;
+
index 96a0617..4f636ae 100644 (file)
@@ -804,21 +804,15 @@ CREATE TABLE change_tag (
   ct_rc_id   INTEGER      NULL,
   ct_log_id  INTEGER      NULL,
   ct_rev_id  INTEGER      NULL,
-  ct_tag     TEXT     NOT NULL DEFAULT '',
   ct_params  TEXT         NULL,
-  ct_tag_id  INTEGER      NULL
+  ct_tag_id  INTEGER  NOT NULL
 );
 ALTER SEQUENCE change_tag_ct_id_seq OWNED BY change_tag.ct_id;
 
-CREATE INDEX change_tag_rc_tag_nonuniq ON change_tag(ct_rc_id,ct_tag);
-CREATE INDEX change_tag_log_tag_nonuniq ON change_tag(ct_log_id,ct_tag);
-CREATE INDEX change_tag_rev_tag_nonuniq ON change_tag(ct_rev_id,ct_tag);
-
 CREATE UNIQUE INDEX change_tag_rc_tag_id ON change_tag(ct_rc_id,ct_tag_id);
 CREATE UNIQUE INDEX change_tag_log_tag_id ON change_tag(ct_log_id,ct_tag_id);
 CREATE UNIQUE INDEX change_tag_rev_tag_id ON change_tag(ct_rev_id,ct_tag_id);
 
-CREATE INDEX change_tag_tag_id ON change_tag(ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 CREATE INDEX change_tag_tag_id_id ON change_tag(ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 CREATE SEQUENCE tag_summary_ts_id_seq;
index 714726a..8350cfa 100644 (file)
@@ -126,7 +126,7 @@ CREATE TABLE /*_*/image_tmp (
   img_height int NOT NULL default 0,
   img_metadata mediumblob NOT NULL,
   img_bits int NOT NULL default 0,
-  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
   img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
   img_minor_mime varbinary(100) NOT NULL default "unknown",
   img_description varbinary(767) NOT NULL default '',
@@ -177,7 +177,7 @@ CREATE TABLE /*_*/oldimage_tmp (
   oi_actor bigint unsigned NOT NULL DEFAULT 0,
   oi_timestamp binary(14) NOT NULL default '',
   oi_metadata mediumblob NOT NULL,
-  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
   oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
   oi_minor_mime varbinary(100) NOT NULL default "unknown",
   oi_deleted tinyint unsigned NOT NULL default 0,
@@ -204,61 +204,7 @@ CREATE INDEX /*i*/oi_actor_timestamp ON /*_*/oldimage (oi_actor,oi_timestamp);
 
 COMMIT;
 
-BEGIN;
-
-DROP TABLE IF EXISTS /*_*/filearchive_tmp;
-CREATE TABLE /*_*/filearchive_tmp (
-  fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
-  fa_name varchar(255) binary NOT NULL default '',
-  fa_archive_name varchar(255) binary default '',
-  fa_storage_group varbinary(16),
-  fa_storage_key varbinary(64) default '',
-  fa_deleted_user int,
-  fa_deleted_timestamp binary(14) default '',
-  fa_deleted_reason varbinary(767) default '',
-  fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0,
-  fa_size int unsigned default 0,
-  fa_width int default 0,
-  fa_height int default 0,
-  fa_metadata mediumblob,
-  fa_bits int default 0,
-  fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
-  fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
-  fa_minor_mime varbinary(100) default "unknown",
-  fa_description varbinary(767) default '',
-  fa_description_id bigint unsigned NOT NULL DEFAULT 0,
-  fa_user int unsigned default 0,
-  fa_user_text varchar(255) binary DEFAULT '',
-  fa_actor bigint unsigned NOT NULL DEFAULT 0,
-  fa_timestamp binary(14) default '',
-  fa_deleted tinyint unsigned NOT NULL default 0,
-  fa_sha1 varbinary(32) NOT NULL default ''
-) /*$wgDBTableOptions*/;
-
-INSERT OR IGNORE INTO /*_*/filearchive_tmp (
-       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
-       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
-       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
-       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
-       fa_deleted, fa_sha1)
-  SELECT
-       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
-       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
-       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
-       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
-       fa_deleted, fa_sha1
-  FROM /*_*/filearchive;
-
-DROP TABLE /*_*/filearchive;
-ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
-CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
-CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
-CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
-CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
-CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
-CREATE INDEX /*i*/fa_actor_timestamp ON /*_*/filearchive (fa_actor,fa_timestamp);
-
-COMMIT;
+-- filearchive is done in patch-filearchive-fa_actor.sql
 
 BEGIN;
 
index 10d74fb..69cfe13 100644 (file)
--- image
-
-CREATE TABLE /*_*/image_tmp (
-  -- Filename.
-  -- This is also the title of the associated description page,
-  -- which will be in namespace 6 (NS_FILE).
-  img_name varchar(255) binary NOT NULL default '' PRIMARY KEY,
-
-  -- File size in bytes.
-  img_size int unsigned NOT NULL default 0,
-
-  -- For images, size in pixels.
-  img_width int NOT NULL default 0,
-  img_height int NOT NULL default 0,
-
-  -- Extracted Exif metadata stored as a serialized PHP array.
-  img_metadata mediumblob NOT NULL,
-
-  -- For images, bits per pixel if known.
-  img_bits int NOT NULL default 0,
-
-  -- Media type as defined by the MEDIATYPE_xxx constants
-  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
-
-  -- major part of a MIME media type as defined by IANA
-  -- see https://www.iana.org/assignments/media-types/
-  -- for "chemical" cf. http://dx.doi.org/10.1021/ci9803233 by the ACS
-  img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
-
-  -- minor part of a MIME media type as defined by IANA
-  -- the minor parts are not required to adher to any standard
-  -- but should be consistent throughout the database
-  -- see https://www.iana.org/assignments/media-types/
-  img_minor_mime varbinary(100) NOT NULL default "unknown",
-
-  -- Description field as entered by the uploader.
-  -- This is displayed in image upload history and logs.
-  img_description varbinary(767) NOT NULL,
-
-  -- user_id and user_name of uploader.
-  img_user int unsigned NOT NULL default 0,
-  img_user_text varchar(255) binary NOT NULL,
-
-  -- Time of the upload.
-  img_timestamp varbinary(14) NOT NULL default '',
-
-  -- SHA-1 content hash in base-36
-  img_sha1 varbinary(32) NOT NULL default ''
-) /*$wgDBTableOptions*/;
-
-INSERT INTO /*_*/image_tmp
-       SELECT img_name, img_size, img_width, img_height, img_metadata, img_bits,
-       img_media_type, img_major_mime, img_minor_mime, img_description,
-       img_user, img_user_text, img_timestamp, img_sha1
-               FROM /*_*/image;
-
-DROP TABLE /*_*/image;
-
-ALTER TABLE /*_*/image_tmp RENAME TO /*_*/image;
-
--- Used by Special:Newimages and ApiQueryAllImages
-CREATE INDEX /*i*/img_user_timestamp ON /*_*/image (img_user,img_timestamp);
-CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
--- Used by Special:ListFiles for sort-by-size
-CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
--- Used by Special:Newimages and Special:ListFiles
-CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);
--- Used in API and duplicate search
-CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1(10));
--- Used to get media of one type
-CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
-
--- oldimage
-
-CREATE TABLE /*_*/oldimage_tmp (
-  -- Base filename: key to image.img_name
-  oi_name varchar(255) binary NOT NULL default '',
-
-  -- Filename of the archived file.
-  -- This is generally a timestamp and '!' prepended to the base name.
-  oi_archive_name varchar(255) binary NOT NULL default '',
-
-  -- Other fields as in image...
-  oi_size int unsigned NOT NULL default 0,
-  oi_width int NOT NULL default 0,
-  oi_height int NOT NULL default 0,
-  oi_bits int NOT NULL default 0,
-  oi_description varbinary(767) NOT NULL,
-  oi_user int unsigned NOT NULL default 0,
-  oi_user_text varchar(255) binary NOT NULL,
-  oi_timestamp binary(14) NOT NULL default '',
-
-  oi_metadata mediumblob NOT NULL,
-  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
-  oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
-  oi_minor_mime varbinary(100) NOT NULL default "unknown",
-  oi_deleted tinyint unsigned NOT NULL default 0,
-  oi_sha1 varbinary(32) NOT NULL default ''
-) /*$wgDBTableOptions*/;
-
-INSERT INTO /*_*/oldimage_tmp
-       SELECT oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
-       oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
-       oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1
-               FROM /*_*/oldimage;
-
-DROP TABLE /*_*/oldimage;
-
-ALTER TABLE oldimage_tmp RENAME TO /*_*/oldimage;
-
-CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
-CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
--- oi_archive_name truncated to 14 to avoid key length overflow
-CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14));
-CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1(10));
-
--- filearchive
-
-CREATE TABLE /*_*/filearchive_tmp (
-  -- Unique row id
-  fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
-
-  -- Original base filename; key to image.img_name, page.page_title, etc
-  fa_name varchar(255) binary NOT NULL default '',
-
-  -- Filename of archived file, if an old revision
-  fa_archive_name varchar(255) binary default '',
-
-  -- Which storage bin (directory tree or object store) the file data
-  -- is stored in. Should be 'deleted' for files that have been deleted;
-  -- any other bin is not yet in use.
-  fa_storage_group varbinary(16),
-
-  -- SHA-1 of the file contents plus extension, used as a key for storage.
-  -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg
-  --
-  -- If NULL, the file was missing at deletion time or has been purged
-  -- from the archival storage.
-  fa_storage_key varbinary(64) default '',
-
-  -- Deletion information, if this file is deleted.
-  fa_deleted_user int,
-  fa_deleted_timestamp binary(14) default '',
-  fa_deleted_reason varbinary(767) default '',
-
-  -- Duped fields from image
-  fa_size int unsigned default 0,
-  fa_width int default 0,
-  fa_height int default 0,
-  fa_metadata mediumblob,
-  fa_bits int default 0,
-  fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
-  fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
-  fa_minor_mime varbinary(100) default "unknown",
-  fa_description varbinary(767),
-  fa_user int unsigned default 0,
-  fa_user_text varchar(255) binary,
-  fa_timestamp binary(14) default '',
-
-  -- Visibility of deleted revisions, bitfield
-  fa_deleted tinyint unsigned NOT NULL default 0,
-
-  -- sha1 hash of file content
-  fa_sha1 varbinary(32) NOT NULL default ''
-) /*$wgDBTableOptions*/;
-
-INSERT INTO /*_*/filearchive_tmp
-       SELECT fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key, fa_deleted_user, fa_deleted_timestamp,
-       fa_deleted_reason, fa_size, fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
-       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp, fa_deleted, fa_sha1
-               FROM /*_*/filearchive;
-
-DROP TABLE /*_*/filearchive;
-
-ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
-
--- pick out by image name
-CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
--- pick out dupe files
-CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
--- sort by deletion time
-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));
-
--- uploadstash
-
-CREATE TABLE /*_*/uploadstash_tmp (
-  us_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
-
-  -- the user who uploaded the file.
-  us_user int unsigned NOT NULL,
-
-  -- file key. this is how applications actually search for the file.
-  -- this might go away, or become the primary key.
-  us_key varchar(255) NOT NULL,
-
-  -- the original path
-  us_orig_path varchar(255) NOT NULL,
-
-  -- the temporary path at which the file is actually stored
-  us_path varchar(255) NOT NULL,
-
-  -- which type of upload the file came from (sometimes)
-  us_source_type varchar(50),
-
-  -- the date/time on which the file was added
-  us_timestamp varbinary(14) NOT NULL,
-
-  us_status varchar(50) NOT NULL,
-
-  -- chunk counter starts at 0, current offset is stored in us_size
-  us_chunk_inx int unsigned NULL,
-
-  -- Serialized file properties from FSFile::getProps()
-  us_props blob,
-
-  -- file size in bytes
-  us_size int unsigned NOT NULL,
-  -- this hash comes from FSFile::getSha1Base36(), and is 31 characters
-  us_sha1 varchar(31) NOT NULL,
-  us_mime varchar(255),
-  -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table
-  us_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
-  -- image-specific properties
-  us_image_width int unsigned,
-  us_image_height int unsigned,
-  us_image_bits smallint unsigned
-
-) /*$wgDBTableOptions*/;
-
-INSERT INTO /*_*/uploadstash_tmp
-       SELECT us_id, us_user, us_key, us_orig_path, us_path, us_source_type,
-       us_timestamp, us_status, us_chunk_inx, us_props, us_size, us_sha1, us_mime,
-       us_media_type, us_image_width, us_image_height, us_image_bits
-               FROM /*_*/uploadstash;
-
-DROP TABLE uploadstash;
-
-ALTER TABLE /*_*/uploadstash_tmp RENAME TO /*_*/uploadstash;
-
--- sometimes there's a delete for all of a user's stuff.
-CREATE INDEX /*i*/us_user ON /*_*/uploadstash (us_user);
--- pick out files by key, enforce key uniqueness
-CREATE UNIQUE INDEX /*i*/us_key ON /*_*/uploadstash (us_key);
--- the abandoned upload cleanup script needs this
-CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp);
+-- In theory all the stuff below would be needed to change the ENUM. But in
+-- practice sqlite3 ignores the list of values and stores an "ENUM" as TEXT,
+-- making this a no-op. So for efficiency and to avoid screwing up tables that
+-- are otherwise correct from tables.sql let's just skip it.
+-- (see code review on I7bf4ad01 and I335cb8d for details).
+
+---- image
+--
+--CREATE TABLE /*_*/image_tmp (
+--  -- Filename.
+--  -- This is also the title of the associated description page,
+--  -- which will be in namespace 6 (NS_FILE).
+--  img_name varchar(255) binary NOT NULL default '' PRIMARY KEY,
+--
+--  -- File size in bytes.
+--  img_size int unsigned NOT NULL default 0,
+--
+--  -- For images, size in pixels.
+--  img_width int NOT NULL default 0,
+--  img_height int NOT NULL default 0,
+--
+--  -- Extracted Exif metadata stored as a serialized PHP array.
+--  img_metadata mediumblob NOT NULL,
+--
+--  -- For images, bits per pixel if known.
+--  img_bits int NOT NULL default 0,
+--
+--  -- Media type as defined by the MEDIATYPE_xxx constants
+--  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+--
+--  -- major part of a MIME media type as defined by IANA
+--  -- see https://www.iana.org/assignments/media-types/
+--  -- for "chemical" cf. http://dx.doi.org/10.1021/ci9803233 by the ACS
+--  img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+--
+--  -- minor part of a MIME media type as defined by IANA
+--  -- the minor parts are not required to adher to any standard
+--  -- but should be consistent throughout the database
+--  -- see https://www.iana.org/assignments/media-types/
+--  img_minor_mime varbinary(100) NOT NULL default "unknown",
+--
+--  -- Description field as entered by the uploader.
+--  -- This is displayed in image upload history and logs.
+--  img_description varbinary(767) NOT NULL,
+--
+--  -- user_id and user_name of uploader.
+--  img_user int unsigned NOT NULL default 0,
+--  img_user_text varchar(255) binary NOT NULL,
+--
+--  -- Time of the upload.
+--  img_timestamp varbinary(14) NOT NULL default '',
+--
+--  -- SHA-1 content hash in base-36
+--  img_sha1 varbinary(32) NOT NULL default ''
+--) /*$wgDBTableOptions*/;
+--
+--INSERT INTO /*_*/image_tmp
+--     SELECT img_name, img_size, img_width, img_height, img_metadata, img_bits,
+--     img_media_type, img_major_mime, img_minor_mime, img_description,
+--     img_user, img_user_text, img_timestamp, img_sha1
+--             FROM /*_*/image;
+--
+--DROP TABLE /*_*/image;
+--
+--ALTER TABLE /*_*/image_tmp RENAME TO /*_*/image;
+--
+---- Used by Special:Newimages and ApiQueryAllImages
+--CREATE INDEX /*i*/img_user_timestamp ON /*_*/image (img_user,img_timestamp);
+--CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
+---- Used by Special:ListFiles for sort-by-size
+--CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
+---- Used by Special:Newimages and Special:ListFiles
+--CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);
+---- Used in API and duplicate search
+--CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1(10));
+---- Used to get media of one type
+--CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
+--
+---- oldimage
+--
+--CREATE TABLE /*_*/oldimage_tmp (
+--  -- Base filename: key to image.img_name
+--  oi_name varchar(255) binary NOT NULL default '',
+--
+--  -- Filename of the archived file.
+--  -- This is generally a timestamp and '!' prepended to the base name.
+--  oi_archive_name varchar(255) binary NOT NULL default '',
+--
+--  -- Other fields as in image...
+--  oi_size int unsigned NOT NULL default 0,
+--  oi_width int NOT NULL default 0,
+--  oi_height int NOT NULL default 0,
+--  oi_bits int NOT NULL default 0,
+--  oi_description varbinary(767) NOT NULL,
+--  oi_user int unsigned NOT NULL default 0,
+--  oi_user_text varchar(255) binary NOT NULL,
+--  oi_timestamp binary(14) NOT NULL default '',
+--
+--  oi_metadata mediumblob NOT NULL,
+--  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+--  oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
+--  oi_minor_mime varbinary(100) NOT NULL default "unknown",
+--  oi_deleted tinyint unsigned NOT NULL default 0,
+--  oi_sha1 varbinary(32) NOT NULL default ''
+--) /*$wgDBTableOptions*/;
+--
+--INSERT INTO /*_*/oldimage_tmp
+--     SELECT oi_name, oi_archive_name, oi_size, oi_width, oi_height, oi_bits,
+--     oi_description, oi_user, oi_user_text, oi_timestamp, oi_metadata,
+--     oi_media_type, oi_major_mime, oi_minor_mime, oi_deleted, oi_sha1
+--             FROM /*_*/oldimage;
+--
+--DROP TABLE /*_*/oldimage;
+--
+--ALTER TABLE oldimage_tmp RENAME TO /*_*/oldimage;
+--
+--CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
+--CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
+---- oi_archive_name truncated to 14 to avoid key length overflow
+--CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name(14));
+--CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1(10));
+--
+---- filearchive
+--
+--CREATE TABLE /*_*/filearchive_tmp (
+--  -- Unique row id
+--  fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+--
+--  -- Original base filename; key to image.img_name, page.page_title, etc
+--  fa_name varchar(255) binary NOT NULL default '',
+--
+--  -- Filename of archived file, if an old revision
+--  fa_archive_name varchar(255) binary default '',
+--
+--  -- Which storage bin (directory tree or object store) the file data
+--  -- is stored in. Should be 'deleted' for files that have been deleted;
+--  -- any other bin is not yet in use.
+--  fa_storage_group varbinary(16),
+--
+--  -- SHA-1 of the file contents plus extension, used as a key for storage.
+--  -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg
+--  --
+--  -- If NULL, the file was missing at deletion time or has been purged
+--  -- from the archival storage.
+--  fa_storage_key varbinary(64) default '',
+--
+--  -- Deletion information, if this file is deleted.
+--  fa_deleted_user int,
+--  fa_deleted_timestamp binary(14) default '',
+--  fa_deleted_reason varbinary(767) default '',
+--
+--  -- Duped fields from image
+--  fa_size int unsigned default 0,
+--  fa_width int default 0,
+--  fa_height int default 0,
+--  fa_metadata mediumblob,
+--  fa_bits int default 0,
+--  fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+--  fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
+--  fa_minor_mime varbinary(100) default "unknown",
+--  fa_description varbinary(767),
+--  fa_user int unsigned default 0,
+--  fa_user_text varchar(255) binary,
+--  fa_timestamp binary(14) default '',
+--
+--  -- Visibility of deleted revisions, bitfield
+--  fa_deleted tinyint unsigned NOT NULL default 0,
+--
+--  -- sha1 hash of file content
+--  fa_sha1 varbinary(32) NOT NULL default ''
+--) /*$wgDBTableOptions*/;
+--
+--INSERT INTO /*_*/filearchive_tmp
+--     SELECT fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key, fa_deleted_user, fa_deleted_timestamp,
+--     fa_deleted_reason, fa_size, fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
+--     fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp, fa_deleted, fa_sha1
+--             FROM /*_*/filearchive;
+--
+--DROP TABLE /*_*/filearchive;
+--
+--ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
+--
+---- pick out by image name
+--CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
+---- pick out dupe files
+--CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
+---- sort by deletion time
+--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));
+--
+---- uploadstash
+--
+--CREATE TABLE /*_*/uploadstash_tmp (
+--  us_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+--
+--  -- the user who uploaded the file.
+--  us_user int unsigned NOT NULL,
+--
+--  -- file key. this is how applications actually search for the file.
+--  -- this might go away, or become the primary key.
+--  us_key varchar(255) NOT NULL,
+--
+--  -- the original path
+--  us_orig_path varchar(255) NOT NULL,
+--
+--  -- the temporary path at which the file is actually stored
+--  us_path varchar(255) NOT NULL,
+--
+--  -- which type of upload the file came from (sometimes)
+--  us_source_type varchar(50),
+--
+--  -- the date/time on which the file was added
+--  us_timestamp varbinary(14) NOT NULL,
+--
+--  us_status varchar(50) NOT NULL,
+--
+--  -- chunk counter starts at 0, current offset is stored in us_size
+--  us_chunk_inx int unsigned NULL,
+--
+--  -- Serialized file properties from FSFile::getProps()
+--  us_props blob,
+--
+--  -- file size in bytes
+--  us_size int unsigned NOT NULL,
+--  -- this hash comes from FSFile::getSha1Base36(), and is 31 characters
+--  us_sha1 varchar(31) NOT NULL,
+--  us_mime varchar(255),
+--  -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table
+--  us_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+--  -- image-specific properties
+--  us_image_width int unsigned,
+--  us_image_height int unsigned,
+--  us_image_bits smallint unsigned
+--
+--) /*$wgDBTableOptions*/;
+--
+--INSERT INTO /*_*/uploadstash_tmp
+--     SELECT us_id, us_user, us_key, us_orig_path, us_path, us_source_type,
+--     us_timestamp, us_status, us_chunk_inx, us_props, us_size, us_sha1, us_mime,
+--     us_media_type, us_image_width, us_image_height, us_image_bits
+--             FROM /*_*/uploadstash;
+--
+--DROP TABLE uploadstash;
+--
+--ALTER TABLE /*_*/uploadstash_tmp RENAME TO /*_*/uploadstash;
+--
+---- sometimes there's a delete for all of a user's stuff.
+--CREATE INDEX /*i*/us_user ON /*_*/uploadstash (us_user);
+---- pick out files by key, enforce key uniqueness
+--CREATE UNIQUE INDEX /*i*/us_key ON /*_*/uploadstash (us_key);
+---- the abandoned upload cleanup script needs this
+--CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp);
index f743b55..d74c3a6 100644 (file)
@@ -177,7 +177,7 @@ CREATE TABLE /*_*/image_tmp (
   img_height int NOT NULL default 0,
   img_metadata mediumblob NOT NULL,
   img_bits int NOT NULL default 0,
-  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+  img_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
   img_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
   img_minor_mime varbinary(100) NOT NULL default "unknown",
   img_description varbinary(767) NOT NULL default '',
@@ -224,7 +224,7 @@ CREATE TABLE /*_*/oldimage_tmp (
   oi_user_text varchar(255) binary NOT NULL,
   oi_timestamp binary(14) NOT NULL default '',
   oi_metadata mediumblob NOT NULL,
-  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
+  oi_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
   oi_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") NOT NULL default "unknown",
   oi_minor_mime varbinary(100) NOT NULL default "unknown",
   oi_deleted tinyint unsigned NOT NULL default 0,
@@ -250,59 +250,7 @@ CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1(10));
 
 COMMIT;
 
-BEGIN;
-
-DROP TABLE IF EXISTS /*_*/filearchive_tmp;
-CREATE TABLE /*_*/filearchive_tmp (
-  fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
-  fa_name varchar(255) binary NOT NULL default '',
-  fa_archive_name varchar(255) binary default '',
-  fa_storage_group varbinary(16),
-  fa_storage_key varbinary(64) default '',
-  fa_deleted_user int,
-  fa_deleted_timestamp binary(14) default '',
-  fa_deleted_reason varbinary(767) default '',
-  fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0,
-  fa_size int unsigned default 0,
-  fa_width int default 0,
-  fa_height int default 0,
-  fa_metadata mediumblob,
-  fa_bits int default 0,
-  fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE") default NULL,
-  fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
-  fa_minor_mime varbinary(100) default "unknown",
-  fa_description varbinary(767) default '',
-  fa_description_id bigint unsigned NOT NULL DEFAULT 0,
-  fa_user int unsigned default 0,
-  fa_user_text varchar(255) binary,
-  fa_timestamp binary(14) default '',
-  fa_deleted tinyint unsigned NOT NULL default 0,
-  fa_sha1 varbinary(32) NOT NULL default ''
-) /*$wgDBTableOptions*/;
-
-INSERT OR IGNORE INTO /*_*/filearchive_tmp (
-       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
-       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
-       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
-       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
-       fa_deleted, fa_sha1)
-  SELECT
-       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
-       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
-       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
-       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
-       fa_deleted, fa_sha1
-  FROM /*_*/filearchive;
-
-DROP TABLE /*_*/filearchive;
-ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
-CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
-CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
-CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
-CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
-CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
-
-COMMIT;
+-- filearchive is done in patch-filearchive-fa_description_id.sql
 
 BEGIN;
 
diff --git a/maintenance/sqlite/archives/patch-drop-ct_tag.sql b/maintenance/sqlite/archives/patch-drop-ct_tag.sql
new file mode 100644 (file)
index 0000000..d5fd77f
--- /dev/null
@@ -0,0 +1,23 @@
+-- T185355
+
+CREATE TABLE /*_*/change_tag_tmp (
+  ct_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  ct_rc_id int NULL,
+  ct_log_id int unsigned NULL,
+  ct_rev_id int unsigned NULL,
+  ct_params blob NULL,
+  ct_tag_id int unsigned NOT NULL
+) /*$wgDBTableOptions*/;
+
+INSERT INTO /*_*/change_tag_tmp
+       SELECT ct_id, ct_rc_id, ct_log_id, ct_rev_id, ct_params, ct_tag_id
+               FROM /*_*/change_tag;
+
+DROP TABLE /*_*/change_tag;
+
+ALTER TABLE /*_*/change_tag_tmp RENAME TO /*_*/change_tag;
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
+CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
diff --git a/maintenance/sqlite/archives/patch-filearchive-fa_actor.sql b/maintenance/sqlite/archives/patch-filearchive-fa_actor.sql
new file mode 100644 (file)
index 0000000..179c29c
--- /dev/null
@@ -0,0 +1,61 @@
+--
+-- patch-filearchive-fa_actor.sql
+--
+-- Split from patch-actor-table.sql to work around SQLite unconditionally running
+-- patch-add-3d.sql on a fresh install, which wipes out fa_actor.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/filearchive_tmp;
+CREATE TABLE /*_*/filearchive_tmp (
+  fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  fa_name varchar(255) binary NOT NULL default '',
+  fa_archive_name varchar(255) binary default '',
+  fa_storage_group varbinary(16),
+  fa_storage_key varbinary(64) default '',
+  fa_deleted_user int,
+  fa_deleted_timestamp binary(14) default '',
+  fa_deleted_reason varbinary(767) default '',
+  fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0,
+  fa_size int unsigned default 0,
+  fa_width int default 0,
+  fa_height int default 0,
+  fa_metadata mediumblob,
+  fa_bits int default 0,
+  fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+  fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
+  fa_minor_mime varbinary(100) default "unknown",
+  fa_description varbinary(767) default '',
+  fa_description_id bigint unsigned NOT NULL DEFAULT 0,
+  fa_user int unsigned default 0,
+  fa_user_text varchar(255) binary DEFAULT '',
+  fa_actor bigint unsigned NOT NULL DEFAULT 0,
+  fa_timestamp binary(14) default '',
+  fa_deleted tinyint unsigned NOT NULL default 0,
+  fa_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/filearchive_tmp (
+       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
+       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
+       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
+       fa_deleted, fa_sha1)
+  SELECT
+       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
+       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
+       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
+       fa_deleted, fa_sha1
+  FROM /*_*/filearchive;
+
+DROP TABLE /*_*/filearchive;
+ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
+CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
+CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
+CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
+CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
+CREATE INDEX /*i*/fa_actor_timestamp ON /*_*/filearchive (fa_actor,fa_timestamp);
+
+COMMIT;
diff --git a/maintenance/sqlite/archives/patch-filearchive-fa_description_id.sql b/maintenance/sqlite/archives/patch-filearchive-fa_description_id.sql
new file mode 100644 (file)
index 0000000..c5361ed
--- /dev/null
@@ -0,0 +1,60 @@
+--
+-- patch-filearchive-fa_description_id.sql
+--
+-- Split from patch-comment-table.sql to work around SQLite unconditionally running
+-- patch-add-3d.sql on a fresh install, which wipes out fa_description_id and
+-- fa_deleted_reason_id.
+
+BEGIN;
+
+DROP TABLE IF EXISTS /*_*/filearchive_tmp;
+CREATE TABLE /*_*/filearchive_tmp (
+  fa_id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
+  fa_name varchar(255) binary NOT NULL default '',
+  fa_archive_name varchar(255) binary default '',
+  fa_storage_group varbinary(16),
+  fa_storage_key varbinary(64) default '',
+  fa_deleted_user int,
+  fa_deleted_timestamp binary(14) default '',
+  fa_deleted_reason varbinary(767) default '',
+  fa_deleted_reason_id bigint unsigned NOT NULL DEFAULT 0,
+  fa_size int unsigned default 0,
+  fa_width int default 0,
+  fa_height int default 0,
+  fa_metadata mediumblob,
+  fa_bits int default 0,
+  fa_media_type ENUM("UNKNOWN", "BITMAP", "DRAWING", "AUDIO", "VIDEO", "MULTIMEDIA", "OFFICE", "TEXT", "EXECUTABLE", "ARCHIVE", "3D") default NULL,
+  fa_major_mime ENUM("unknown", "application", "audio", "image", "text", "video", "message", "model", "multipart", "chemical") default "unknown",
+  fa_minor_mime varbinary(100) default "unknown",
+  fa_description varbinary(767) default '',
+  fa_description_id bigint unsigned NOT NULL DEFAULT 0,
+  fa_user int unsigned default 0,
+  fa_user_text varchar(255) binary,
+  fa_timestamp binary(14) default '',
+  fa_deleted tinyint unsigned NOT NULL default 0,
+  fa_sha1 varbinary(32) NOT NULL default ''
+) /*$wgDBTableOptions*/;
+
+INSERT OR IGNORE INTO /*_*/filearchive_tmp (
+       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
+       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
+       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
+       fa_deleted, fa_sha1)
+  SELECT
+       fa_id, fa_name, fa_archive_name, fa_storage_group, fa_storage_key,
+       fa_deleted_user, fa_deleted_timestamp, fa_deleted_reason, fa_size,
+       fa_width, fa_height, fa_metadata, fa_bits, fa_media_type, fa_major_mime,
+       fa_minor_mime, fa_description, fa_user, fa_user_text, fa_timestamp,
+       fa_deleted, fa_sha1
+  FROM /*_*/filearchive;
+
+DROP TABLE /*_*/filearchive;
+ALTER TABLE /*_*/filearchive_tmp RENAME TO /*_*/filearchive;
+CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
+CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
+CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
+CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1(10));
+
+COMMIT;
index 3c8b598..72db8c3 100644 (file)
@@ -1846,23 +1846,17 @@ CREATE TABLE /*_*/change_tag (
   ct_log_id int unsigned NULL,
   -- REVID for the change
   ct_rev_id int unsigned NULL,
-  -- Tag applied, this will go away and be replaced with ct_tag_id
-  ct_tag varchar(255) NOT NULL default '',
   -- Parameters for the tag; used by some extensions
   ct_params blob NULL,
-  -- Foreign key to change_tag_def row, this will be "NOT NULL" once populated
-  ct_tag_id int unsigned NULL
+  -- Foreign key to change_tag_def row
+  ct_tag_id int unsigned NOT NULL
 ) /*$wgDBTableOptions*/;
 
-CREATE INDEX /*i*/change_tag_rc_tag_nonuniq ON /*_*/change_tag (ct_rc_id,ct_tag);
-CREATE INDEX /*i*/change_tag_log_tag_nonuniq ON /*_*/change_tag (ct_log_id,ct_tag);
-CREATE INDEX /*i*/change_tag_rev_tag_nonuniq ON /*_*/change_tag (ct_rev_id,ct_tag);
 
 CREATE UNIQUE INDEX /*i*/change_tag_rc_tag_id ON /*_*/change_tag (ct_rc_id,ct_tag_id);
 CREATE UNIQUE INDEX /*i*/change_tag_log_tag_id ON /*_*/change_tag (ct_log_id,ct_tag_id);
 CREATE UNIQUE INDEX /*i*/change_tag_rev_tag_id ON /*_*/change_tag (ct_rev_id,ct_tag_id);
 -- Covering index, so we can pull all the info only out of the index.
-CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 CREATE INDEX /*i*/change_tag_tag_id_id ON /*_*/change_tag (ct_tag_id,ct_rc_id,ct_rev_id,ct_log_id);
 
 -- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT
index 2468c71..1b2574d 100644 (file)
@@ -10,7 +10,6 @@
 .config-block {
        margin-top: 2em;
        display: block;
-
 }
 
 .config-block-label {
index ac26a53..e3379ca 100644 (file)
@@ -27,8 +27,8 @@
     "karma-qunit": "2.1.0",
     "postcss-less": "2.0.0",
     "qunit": "2.6.2",
-    "stylelint": "9.2.0",
-    "stylelint-config-wikimedia": "0.4.3",
+    "stylelint": "9.6.0",
+    "stylelint-config-wikimedia": "0.5.0",
     "wdio-junit-reporter": "0.2.0",
     "wdio-mediawiki": "file:tests/selenium/wdio-mediawiki",
     "wdio-mocha-framework": "0.5.13",
index cb1f2bd..0385d80 100644 (file)
@@ -1372,7 +1372,6 @@ return [
                'dependencies' => [
                        'jquery.accessKeyLabel',
                        'mediawiki.RegExp',
-                       'mediawiki.notify',
                ],
                'targets' => [ 'desktop', 'mobile' ],
        ],
index 9036dd3..ea60702 100644 (file)
@@ -4,9 +4,10 @@
        z-index: 100000;
        cursor: default;
 }
+
 .tipsy-inner {
        padding: 5px 8px 4px 8px;
-       /*background-color: #e8f2f8;*/
+       /* background-color: #e8f2f8; */
        background-color: #fff;
        border: solid 1px #a7d7f9;
        color: #000;
@@ -20,6 +21,7 @@
        filter: progid:DXImageTransform.Microsoft.DropShadow(OffX=0, OffY=2, Strength=6, Direction=90, Color='#cccccc');
        */
 }
+
 .tipsy-arrow {
        position: absolute;
        /* @embed */
        width: 11px;
        height: 6px;
 }
-/* @noflip */ .tipsy-n .tipsy-arrow {
+
+/* @noflip */
+.tipsy-n .tipsy-arrow {
        top: 0;
        left: 50%;
        margin-left: -5px;
 }
-/* @noflip */ .tipsy-nw .tipsy-arrow {
+
+/* @noflip */
+.tipsy-nw .tipsy-arrow {
        top: 0;
        left: 10px;
 }
-/* @noflip */ .tipsy-ne .tipsy-arrow {
+
+/* @noflip */
+.tipsy-ne .tipsy-arrow {
        top: 0;
        right: 10px;
 }
-/* @noflip */ .tipsy-s .tipsy-arrow {
+
+/* @noflip */
+.tipsy-s .tipsy-arrow {
        bottom: 0;
        left: 50%;
        margin-left: -5px;
        background-position: bottom left;
 }
-/* @noflip */ .tipsy-sw .tipsy-arrow {
+
+/* @noflip */
+.tipsy-sw .tipsy-arrow {
        bottom: 0;
        left: 10px;
        background-position: bottom left;
 }
-/* @noflip */ .tipsy-se .tipsy-arrow {
+
+/* @noflip */
+.tipsy-se .tipsy-arrow {
        bottom: 0;
        right: 10px;
        background-position: bottom left;
 }
-/* @noflip */ .tipsy-e .tipsy-arrow {
+
+/* @noflip */
+.tipsy-e .tipsy-arrow {
        top: 50%;
        margin-top: -5px;
        right: 0;
@@ -64,7 +80,9 @@
        height: 11px;
        background-position: top right;
 }
-/* @noflip */ .tipsy-w .tipsy-arrow {
+
+/* @noflip */
+.tipsy-w .tipsy-arrow {
        top: 50%;
        margin-top: -5px;
        left: 0;
index fc52d51..bc37943 100644 (file)
        -ms-user-select: none;
        user-select: none;
 }
+
 .mw-collapsible-toggle-default:before {
        content: '[';
 }
+
 .mw-collapsible-toggle-default:after {
        content: ']';
 }
@@ -24,7 +26,7 @@
        cursor: pointer;
 }
 
-/* collapse links in captions should be inline */
+/* Collapse links in captions should be inline */
 caption .mw-collapsible-toggle,
 .mw-content-ltr caption .mw-collapsible-toggle,
 .mw-content-rtl caption .mw-collapsible-toggle,
index ea5b6dd..1ab91a9 100644 (file)
@@ -25,7 +25,6 @@
 @exclude: ~'.mw-made-collapsible';
 
 .client-js {
-
        ol.mw-collapsible:before,
        ul.mw-collapsible:before,
        .mw-collapsible-toggle-li {
@@ -76,8 +75,7 @@
                // Avoid FOUC/reflows on collapsed elements by making sure they are opened by default (T42812)
                > p,
                > table,
-               // Manual:Collapsible_elements/Demo/Simple#Collapsed_by_default
-               > thead + tbody,
+               > thead + tbody, // 'https://www.mediawiki.org/wiki/Manual:Collapsible_elements/Demo/Simple#Collapsed_by_default'
                tr:not( :first-child ),
                .mw-collapsible-content {
                        display: none;
index 0bcb2b6..44baa8b 100644 (file)
 
        /**
         * Check if a given namespace is a talk namespace
+        *
+        * See MWNamespace::isTalk in PHP
+        *
         * @param {number} namespaceId Namespace ID
         * @return {boolean} Namespace is a talk namespace
         */
                return !!( namespaceId > NS_MAIN && namespaceId % 2 );
        };
 
+       /**
+        * Check if signature buttons should be shown in a given namespace
+        *
+        * See MWNamespace::wantSignatures in PHP
+        *
+        * @param {number} namespaceId Namespace ID
+        * @return {boolean} Namespace is a signature namespace
+        */
+       Title.wantSignaturesNamespace = function ( namespaceId ) {
+               return this.isTalkNamespace( namespaceId ) ||
+                       mw.config.get( 'wgExtraSignatureNamespaces' ).indexOf( namespaceId ) !== -1;
+       };
+
        /**
         * Whether this title exists on the wiki.
         *
index a481074..abdee12 100644 (file)
@@ -3,11 +3,13 @@
 .mw-category {
        .column-count(3);
        .column-width(24em);
+
        .mw-category-group {
                ul {
                        margin-top: 0;
                        margin-bottom: 0;
                }
+
                li {
                        .column-break-inside-avoid;
                }
index d3e4950..7528fdb 100644 (file)
@@ -97,9 +97,11 @@ div.apihelp-linktrail {
 .api-main-links {
        text-align: center;
 }
+
 .api-main-links ul:before {
        content: '[';
 }
+
 .api-main-links ul:after {
        content: ']';
 }
index f1e829c..32dbdc1 100644 (file)
                                        .append( $( '<td>' ).text( i + 1 ) )
                                        .append( $( '<td>' ).text( query.sql ) )
                                        .append( $( '<td>' ).text( ( query.time * 1000 ).toFixed( 4 ) + 'ms' ).addClass( 'stats' ) )
-                                       .append( $( '<td>' ).text( query[ 'function' ] ) )
+                                       .append( $( '<td>' ).text( query.function ) )
                                        .appendTo( $table );
                        }
 
index ac33b84..92e1d04 100644 (file)
        margin-bottom: 1em;
 }
 
-/* Overwriting OOUI is no fun */
+/* Overwriting OOUI */
 .mw-feedbackDialog-feedback-form .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-header {
        min-width: 4.2em;
        width: 20%;
 }
+
 .mw-feedbackDialog-feedback-form .oo-ui-fieldLayout.oo-ui-labelElement.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-body > .oo-ui-fieldLayout-field {
        width: 80%;
 }
index 2663d87..e25a92f 100644 (file)
@@ -6,22 +6,26 @@
 .hlist dt:after {
        content: ':';
 }
+
 .hlist dd:after,
 .hlist li:after {
        content: ' ·';
        font-weight: bold;
 }
+
 .hlist dd:last-child:after,
 .hlist dt:last-child:after,
 .hlist li:last-child:after {
        content: none;
 }
+
 /* For IE8 */
 .hlist dd.hlist-last-child:after,
 .hlist dt.hlist-last-child:after,
 .hlist li.hlist-last-child:after {
        content: none;
 }
+
 /* Add parentheses around nested lists */
 .hlist dd dd:first-child:before,
 .hlist dd dt:first-child:before,
@@ -35,6 +39,7 @@
        content: '(';
        font-weight: normal;
 }
+
 .hlist dd dd:last-child:after,
 .hlist dd dt:last-child:after,
 .hlist dd li:last-child:after,
@@ -47,6 +52,7 @@
        content: ')';
        font-weight: normal;
 }
+
 /* For IE8 */
 .hlist dd dd.hlist-last-child:after,
 .hlist dd dt.hlist-last-child:after,
        content: ')';
        font-weight: normal;
 }
+
 /* Put ordinals in front of ordered list items */
 .hlist ol {
        counter-reset: list-item;
 }
+
 .hlist ol > li {
        counter-increment: list-item;
 }
+
 .hlist ol > li:before {
        content: counter( list-item ) ' ';
 }
+
 .hlist dd ol > li:first-child:before,
 .hlist dt ol > li:first-child:before,
 .hlist li ol > li:first-child:before {
index 3feb9a1..8f1d563 100644 (file)
@@ -78,9 +78,9 @@
        }
 }
 
-// Flatlist styling for PHP widgets...
+// Flatlist styling for PHP (`.oo-ui-fieldLayout-align-inline`) &
+// JS (`.oo-ui-radioOptionWidget, .oo-ui-checkboxMultioptionWidget`) widgets
 .mw-htmlform-flatlist .oo-ui-fieldLayout-align-inline,
-// ...and for JS widgets
 .mw-htmlform-flatlist .oo-ui-radioOptionWidget,
 .mw-htmlform-flatlist .oo-ui-checkboxMultioptionWidget {
        display: inline-block;
index 1c69a75..d943219 100644 (file)
@@ -47,7 +47,6 @@ tr.mw-htmlform-vertical-label td.mw-label {
        margin-left: 4px;
 }
 
-/* stylelint-disable indentation */
 .mw-icon-question:lang( ar ),
 .mw-icon-question:lang( fa ),
 .mw-icon-question:lang( ur ) {
index f5a8272..caaebad 100644 (file)
@@ -153,7 +153,9 @@ img.thumbborder {
 
 /* Page history styling */
 /* the auto-generated edit comments */
-.autocomment {
+.autocomment,
+.autocomment a,
+.autocomment a:visited {
        color: #4b4b4b;
 }
 
index cdf47d0..a98a73f 100644 (file)
@@ -256,7 +256,9 @@ p.mw-delete-editreasons {
 }
 
 /* The auto-generated edit comments */
-.autocomment {
+.autocomment,
+.autocomment a,
+.autocomment a:visited {
        color: #72777d;
 }
 
index 7e7821e..fe5647f 100644 (file)
@@ -54,7 +54,7 @@
 }
 
 .hyphens( @value: auto ) {
-       & when ( @value = auto ){
+       & when ( @value = auto ) {
                // Legacy `word-wrap`; IE 6-11, Edge 12+, Firefox 3.5+, Chrome 4+, Safari 3.1+,
                //   Opera 11.5+, iOS 3.2+, Android 2.1+
                // `overflow-wrap` is W3 standard, but it doesn't seem as if browser vendors
@@ -92,7 +92,6 @@
 // and remaining parameters are additional transitions."
 .transition-transform( ... ) {
        -webkit-backface-visibility: hidden; // Older Webkit browsers: Promote element to a composite layer & involve the GPU
-
        -webkit-transition: -webkit-transform @arguments; // Safari 3.1-8, iOS 3.2-8.4, Android 2.1-4.4.4
        -moz-transition: -moz-transform @arguments; // Firefox 4-15 for `-moz-transition`
        transition: transform @arguments; // Chrome 36+, Firefox 16+, IE 10+, Safari 9+, Opera 12.1+, iOS 9.2+, Android 36+
        -webkit-box-flex: @grow; // iOS 6-, Safari 3.1-6
        -moz-box-flex: @grow; // Firefox 21-
        width: @width; // Fallback for flex-basis
-
        -ms-flex: @grow @shrink @width; // IE 10
        flex: @grow @shrink @width;
-
        -webkit-box-ordinal-group: @order; // iOS 6-, Safari 3.1-6
        -moz-box-ordinal-group: @order; // Firefox 21-
        -ms-flex-order: @order; // IE 10
index 64d6b3d..ccc9564 100644 (file)
@@ -7,6 +7,7 @@
        from {
                .transform-rotate( 0deg );
        }
+
        to {
                .transform-rotate( 360deg );
        }
index a56be76..c36b8d8 100644 (file)
@@ -17,7 +17,6 @@
        background-color: #fff;
        /* Click handler in mediawiki.notification.js */
        cursor: pointer;
-
        opacity: 0;
        -webkit-transform: translateX( 35px );
        transform: translateX( 35px );
index 047c933..f7a3f0d 100644 (file)
@@ -56,4 +56,3 @@ ul.mw-gallery-packed-hover li.gallerybox.mw-gallery-focused div.gallerytextwrapp
        white-space: normal;
        overflow: visible;
 }
-
index 9101fba..689f322 100644 (file)
@@ -24,7 +24,6 @@
        // On the watchlist, reserve a bit more
        .mw-special-Watchlist .rcfilters-head {
                min-height: @rcfilters-wl-head-min-height;
-
        }
 
        .mw-rcfilters-collapsed {
@@ -79,7 +78,6 @@
                        .cloptions {
                                display: none;
                        }
-
                }
        }
 
                        .animation-delay( 0s );
                }
        }
+
        body:not( .mw-rcfilters-ui-initialized ) .rcfilters-spinner {
                display: block;
                // When initializing, display the spinner on top of the area where the UI will appear
                margin-top: -( @rcfilters-head-min-height + @rcfilters-head-margin-bottom ) / 1.5;
        }
+
        body.mw-rcfilters-ui-loading .rcfilters-spinner {
                display: block;
                // When loading new results, display the spinner on top of the results area
        100% {
                -webkit-transform: scale( 0.625 );
        }
+
        20% { // equals 320ms
                opacity: 0.87;
                -webkit-transform: scale( 1 );
        100% {
                -moz-transform: scale( 0.625 );
        }
+
        20% {
                opacity: 0.87;
                -moz-transform: scale( 1 );
        100% {
                transform: scale( 0.625 );
        }
+
        20% { // equals 320ms
                opacity: 0.87;
                transform: scale( 1 );
index 516a79b..96a791f 100644 (file)
@@ -41,7 +41,6 @@ div.mw-rcfilters-ui-highlights {
                                        .mw-rcfilters-circle-color( @highlight-bluedot, true, @highlight-bluedot );
                                }
                        }
-
                }
 
                // Watchlist unseen highlighted fixes
index 16f110a..87f257b 100644 (file)
@@ -6,6 +6,7 @@
        60% {
                border-top-color: @colorProgressive;
        }
+
        100% {
                border-top-color: @colorGray12;
        }
index 93fae1e..d74f4d0 100644 (file)
                        &-c1 {
                                .mw-rcfilters-circle-color( @highlight-c1 );
                        }
+
                        &-c2 {
                                .mw-rcfilters-circle-color( @highlight-c2 );
                        }
+
                        &-c3 {
                                .mw-rcfilters-circle-color( @highlight-c3 );
                        }
+
                        &-c4 {
                                .mw-rcfilters-circle-color( @highlight-c4 );
                        }
+
                        &-c5 {
                                .mw-rcfilters-circle-color( @highlight-c5 );
                        }
index aa285e6..d67739d 100644 (file)
@@ -78,6 +78,7 @@
                                padding: 0.6em 0; // Same top padding as the handle
                                flex: 0 0 auto;
                        }
+
                        &-queryName {
                                flex: 1 1 auto;
                                padding: 0.6em 0; // Same top padding as the handle
index e6003c1..949980d 100644 (file)
@@ -12,7 +12,6 @@
        &-bottom {
                .flex-display;
                .flex;
-
                margin-top: 1em;
        }
 }
index deecd67..4fa5183 100644 (file)
@@ -50,6 +50,7 @@
                                        background-color: @highlight-none;
                                }
                        }
+
                        &-c1 {
                                .mw-rcfilters-circle-color( @highlight-c1, false );
                                border-color: @highlight-c1;
@@ -60,6 +61,7 @@
                                        background-color: @highlight-c1;
                                }
                        }
+
                        &-c2 {
                                .mw-rcfilters-circle-color( @highlight-c2, true );
                                border-color: @highlight-c2;
@@ -70,6 +72,7 @@
                                        background-color: @highlight-c2;
                                }
                        }
+
                        &-c3 {
                                .mw-rcfilters-circle-color( @highlight-c3, true );
                                border-color: @highlight-c3;
@@ -80,6 +83,7 @@
                                        background-color: @highlight-c3;
                                }
                        }
+
                        &-c4 {
                                .mw-rcfilters-circle-color( @highlight-c4, true );
                                border-color: @highlight-c4;
@@ -90,6 +94,7 @@
                                        background-color: @highlight-c4;
                                }
                        }
+
                        &-c5 {
                                .mw-rcfilters-circle-color( @highlight-c5, true );
                                border-color: @highlight-c5;
index 61872bd..5c3c0df 100644 (file)
@@ -14,9 +14,8 @@
                border-top: 4px solid @colorGray12;
        }
 
-       // Don't show border for first namespace
+       // Don't show border for first namespace & hide for every 'talk' option in second selector
        &-view-default + &-view-namespaces,
-       // Hide for every 'talk' option
        &-view-namespaces&.mw-rcfilters-ui-itemMenuOptionWidget-identifier-subject + &-view-namespaces.mw-rcfilters-ui-itemMenuOptionWidget-identifier-talk {
                border-top: 0;
        }
@@ -40,6 +39,7 @@
                        font-size: 1.15em;
                        color: @colorGray2;
                }
+
                &-desc {
                        color: @colorGray5;
                        white-space: normal;
index f210a44..e593966 100644 (file)
                .transform( scale( 0 ) );
                opacity: 1;
        }
+
        50% {
                .transform( scale( 1.5 ) );
                opacity: 0.8;
        }
+
        80%,
        100% {
                opacity: 0;
index 824485f..31a5f54 100644 (file)
@@ -16,6 +16,7 @@
                .oo-ui-labelElement-label {
                        color: @colorGray7;
                }
+
                .oo-ui-buttonWidget {
                        opacity: @muted-opacity;
                }
index 2957080..3104a69 100644 (file)
@@ -34,7 +34,6 @@
        /* IE7 and earlier */
        zoom: 1;
        *display: inline; /* stylelint-disable declaration-block-no-duplicate-properties */
-
        padding: 7px;
 }
 
index 3f33837..8b2657d 100644 (file)
@@ -120,6 +120,7 @@ figure[ typeof~='mw:Audio/Frame' ] {
                /* @noflip */
                margin: 0.5em 1.4em 1.3em 0;
        }
+
        &.mw-halign-right {
                /* @noflip */
                margin: 0.5em 0 1.3em 1.4em;
@@ -198,6 +199,7 @@ figure[ typeof*='mw:Audio/Thumb' ] {
                display: inline-block;
                height: 100%;
        }
+
        > * {
                vertical-align: middle;
                display: inline-block;
@@ -213,24 +215,31 @@ figure[ typeof*='mw:Audio/Thumb' ] {
                .mw-valign-middle > & {
                        vertical-align: middle;
                }
+
                .mw-valign-baseline > & {
                        vertical-align: baseline;
                }
+
                .mw-valign-sub > & {
                        vertical-align: sub;
                }
+
                .mw-valign-super > & {
                        vertical-align: super;
                }
+
                .mw-valign-top > & {
                        vertical-align: top;
                }
+
                .mw-valign-text-top > & {
                        vertical-align: text-top;
                }
+
                .mw-valign-bottom > & {
                        vertical-align: bottom;
                }
+
                .mw-valign-text-bottom > & {
                        vertical-align: text-bottom;
                }
index 301024d..db9265a 100644 (file)
@@ -53,10 +53,12 @@ a.mw-selflink {
        font-weight: bold;
        text-decoration: inherit;
 }
+
 a.mw-selflink:hover {
        cursor: inherit;
        text-decoration: inherit;
 }
+
 a.mw-selflink:active,
 a.mw-selflink:visited {
        color: inherit;
index fe5ac41..d7415c9 100644 (file)
@@ -1,6 +1,6 @@
 .mw-apisandbox-toolbar {
        background: #fff;
-       -webkit-position: sticky;
+       position: -webkit-sticky;
        position: sticky;
        top: 0;
        margin-bottom: -1px;
index 52bcd30..3762ae7 100644 (file)
@@ -33,7 +33,7 @@
                this.checkbox = new OO.ui.CheckboxInputWidget( config.checkbox )
                        .on( 'change', this.onCheckboxChange, [], this );
 
-               OptionalWidget[ 'super' ].call( this, config );
+               OptionalWidget.super.call( this, config );
 
                // Forward most methods for convenience
                for ( k in this.widget ) {
@@ -75,7 +75,7 @@
                }
        };
        OptionalWidget.prototype.setDisabled = function ( disabled ) {
-               OptionalWidget[ 'super' ].prototype.setDisabled.call( this, disabled );
+               OptionalWidget.super.prototype.setDisabled.call( this, disabled );
                this.widget.setDisabled( this.isDisabled() );
                this.checkbox.setSelected( !this.isDisabled() );
                this.$cover.toggle( this.isDisabled() );
@@ -90,7 +90,7 @@
                        },
                        setApiValue: function ( v ) {
                                if ( v === undefined ) {
-                                       v = this.paramInfo[ 'default' ];
+                                       v = this.paramInfo.default;
                                }
                                this.setValue( v );
                        },
                                var menu = this.getMenu();
 
                                if ( v === undefined ) {
-                                       v = this.paramInfo[ 'default' ];
+                                       v = this.paramInfo.default;
                                }
                                if ( v === undefined ) {
                                        menu.selectItem();
                                }
                        },
                        getApiValueForTemplates: function () {
-                               return this.isDisabled() ? this.parseApiValue( this.paramInfo[ 'default' ] ) : this.getValue();
+                               return this.isDisabled() ? this.parseApiValue( this.paramInfo.default ) : this.getValue();
                        },
                        getApiValue: function () {
                                var items = this.getValue();
                        },
                        setApiValue: function ( v ) {
                                if ( v === undefined ) {
-                                       v = this.paramInfo[ 'default' ];
+                                       v = this.paramInfo.default;
                                }
                                this.setValue( this.parseApiValue( v ) );
                        },
 
                submoduleWidget: {
                        single: function () {
-                               var v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
+                               var v = this.isDisabled() ? this.paramInfo.default : this.getApiValue();
                                return v === undefined ? [] : [ { value: v, path: this.paramInfo.submodules[ v ] } ];
                        },
                        multi: function () {
                                var map = this.paramInfo.submodules,
-                                       v = this.isDisabled() ? this.paramInfo[ 'default' ] : this.getApiValue();
+                                       v = this.isDisabled() ? this.paramInfo.default : this.getApiValue();
                                return v === undefined || v === '' ? [] : String( v ).split( '|' ).map( function ( v ) {
                                        return { value: v, path: map[ v ] };
                                } );
                                finalWidget.setDisabled( true );
                        }
 
-                       widget.setApiValue( pi[ 'default' ] );
+                       widget.setApiValue( pi.default );
 
                        return finalWidget;
                },
                                                                .text( data )
                                                                .appendTo( $result );
                                                }
-                                               if ( paramsAreForced || data[ 'continue' ] ) {
+                                               if ( paramsAreForced || data.continue ) {
                                                        $result.append(
                                                                $( '<div>' ).append(
                                                                        new OO.ui.ButtonWidget( {
                                                                                label: mw.message( 'apisandbox-continue' ).text()
                                                                        } ).on( 'click', function () {
-                                                                               ApiSandbox.sendRequest( $.extend( {}, baseRequestParams, data[ 'continue' ] ) );
-                                                                       } ).setDisabled( !data[ 'continue' ] ).$element,
+                                                                               ApiSandbox.sendRequest( $.extend( {}, baseRequestParams, data.continue ) );
+                                                                       } ).setDisabled( !data.continue ).$element,
                                                                        ( clear = new OO.ui.ButtonWidget( {
                                                                                label: mw.message( 'apisandbox-continue-clear' ).text()
                                                                        } ).on( 'click', function () {
                this.templatedItemsCache = {};
                this.tokenWidget = null;
                this.indentLevel = config.indentLevel ? config.indentLevel : 0;
-               ApiSandbox.PageLayout[ 'super' ].call( this, config.key, config );
+               ApiSandbox.PageLayout.super.call( this, config.key, config );
                this.loadParamInfo();
        };
        OO.inheritClass( ApiSandbox.PageLayout, OO.ui.PageLayout );
                                        for ( i = 0; i < pi.parameters.length; i++ ) {
                                                if ( pi.parameters[ i ].name === 'action' ) {
                                                        pi.parameters[ i ].required = true;
-                                                       delete pi.parameters[ i ][ 'default' ];
+                                                       delete pi.parameters[ i ].default;
                                                }
                                                if ( pi.parameters[ i ].name === 'format' ) {
                                                        tmp = pi.parameters[ i ].type;
                                                                availableFormats[ tmp[ j ] ] = true;
                                                        }
                                                        pi.parameters[ i ].type = tmp.filter( filterFmModules );
-                                                       pi.parameters[ i ][ 'default' ] = 'json';
+                                                       pi.parameters[ i ].default = 'json';
                                                        pi.parameters[ i ].required = true;
                                                }
                                        }
index c013994..c319294 100644 (file)
@@ -1,5 +1,6 @@
 .mw-block-page-restrictions {
        margin-left: 2em;
+
        .oo-ui-widget {
                max-width: 48em;
        }
index c87a8a1..db33f4a 100644 (file)
@@ -75,6 +75,7 @@
        &:before {
                content: '@{msg-parentheses-start}';
        }
+
        &:after {
                content: '@{msg-parentheses-end}';
        }
index 5869303..37d3a16 100644 (file)
@@ -17,6 +17,7 @@
 #preferences > fieldset table {
        width: 100%;
 }
+
 #preferences > fieldset table.mw-htmlform-matrix {
        width: auto;
 }
index 6f91ad2..b1931f4 100644 (file)
 .mw-email-authenticated .oo-ui-labelWidget { }
 */
 
+/*
+ * Use `position: sticky` on supported browsers, degrades gracefully in
+ * all others, therefore no `@supports` feature query to reduce code complexity.
+ */
+.mw-prefs-buttons {
+       background-color: #fff;
+       position: -webkit-sticky;
+       position: sticky;
+       bottom: 0;
+       margin-top: -1px;
+       border-top: 1px solid #c8ccd1;
+       padding: 1em 0;
+}
+
 /* This is needed because add extra buttons in a weird way */
 .mw-prefs-buttons .mw-htmlform-submit-buttons {
        display: inline;
        margin: 0;
 }
 
-.mw-prefs-buttons {
-       margin-top: 1em;
-}
-
 #prefcontrol {
        margin-right: 0.5em;
 }
index 7265399..81c8dc9 100644 (file)
@@ -1,11 +1,10 @@
-/* interwiki search results */
-/*==========================*/
+/* Interwiki search results */
+/* ======================== */
 
 @import 'mediawiki.ui/variables.less';
 @import 'mediawiki.mixins';
 
 .mw-searchresults-has-iw {
-
        .iw-headline {
                font-weight: bold;
        }
        }
 
        .iw-result__title {
-               font-size: 108%; /* matching regular search title */
+               font-size: 108%; /* Matching regular search title */
        }
 
        .iw-result:after,
-       .iw-result__content:after { /* clearfix */
+       .iw-result__content:after { /* Clearfix */
                visibility: hidden;
                display: block;
                font-size: 0;
 
        .iw-result__footer {
                float: right;
-               font-size: 97%; /* matching main search result font-size */
+               font-size: 97%; /* Matching main search result font-size */
                margin-top: 0.5em;
        }
+
        .iw-result__footer a {
                vertical-align: middle;
                font-style: italic;
@@ -54,7 +54,7 @@
                padding-right: 1em;
        }
 
-       /* image search result */
+       /* Image search result */
        .iw-result__mini-gallery {
                position: relative;
                float: left;
@@ -64,7 +64,7 @@
                padding: 0.25rem;
        }
 
-       /* second and third images are small */
+       /* Second and third images are small */
        .iw-result__mini-gallery:nth-child( 2 ),
        .iw-result__mini-gallery:nth-child( 3 ) { /* stylelint-disable-line indentation */
                width: 50%;
@@ -82,7 +82,7 @@
                background-position: center center;
        }
 
-       /* image gallery text */
+       /* Image gallery text */
        .iw-result__mini-gallery__image > .iw-result__mini-gallery__caption {
                visibility: hidden;
                position: absolute;
                visibility: visible;
        }
 
-       /* tablet and up */
-
+       /* Tablet and up */
        @media only screen and ( min-width: @width-breakpoint-tablet ) {
-
                #mw-interwiki-results {
                        width: 30%;
-                       display: inline-block; /* used to align interwiki sidebar with the top of the main search results */
-                       margin-left: 8%; /* since inline-block causes whitespace issues, this is 8 instead of 10% */
+                       display: inline-block; /* Used to align interwiki sidebar with the top of the main search results */
+                       margin-left: 8%; /* Since inline-block causes whitespace issues, this is 8 instead of 10% */
                }
+
                .mw-search-createlink,
                .mw-search-nonefound,
                .mw-search-results,
index 59a15a9..1179f90 100644 (file)
 .searchresult {
        display: inline !ie;
 }
+
 .searchresults {
        margin: 1em 0 1em 0.4em;
 }
+
 /* needs extra specificity to override `.mw-body p` selector */
 .mw-body .mw-search-nonefound {
        margin: 0;
 .mw-search-visualclear {
        clear: both;
 }
+
 .mw-search-results li {
        padding-bottom: 1.2em;
        list-style: none;
        list-style-image: none;
 }
+
 .mw-search-results li a {
        font-size: 108%;
 }
+
 .mw-search-result-data {
        color: #008000;
        font-size: 97%;
 }
+
 .mw-search-profile-tabs {
        background-color: #f8f9fa;
        margin-top: 1em;
        border: 1px solid #c8ccd1;
        border-radius: 2px;
 }
+
 .search-types {
        float: left;
        padding-left: 0.25em;
 }
+
 .search-types ul {
        margin: 0;
        padding: 0;
        list-style: none;
 }
+
 .search-types li {
        float: left;
        margin: 0;
        padding: 0;
 }
+
 .search-types a {
        display: block;
        padding: 0.5em;
 }
+
 .search-types .current a {
        color: #222;
        cursor: default;
 }
+
 .search-types .current a:hover {
        text-decoration: none;
 }
+
 .results-info {
        float: right;
        padding: 0.5em;
        color: #54595d;
        font-size: 95%;
 }
+
 #mw-search-top-table div.oo-ui-actionFieldLayout {
        float: left;
        width: 100%;
 }
 
 /* Advanced options menu */
-/*==========================*/
+/* ===================== */
 
 #mw-searchoptions {
        /* Support: Firefox, needs `clear: both` on `fieldset` when zoom level > 100%, see T176499 */
        border: 1px solid #c8ccd1;
        border-radius: 0 0 2px 2px;
 }
+
 #mw-searchoptions legend {
        display: none;
 }
+
 #mw-searchoptions h4 {
        padding: 0;
        margin: 0;
        float: left;
 }
+
 #mw-searchoptions table {
        float: left;
        margin-right: 3em;
        border-collapse: collapse;
 }
+
 #mw-searchoptions table td {
        padding: 0 1em 0 0;
        white-space: nowrap;
 }
+
 #mw-searchoptions .divider {
        clear: both;
        border-bottom: 1px solid #eaecf0;
        padding-top: 0.5em;
        margin-bottom: 0.5em;
 }
+
 #mw-search-menu {
        padding-left: 6em;
        font-size: 85%;
 #mw-search-interwiki li {
        font-size: 95%;
 }
+
 .mw-search-interwiki-more {
        float: right;
        font-size: 90%;
 }
+
 #mw-search-interwiki-caption {
        text-align: center;
        font-weight: bold;
        font-size: 95%;
 }
+
 .mw-search-interwiki-project {
        font-size: 97%;
        text-align: left;
index aad784e..e55c785 100644 (file)
@@ -1,9 +1,11 @@
 #mw-search-togglebox {
        float: right;
 }
+
 #mw-search-togglebox label {
        margin-right: 0.25em;
 }
+
 #mw-search-togglebox input {
        margin-left: 0.25em;
 }
index fe013bc..97a986e 100644 (file)
        background-color: #f8f9fa;
        color: #36c;
 }
+
 #mw-createaccount-join:hover {
        background-color: #fff;
        border-color: #859ecc;
        box-shadow: none;
 }
+
 #mw-createaccount-join:active {
        background-color: #eff3fa;
        color: #2a4b8d;
        border-color: #2a4b8d;
 }
+
 #mw-createaccount-join:focus {
        border-color: #36c;
        box-shadow: inset 0 0 0 1px #36c;
index 0404c45..35cdee7 100644 (file)
@@ -68,6 +68,7 @@
 .mw-uctop {
        font-weight: bold;
 }
+
 .mw-contributions-form select {
        vertical-align: middle;
 }
@@ -92,6 +93,7 @@
 .mw-listgrouprights-table tr {
        vertical-align: top;
 }
+
 .listgrouprights-revoked {
        text-decoration: line-through;
 }
        white-space: nowrap;
        font-size: 90%;
 }
+
 .mw-protectedpages-unknown {
        color: #72777d;
        font-size: 90%;
index 1ffdf70..14ad695 100644 (file)
@@ -14,6 +14,7 @@
 .mw-userrights-disabled {
        color: #72777d;
 }
+
 .mw-userrights-groups * td,
 .mw-userrights-groups * th {
        padding-right: 1.5em;
index 4de2451..a9e4b78 100644 (file)
@@ -67,6 +67,7 @@ Styleguide 6.2.1.
        &:hover {
                color: @mainColor;
        }
+
        &:focus,
        &:active {
                color: darken( @mainColor, @colorDarkenPercentage );
index ecdcc46..b7175d0 100644 (file)
@@ -21,8 +21,7 @@
        }
 
        &:active,
-       &.is-on,
-       &.mw-ui-checked {
+       &.is-on {
                background-color: @activeColor;
                border-color: @activeColor;
                box-shadow: none;
@@ -35,8 +34,7 @@
 
                // Make sure disabled buttons don't have hover and active states
                &:hover,
-               &:active,
-               &.mw-ui-checked {
+               &:active {
                        background-color: @colorGray12;
                        color: #fff;
                        border-color: @colorGray12;
        }
 
        &:active,
-       &.is-on,
-       &.mw-ui-checked {
+       &.is-on {
                background-color: @colorGray12;
                color: @colorGray1;
                border-color: @colorGray7;
                        box-shadow: none;
                }
 
-               &:active,
-               &.mw-ui-checked {
+               &:active {
                        background-color: transparent;
                        color: @colorButtonTextActive;
                        border-color: transparent;
                                color: @colorProgressiveHighlight;
                        }
 
-                       &:active,
-                       &.mw-ui-checked {
+                       &:active {
                                color: @colorProgressiveActive;
                        }
 
                                color: @colorDestructiveHighlight;
                        }
 
-                       &:active,
-                       &.mw-ui-checked {
+                       &:active {
                                color: @colorDestructiveActive;
                        }
 
index 18ac318..09bf9ca 100644 (file)
@@ -36,7 +36,6 @@
 // Styleguide 5.1.
 .mw-ui-vform {
        .box-sizing( border-box );
-
        width: @defaultFormWidth;
 
        // MW currently doesn't use the type attribute everywhere on inputs.
                display: block;
                margin-top: 5px;
        }
-
 }
 
 // --------------------------------------------------------------------------
index 461de2f..1600493 100644 (file)
@@ -47,7 +47,6 @@
                @marginIcon: 2 * @iconGutterWidth;
                @width: @iconSize + @marginIcon;
                @sizeIconLarge: ( @iconSize * 1.75) + @marginIcon;
-
                text-indent: -999px;
                overflow: hidden;
                width: @width;
index 55d15b1..53c911b 100644 (file)
        vertical-align: middle;
 
        // Normalize & style placeholder text, see T139034
-       /* stylelint-disable indentation */
        .mixin-placeholder( {
                color: @colorGray7;
                opacity: 1;
        } );
-       /* stylelint-enable indentation */
 
        // Firefox: Remove red outline when `required` attribute set and invalid content.
        // See https://developer.mozilla.org/en-US/docs/Web/CSS/:invalid
index e2264c6..0bcded9 100644 (file)
@@ -29,6 +29,7 @@ Styleguide 6.1.
        &.mw-ui-progressive {
                color: @colorProgressive;
        }
+
        &.mw-ui-destructive {
                color: @colorDestructive;
        }
index 27031f1..65fe3d3 100644 (file)
                }
        };
 
-       /**
-        * Add a little box at the top of the screen to inform the user of
-        * something, replacing any previous message.
-        * Calling with no arguments, with an empty string or null will hide the message
-        *
-        * @method jsMessage
-        * @deprecated since 1.20 Use mw#notify
-        * @param {Mixed} message The DOM-element, jQuery object or HTML-string to be put inside the message box.
-        *  to allow CSS/JS to hide different boxes. null = no class used.
-        */
-       mw.log.deprecate( util, 'jsMessage', function ( message ) {
-               if ( !arguments.length || message === '' || message === null ) {
-                       return true;
-               }
-               if ( typeof message !== 'object' ) {
-                       message = $.parseHTML( message );
-               }
-               mw.notify( message, { autoHide: true, tag: 'legacy' } );
-               return true;
-       }, 'Use mw.notify instead.', 'mw.util.jsMessage' );
-
        /**
         * Initialisation of mw.util.$content
         */
index 0d664e4..3ad6e29 100644 (file)
@@ -40,7 +40,7 @@
                }, config );
 
                // Parent constructor
-               mw.widgets.datetime.CalendarWidget[ 'super' ].call( this, config );
+               mw.widgets.datetime.CalendarWidget.super.call( this, config );
 
                // Mixin constructors
                OO.ui.mixin.TabIndexedElement.call( this, $.extend( {}, config, { $tabIndexed: this.$element } ) );
                change = visible !== this.isVisible();
 
                // Parent method
-               mw.widgets.datetime.CalendarWidget[ 'super' ].prototype.toggle.call( this, visible );
+               mw.widgets.datetime.CalendarWidget.super.prototype.toggle.call( this, visible );
 
                if ( change ) {
                        if ( visible ) {
index e7afff8..5e4df47 100644 (file)
@@ -50,6 +50,7 @@
                                margin-left: 0;
                        }
                }
+
                .mw-widgets-datetime-calendarWidget-next {
                        float: right;
                }
index db9b7d6..ef7cea9 100644 (file)
@@ -64,7 +64,7 @@
                this.type = config.type;
 
                // Parent constructor
-               mw.widgets.datetime.DateTimeInputWidget[ 'super' ].call( this, config );
+               mw.widgets.datetime.DateTimeInputWidget.super.call( this, config );
 
                // Mixin constructors
                OO.ui.mixin.IconElement.call( this, config );
         * @inheritdoc
         */
        mw.widgets.datetime.DateTimeInputWidget.prototype.setDisabled = function ( disabled ) {
-               mw.widgets.datetime.DateTimeInputWidget[ 'super' ].prototype.setDisabled.call( this, disabled );
+               mw.widgets.datetime.DateTimeInputWidget.super.prototype.setDisabled.call( this, disabled );
 
                // Flag all our fields as disabled
                if ( this.$fields ) {
index 6635576..c64a550 100644 (file)
@@ -20,7 +20,7 @@
                config = $.extend( {}, config );
 
                // Parent constructor
-               mw.widgets.datetime.DiscordianDateTimeFormatter[ 'super' ].call( this, config );
+               mw.widgets.datetime.DiscordianDateTimeFormatter.super.call( this, config );
        };
 
        /* Setup */
                                break;
 
                        default:
-                               return mw.widgets.datetime.DiscordianDateTimeFormatter[ 'super' ].prototype.getFieldForTag.call( this, tag, params );
+                               return mw.widgets.datetime.DiscordianDateTimeFormatter.super.prototype.getFieldForTag.call( this, tag, params );
                }
 
                if ( spec ) {
index aaf8817..06dd2d5 100644 (file)
@@ -70,7 +70,7 @@
                }, config );
 
                // Parent constructor
-               mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'super' ].call( this, config );
+               mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.super.call( this, config );
 
                // Properties
                this.weekStartsOn = config.weekStartsOn % 7;
                                break;
 
                        default:
-                               return mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'super' ].prototype.getFieldForTag.call( this, tag, params );
+                               return mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.super.prototype.getFieldForTag.call( this, tag, params );
                }
 
                if ( spec ) {
index 1035786..253784e 100644 (file)
        // 7x7 grid
        width: @calendarWidth / 7;
        line-height: @calendarHeight / 7;
+
        // Don't overlap the hacked-up fake box-shadow border we get when focussed
        &:nth-child( 7n ) {
                width: @calendarWidth / 7 - 0.2em;
                margin-right: 0.2em;
        }
+
        &:nth-child( 7n+1 ) {
                width: @calendarWidth / 7 - 0.2em;
                margin-left: 0.2em;
        }
+
        &:nth-child( 42 ) ~ & {
                line-height: @calendarHeight / 7 - 0.2em;
                margin-bottom: 0.2em;
        // 2x6 grid
        width: @calendarWidth / 2;
        line-height: @calendarHeight / 6;
+
        // Don't overlap the hacked-up fake box-shadow border we get when focussed
        &:nth-child( 2n ) {
                width: @calendarWidth / 2 - 0.2em;
                margin-right: 0.2em;
        }
+
        &:nth-child( 2n+1 ) {
                width: @calendarWidth / 2 - 0.2em;
                margin-left: 0.2em;
        }
+
        &:nth-child( 10 ) ~ & {
                line-height: @calendarHeight / 6 - 0.2em;
                margin-bottom: 0.2em;
        // 5x4 grid
        width: @calendarWidth / 5;
        line-height: @calendarHeight / 4;
+
        // Don't overlap the hacked-up fake box-shadow border we get when focussed
        &:nth-child( 5n ) {
                width: @calendarWidth / 5 - 0.2em;
                margin-right: 0.2em;
        }
+
        &:nth-child( 5n+1 ) {
                width: @calendarWidth / 5 - 0.2em;
                margin-left: 0.2em;
        }
+
        &:nth-child( 15 ) ~ & {
                line-height: @calendarHeight / 4 - 0.2em;
                margin-bottom: 0.2em;
index 8be1e86..b7f58a6 100644 (file)
@@ -48,6 +48,7 @@
                > .mw-widgets-stashedFileWidget-fileName {
                        float: left;
                }
+
                > .mw-widgets-stashedFileWidget-fileType {
                        color: #72777d;
                        float: right;
index 5540c64..e52d0cd 100644 (file)
                                        width: 3.75em;
                                        height: 3.75em;
                                        left: 0;
+
                                        &:not( .mw-widget-titleOptionWidget-hasImage ) {
                                                background-color: #c8ccd1;
                                                opacity: 0.4;
                                        }
+
                                        &.mw-widget-titleOptionWidget-hasImage {
                                                border: 0;
                                                background-size: cover;
index e034fec..3fd6158 100644 (file)
@@ -1435,7 +1435,7 @@ Non-word characters don't terminate tag names
 !! end
 
 ###
-### See tests/parser/parserTestsParserHook.php for the <tåg> extension)
+### See tests/parser/ParserTestParserHook.php for the <tåg> extension)
 ### This checks that HTML5 tags (with non-word characters in the tag
 ### name) make it safely through the parser -- the Sanitizer will
 ### munge them later, as it should.
@@ -2359,6 +2359,17 @@ parsoid=wt2html,html2html
 </tbody></table><p> ho</p>
 !! end
 
+!! test
+P-wrapping non-breaking spaces
+!! wikitext
+!! html/php+tidy
+<p>&#160;
+</p>
+!! html/parsoid
+<p> </p>
+!! end
+
 ###
 ### Preformatted text
 ###
@@ -2834,7 +2845,7 @@ two">hi</pre>
 <pre class="one two">hi</pre>
 
 !! html/parsoid
-<pre typeof="mw:Extension/pre" about="#mwt2" class="one two" data-mw='{"name":"pre","attrs":{"class":"one two"},"body":{"extsrc":"hi"}}'>hi</pre>
+<pre class="one two" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"one two"},"body":{"extsrc":"hi"}}'>hi</pre>
 !! end
 
 !! test
@@ -2869,7 +2880,7 @@ parsoid=wt2html
 <pre>x</pre>
 &lt;pre <table></table>
 !! html/parsoid
-<pre typeof="mw:Transclusion mw:Extension/pre" about="#mwt2" data-parsoid='{"stx":"html","a":{"&lt;pre":null},"sa":{"&lt;pre":""},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
+<pre typeof="mw:Extension/pre mw:Transclusion" about="#mwt2" data-parsoid='{"stx":"html","a":{"&lt;pre":null},"sa":{"&lt;pre":""},"pi":[[{"k":"1"}]]}' data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre &lt;pre>x&lt;/pre>"}},"i":0}}]}'>x</pre>
 
 <pre data-parsoid='{"stx":"html","src":"&lt;pre &lt;/table>","tagWidths":[13,0],"a":{"&lt;":null,"table":null},"sa":{"&lt;":"","table":""},"fostered":true,"autoInsertedEnd":true}'></pre><table data-parsoid='{"stx":"html","autoInsertedEnd":true}'></table>
 !! end
@@ -3681,7 +3692,7 @@ array (
  <pre class="123">hi</pre>
 
 !! html/parsoid
- <pre typeof="mw:Extension/pre" about="#mwt2" class="123" data-mw='{"name":"pre","attrs":{"class":"123"},"body":{"extsrc":"hi"}}'>hi</pre>
+ <pre class="123" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"class":"123"},"body":{"extsrc":"hi"}}'>hi</pre>
 !! end
 
 !!test
@@ -6273,8 +6284,6 @@ parsoid=wt2html
 
 !! end
 
-# Note that the PHP parser output appears to be broken when the table
-# end tag is not separated by a space from the style attribute
 !! test
 A table with stray table end tags on start tag line (wt2html)
 !! options
@@ -6294,13 +6303,13 @@ parsoid=wt2html
 |foo
 |}
 !! html/php+tidy
-<table style="&quot;color:">
+<table style="color: red;">
 
 </table><table style="color: red;">
 <tbody><tr>
 <td>foo
 </td></tr></tbody></table>
-<table style="&quot;color:" id="foo">
+<table style="color: red;" id="foo">
 <tbody><tr>
 <td>foo
 </td></tr></tbody></table>
@@ -6925,9 +6934,9 @@ Don't break on | in extension attribute in template
 
 <references />
 !! html/parsoid
-<p><sup about="#mwt2" class="mw-ref" id="cite_ref-hi|ho_1-0" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref name=\"hi|ho\">ha&lt;/ref>"}},"i":0}}]}'><a href="./Main_Page#cite_note-hi|ho-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p>
+<p><sup about="#mwt2" class="mw-ref" id="cite_ref-hi|ho_1-0" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref name=\"hi|ho\">ha&lt;/ref>"}},"i":0}}]}'><a href="./Parser_test#cite_note-hi|ho-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-hi|ho-1" id="cite_note-hi|ho-1"><a href="./Main_Page#cite_ref-hi|ho_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-hi|ho-1" class="mw-reference-text">ha</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-hi|ho-1" id="cite_note-hi|ho-1"><a href="./Parser_test#cite_ref-hi|ho_1-0" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-hi|ho-1" class="mw-reference-text">ha</span></li></ol>
 !! end
 
 ## We don't support roundtripping of these attributes in Parsoid.
@@ -7100,9 +7109,9 @@ T107652: <ref>s in templates that also generate table cell attributes should be
 <references />
 !! html/parsoid
 <table>
-<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<sup class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></s></td></tr>
+<tbody><tr><td style="background:#f9f9f9;" typeof="mw:Transclusion" about="#mwt1" data-mw='{"parts":["|",{"template":{"target":{"wt":"table_attribs_7","href":"./Template:Table_attribs_7"},"params":{},"i":0}}]}'>Foo<sup class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></s></td></tr>
 </tbody></table>
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
 !! end
 
 !! test
@@ -8044,6 +8053,8 @@ Link containing % as a double hex sequence interpreted to hex sequence
 ## Example for such a section: == < ==
 !! test
 Link containing "#<" and "#>" % as a hex sequences- these are valid section anchors
+!! options
+title=[[Main Page]]
 !! config
 wgFragmentMode=[ 'html5', 'legacy' ]
 !! wikitext
@@ -8822,6 +8833,8 @@ Interwiki link with fragment (T4130)
 
 !! test
 Link scenarios with escaped fragments
+!! options
+title=[[Main Page]]
 !! config
 wgFragmentMode=[ 'html5', 'legacy' ]
 !! wikitext
@@ -9648,17 +9661,14 @@ Handling html with a div self-closing tag
 <div title=bar />
 <div title=bar/>
 <div title=bar/ >
-!! html/php
-<p>&lt;div title /&gt;
-&lt;div title/&gt;
-</p>
-<div>
-<p>&lt;div title=bar /&gt;
-&lt;div title=bar/&gt;
-</p>
-<div title="bar/"></div>
-</div>
-
+!! html/php+tidy
+<div title=""></div>
+<div title=""></div>
+<div title="">
+<div title="bar"></div>
+<div title="bar"></div>
+<div title="bar/">
+</div></div>
 !! html/parsoid
 <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
 <div title="" data-parsoid='{"stx":"html","selfClose":true}'></div>
@@ -9699,10 +9709,10 @@ Handling html with a br self-closing tag
 <br title=bar />
 <br title=bar/>
 <br title=bar/ >
-!! html/php
+!! html/php+tidy
 <p><br title="" />
 <br title="" />
-<br />
+<br title="" />
 <br title="bar" />
 <br title="bar" />
 <br title="bar/" />
@@ -9717,6 +9727,18 @@ Handling html with a br self-closing tag
 </p>
 !! end
 
+!! test
+Quoted attributes without spaces
+!! options
+parsoid=wt2html
+!! wikitext
+<div class="foo"style="color:red">red</div>
+!! html/php+tidy
+<div class="foo" style="color:red">red</div>
+!! html/parsoid
+<div class="foo" style="color:red">red</div>
+!! end
+
 !! test
 Horizontal ruler (should it add that extra space?)
 !! wikitext
@@ -11024,7 +11046,7 @@ wgRestrictDisplayTitle=false
 <i>Parser test</i>
 
 !! html/parsoid
-<meta property="mw:PageProp/displaytitle" content="Main Page" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"DISPLAYTITLE:&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Main Page&lt;/span>&lt;/i>"}]]}'/>
+<meta property="mw:PageProp/displaytitle" content="Parser test" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"src":"{{DISPLAYTITLE:&#39;&#39;{{PAGENAME}}&#39;&#39;}}"}' data-mw='{"attribs":[[{"txt":"content"},{"html":"DISPLAYTITLE:&lt;i data-parsoid=&#39;{\"dsr\":[15,31,2,2]}&#39;>&lt;span about=\"#mwt1\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[17,29,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"PAGENAME\",\"function\":\"pagename\"},\"params\":{},\"i\":0}}]}&#39;>Parser test&lt;/span>&lt;/i>"}]]}'/>
 !! end
 
 # NOTE: mw:ExpandedAttrs is not the best typeof here. mw:Transclusion is better.
@@ -12725,7 +12747,7 @@ array (
 <li><span typeof="mw:Nowiki">foo-{bar}bat</span></li>
 <li><span typeof="mw:Transclusion mw:Nowiki" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;nowiki>foo-{bar}bat&lt;/nowiki>"}},"i":0}}]}'>foo-{bar}bat</span></li>
 <li><pre typeof="mw:Extension/pre" data-mw='{"name":"pre","attrs":{},"body":{"extsrc":"foo-{bar}bat"}}'>foo-{bar}bat</pre></li>
-<li><pre typeof="mw:Transclusion mw:Extension/pre" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre>foo-{bar}bat&lt;/pre>"}},"i":0}}]}'>foo-{bar}bat</pre></li>
+<li><pre typeof="mw:Extension/pre mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;pre>foo-{bar}bat&lt;/pre>"}},"i":0}}]}'>foo-{bar}bat</pre></li>
 </ul>
 <pre typeof="mw:Extension/tag" data-mw='{"name":"tag","attrs":{},"body":{"extsrc":"foo-{bar}bat"}}'></pre> <pre typeof="mw:Extension/tag mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;tag>foo-{bar}bat&lt;/tag>"}},"i":0}}]}'></pre>
 !! end
@@ -13647,11 +13669,11 @@ Templates: Wiki Tables: 7. Fosterable <ref>s should get fostered
 
 <references />
 !! html/parsoid
-<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><sup about="#mwt3" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p><table about="#mwt2">
+<p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"PartialTable","href":"./Template:PartialTable"},"params":{},"i":0}},"&lt;ref>foo&lt;/ref>\n|}"]}'><sup about="#mwt3" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></p><table about="#mwt2">
 <tbody>
 </tbody></table>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt5" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 !! end
 
 !! test
@@ -13827,6 +13849,7 @@ Parser Functions: 2. Nested use (only outermost should be marked up)
 !! test
 Template nested in extension tag in template
 !! options
+title=[[Main Page]]
 language=zh
 !! wikitext
 {{echo|hi<ref>[[ho|{{echo|hi}}]]</ref>}}
@@ -13834,10 +13857,10 @@ language=zh
 {{echo|hi<ref>-{ho|{{echo|hi}}}-</ref>}}
 <references />
 !! html/parsoid
-<p><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[[ho|{{echo|hi}}]]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Wikipedia:首页#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup>
-<span about="#mwt8" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[http://test.com?q={{echo|ho}}]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt8" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-2"}}'><a href="./Wikipedia:首页#cite_note-2" style="counter-reset: mw-Ref 2;"><span class="mw-reflink-text">[2]</span></a></sup>
-<span about="#mwt13" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>-{ho|{{echo|hi}}}-&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt13" class="mw-ref" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-3"}}'><a href="./Wikipedia:首页#cite_note-3" style="counter-reset: mw-Ref 3;"><span class="mw-reflink-text">[3]</span></a></sup></p>
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt17" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Wikipedia:首页#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><a rel="mw:WikiLink" href="./Ho" title="Ho">hi</a></span></li><li about="#cite_note-2" id="cite_note-2"><a href="./Wikipedia:首页#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"><a rel="mw:ExtLink" class="external autonumber" href="http://test.com?q=ho"></a></span></li><li about="#cite_note-3" id="cite_note-3"><a href="./Wikipedia:首页#cite_ref-3" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-3" class="mw-reference-text"><span typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["ho"],"t":"hi"}}'></span></span></li></ol>
+<p><span about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[[ho|{{echo|hi}}]]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt2" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-1"}}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup>
+<span about="#mwt8" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>[http://test.com?q={{echo|ho}}]&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt8" class="mw-ref" id="cite_ref-2" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-2"}}'><a href="./Main_Page#cite_note-2" style="counter-reset: mw-Ref 2;"><span class="mw-reflink-text">[2]</span></a></sup>
+<span about="#mwt13" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"hi&lt;ref>-{ho|{{echo|hi}}}-&lt;/ref>"}},"i":0}}]}'>hi</span><sup about="#mwt13" class="mw-ref" id="cite_ref-3" rel="dc:references" typeof="mw:Extension/ref" data-mw='{"name":"ref","attrs":{},"body":{"id":"mw-reference-text-cite_note-3"}}'><a href="./Main_Page#cite_note-3" style="counter-reset: mw-Ref 3;"><span class="mw-reflink-text">[3]</span></a></sup></p>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt17" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text"><a rel="mw:WikiLink" href="./Ho" title="Ho">hi</a></span></li><li about="#cite_note-2" id="cite_note-2"><a href="./Main_Page#cite_ref-2" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-2" class="mw-reference-text"><a rel="mw:ExtLink" class="external autonumber" href="http://test.com?q=ho"></a></span></li><li about="#cite_note-3" id="cite_note-3"><a href="./Main_Page#cite_ref-3" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-3" class="mw-reference-text"><span typeof="mw:LanguageVariant" data-mw-variant='{"filter":{"l":["ho"],"t":"hi"}}'></span></span></li></ol>
 !! end
 
 ###
@@ -15471,6 +15494,37 @@ File:Foobar.jpg|link=Foo<nowiki>''s_bar''</nowiki>s|caption
 </ul>
 !! end
 
+!! test
+HTML entity prefix in link markup (T209236)
+!! wikitext
+[[File:Foobar.jpg|link=https://example.com?foo&params=bar]]
+
+<!-- consistency with gallery extension -->
+<gallery>
+File:Foobar.jpg|link=https://example.com?foo&params=bar
+</gallery>
+!! html/php+tidy
+<p><a href="https://example.com?foo&amp;params=bar" rel="nofollow"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p>
+<ul class="gallery mw-gallery-traditional">
+               <li class="gallerybox" style="width: 155px"><div style="width: 155px">
+                       <div class="thumb" style="width: 150px;"><div style="margin:68px auto;"><a href="https://example.com?foo&amp;params=bar"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+                       </div>
+               </div></li>
+</ul>
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941"/></a></figure-inline></p>
+
+<!-- consistency with gallery extension -->
+<ul class="gallery mw-gallery-traditional" typeof="mw:Extension/gallery" data-mw='{"name":"gallery","attrs":{},"body":{"extsrc":"\nFile:Foobar.jpg|link=https://example.com?foo&amp;params=bar\n"}}'>
+<li class="gallerybox">
+<div class="thumb"><figure-inline typeof="mw:Image"><a href="https://example.com?foo&amp;params=bar"><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="14" width="120"/></a></figure-inline></div>
+<div class="gallerytext"></div>
+</li>
+</ul>
+!! end
+
 !! test
 Image with table with attributes in caption
 !! options
@@ -16418,9 +16472,9 @@ T93580: 1. Templated <ref> inside block images
 
 <references />
 !! html/parsoid
-<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption with templated ref: {{echo|&lt;ref>foo&lt;/ref>}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption with templated ref: <sup about="#mwt5" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo&lt;/ref>"}},"i":0}}]}'><a href="./Main_Page#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></figcaption></figure>
+<figure class="mw-default-size" typeof="mw:Image/Thumb" data-parsoid='{"optList":[{"ck":"thumbnail","ak":"thumb"},{"ck":"caption","ak":"Caption with templated ref: {{echo|&lt;ref>foo&lt;/ref>}}"}]}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="25" width="220" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"25","width":"220"},"sa":{"resource":"File:Foobar.jpg"}}'/></a><figcaption>Caption with templated ref: <sup about="#mwt5" class="mw-ref" id="cite_ref-1" rel="dc:references" typeof="mw:Transclusion  mw:Extension/ref" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"&lt;ref>foo&lt;/ref>"}},"i":0}}]}'><a href="./Parser_test#cite_note-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></sup></figcaption></figure>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text" data-parsoid="{}">foo</span></li></ol>
 !! end
 
 !! test
@@ -16430,9 +16484,9 @@ T93580: 2. <ref> inside inline images
 
 <references />
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: &lt;ref>foo&lt;/ref>"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,78,5,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"attrs\":{},\"body\":{\"id\":\"mw-reference-text-cite_note-1\"}}&#39;>&lt;a href=\"./Main_Page#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: &lt;ref>foo&lt;/ref>"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,78,5,6]}&#39; data-mw=&#39;{\"name\":\"ref\",\"attrs\":{},\"body\":{\"id\":\"mw-reference-text-cite_note-1\"}}&#39;>&lt;a href=\"./Parser_test#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt4" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 !! end
 
 !! test
@@ -16442,9 +16496,9 @@ T93580: 3. Templated <ref> inside inline images
 
 <references />
 !! html/parsoid
-<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: {{echo|&lt;ref>{{echo|foo}}&lt;/ref>}}"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Transclusion  mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,96,null,null],\"pi\":[[{\"k\":\"1\"}]]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;lt;ref>{{echo|foo}}&amp;lt;/ref>\"}},\"i\":0}}]}&#39;>&lt;a href=\"./Main_Page#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"caption","ak":"Undisplayed caption in inline image with ref: {{echo|&lt;ref>{{echo|foo}}&lt;/ref>}}"}]}' data-mw='{"caption":"Undisplayed caption in inline image with ref: &lt;sup about=\"#mwt2\" class=\"mw-ref\" id=\"cite_ref-1\" rel=\"dc:references\" typeof=\"mw:Transclusion  mw:Extension/ref\" data-parsoid=&#39;{\"dsr\":[64,96,null,null],\"pi\":[[{\"k\":\"1\"}]]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"echo\",\"href\":\"./Template:Echo\"},\"params\":{\"1\":{\"wt\":\"&amp;lt;ref>{{echo|foo}}&amp;lt;/ref>\"}},\"i\":0}}]}&#39;>&lt;a href=\"./Parser_test#cite_note-1\" style=\"counter-reset: mw-Ref 1;\" data-parsoid=\"{}\">&lt;span class=\"mw-reflink-text\" data-parsoid=\"{}\">[1]&lt;/span>&lt;/a>&lt;/sup>"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{"href":"File:Foobar.jpg"}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 
-<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Main_Page#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
+<ol class="mw-references references" typeof="mw:Extension/references" about="#mwt6" data-mw='{"name":"references","attrs":{}}'><li about="#cite_note-1" id="cite_note-1"><a href="./Parser_test#cite_ref-1" rel="mw:referencedBy"><span class="mw-linkback-text">↑ </span></a> <span id="mw-reference-text-cite_note-1" class="mw-reference-text">foo</span></li></ol>
 !! end
 
 ###
@@ -17779,12 +17833,12 @@ section 6
 <h2 id="Underscore-Entity_between_Text">Underscore-Entity<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>between<span typeof="mw:Entity" data-parsoid='{"src":"&amp;#95;","srcContent":"_"}'>_</span>Text</h2>
 <p>section 6</p>
 
-<p><a rel="mw:WikiLink" href="./Main_Page#Space_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Space_between_Text"},"sa":{"href":"#Space between Text"}}'>#Space between Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Space-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Space-Entity_between_Text"},"sa":{"href":"#Space-Entity&amp;#32;between&amp;#32;Text"}}'>#Space-Entity between Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Plus+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Plus+between+Text"},"sa":{"href":"#Plus+between+Text"}}'>#Plus+between+Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Plus-Entity+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Plus-Entity+between+Text"},"sa":{"href":"#Plus-Entity&amp;#43;between&amp;#43;Text"}}'>#Plus-Entity+between+Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Underscore_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Underscore_between_Text"},"sa":{"href":"#Underscore_between_Text"}}'>#Underscore_between_Text</a>
-<a rel="mw:WikiLink" href="./Main_Page#Underscore-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Underscore-Entity_between_Text"},"sa":{"href":"#Underscore-Entity&amp;#95;between&amp;#95;Text"}}'>#Underscore-Entity_between_Text</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#Space_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Space_between_Text"},"sa":{"href":"#Space between Text"}}'>#Space between Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Space-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Space-Entity_between_Text"},"sa":{"href":"#Space-Entity&amp;#32;between&amp;#32;Text"}}'>#Space-Entity between Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Plus+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Plus+between+Text"},"sa":{"href":"#Plus+between+Text"}}'>#Plus+between+Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Plus-Entity+between+Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Plus-Entity+between+Text"},"sa":{"href":"#Plus-Entity&amp;#43;between&amp;#43;Text"}}'>#Plus-Entity+between+Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Underscore_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Underscore_between_Text"},"sa":{"href":"#Underscore_between_Text"}}'>#Underscore_between_Text</a>
+<a rel="mw:WikiLink" href="./Parser_test#Underscore-Entity_between_Text" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Underscore-Entity_between_Text"},"sa":{"href":"#Underscore-Entity&amp;#95;between&amp;#95;Text"}}'>#Underscore-Entity_between_Text</a></p>
 !! end
 
 # Parsoid html2wt disabled because it adds padding spaces around =
@@ -18177,8 +18231,7 @@ HTML tag with leading space is parsed as text
 </p>
 !! end
 
-## Don't expect Parsoid and PHP to match, since PHP isn't exactly following
-## the HTML5 parsing spec.
+## FIXME: The untrimmed attribute in Parsoid is T205737
 !! test
 Element with broken attribute syntax
 !! options
@@ -18187,7 +18240,7 @@ parsoid=wt2html
 <div style=" style="123">hi</div>
 <div =>ho</div>
 !! html/php
-<div style="123">hi</div>
+<div style="style=">hi</div>
 <div>ho</div>
 
 !! html/parsoid
@@ -18991,7 +19044,7 @@ Tags which are hidden from tidiers cannot pass through the Sanitizer
 !! end
 
 ###
-### Parser hooks (see tests/parser/parserTestsParserHook.php for the <tag> extension)
+### Parser hooks (see tests/parser/ParserTestParserHook.php for the <tag> extension)
 ###
 
 !! test
@@ -19261,7 +19314,7 @@ array (
 !! end
 
 ###
-### (see tests/parser/parserTestsParserHook.php for the <statictag> extension)
+### (see tests/parser/ParserTestParserHook.php for the <statictag> extension)
 ###
 
 !! test
@@ -19275,8 +19328,8 @@ Parser hook: static parser hook not inside a comment
 hello, world
 </p>
 !! html/parsoid
-<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{},"body":{"extsrc":"hello, world"}}' data-parsoid='{}' about="#mwt2"></span></p>
-<p typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{"action":"flush"}}' data-parsoid='{}' about="#mwt4">hello, world</p>
+<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{},"body":{"extsrc":"hello, world"}}' about="#mwt2"></span></p>
+<p><span typeof="mw:Extension/statictag" data-mw='{"name":"statictag","attrs":{"action":"flush"}}' about="#mwt4">hello, world</span></p>
 !! end
 
 !! test
@@ -19289,7 +19342,7 @@ Parser hook: static parser hook inside a comment
 </p>
 !! html/parsoid
 <!-- <statictag&#x3E;hello, world</statictag&#x3E; -->
-<p typeof='mw:Extension/statictag' data-mw='{"name":"statictag","attrs":{"action":"flush"}}' data-parsoid='{}' about='#mwt2'></p>
+<p><span typeof='mw:Extension/statictag' data-mw='{"name":"statictag","attrs":{"action":"flush"}}' data-parsoid='{}' about='#mwt2'></span></p>
 !! end
 
 # Nested template calls; this case was broken by Parser.php rev 1.506,
@@ -19364,6 +19417,8 @@ Table not started</td></tr></table>
 
 !! test
 Sanitizer: Escaping of spaces, multibyte characters, colons & other stuff in id=""
+!! options
+title=[[Main Page]]
 !! config
 wgFragmentMode=[ 'html5', 'legacy' ]
 !! wikitext
@@ -20055,8 +20110,8 @@ parsoid=wt2html
 <pre dir="&#10;"></pre>
 
 !! html/parsoid
-<pre typeof="mw:Extension/pre" about="#mwt2" dir="
-" data-mw='{"name":"pre","attrs":{"dir":"\n"},"body":{"extsrc":""}}'></pre>
+<pre dir="
+" typeof="mw:Extension/pre" about="#mwt2"data-mw='{"name":"pre","attrs":{"dir":"\n"},"body":{"extsrc":""}}'></pre>
 !! end
 
 !! test
@@ -20082,7 +20137,7 @@ Templates in extension attributes are not expanded
 <pre dir="{{echo|ltr}}"></pre>
 
 !! html/parsoid
-<pre typeof="mw:Extension/pre" about="#mwt2" dir="{{echo|ltr}}" data-mw='{"name":"pre","attrs":{"dir":"{{echo|ltr}}"},"body":{"extsrc":""}}'></pre>
+<pre dir="{{echo|ltr}}" typeof="mw:Extension/pre" about="#mwt2" data-mw='{"name":"pre","attrs":{"dir":"{{echo|ltr}}"},"body":{"extsrc":""}}'></pre>
 !! end
 
 !! test
@@ -21519,7 +21574,6 @@ image:foobar.jpg|link=Main Page#section|caption
 </ul>
 !! end
 
-## Whoops, Parsoid shouldn't be parsing templates in the attribute caption!
 !! test
 Gallery with template inside caption
 !! options
@@ -21532,7 +21586,7 @@ File:Foobar.jpg|{{echo|ho}}
 </gallery>
 !! html/php
 <ul class="gallery mw-gallery-traditional">
-       <li class='gallerycaption'>{{echo|hi}}</li>
+       <li class='gallerycaption'>hi</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/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
                        <div class="gallerytext">
@@ -21549,6 +21603,30 @@ File:Foobar.jpg|{{echo|ho}}
 </ul>
 !! end
 
+!! test
+Gallery with wikitext inside gallery caption
+!! wikitext
+<gallery caption="# List item
+
+Text '''bold''' [[link]] {{ns:-1}}
+
+[[File:Foobar.jpg|thumb|File in gallery caption]]">
+File:Foobar.jpg|Image caption
+</gallery>
+!! html/php
+<ul class="gallery mw-gallery-traditional">
+       <li class='gallerycaption'># List item Text <b>bold</b> <a href="/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> Special <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"></a></div>File in gallery caption</div></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/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/240px-Foobar.jpg 2x" /></a></div></div>
+                       <div class="gallerytext">
+<p>Image caption
+</p>
+                       </div>
+               </div></li>
+</ul>
+
+!! end
+
 !! test
 Gallery with wikitext inside caption
 !! options
@@ -22931,6 +23009,19 @@ language=zh variant=zh-tw
 <p><span typeof="mw:LanguageVariant" data-parsoid='{"tSp":[6]}' data-mw-variant='{"twoway":[{"l":"zh","t":"China"},{"l":"zh-tw","t":"Taiwan"}]}'></span>, not China</p>
 !! end
 
+!! test
+Explicit definition of language variant alternatives (BCP 47 codes)
+!! options
+language=zh variant=zh-tw
+!! wikitext
+-{zh:China;zh-Hant-TW:Taiwan}-, not China
+!! html/php
+<p>Taiwan, not China
+</p>
+!! html/parsoid
+<p><span typeof="mw:LanguageVariant" data-parsoid='{"tSp":[6]}' data-mw-variant='{"twoway":[{"l":"zh","t":"China"},{"l":"zh-Hant-TW","t":"Taiwan"}]}'></span>, not China</p>
+!! end
+
 !! test
 Filter syntax for language variants
 !! options
@@ -24422,7 +24513,7 @@ comment title=[[Main Page]]
 !! wikitext
 /* External links */ removed bogus entries
 !! html/php
-<a href="/wiki/Main_Page#External_links" title="Main Page">→External links</a>‎<span dir="auto"><span class="autocomment">: </span> removed bogus entries</span>
+<span dir="auto"><span class="autocomment"><a href="/wiki/Main_Page#External_links" title="Main Page">→‎External links</a>: </span> removed bogus entries</span>
 !!end
 
 !! test
@@ -24432,7 +24523,7 @@ comment title=[[Main Page]]
 !! wikitext
 pre-comment text /* External links */ removed bogus entries
 !! html/php
-pre-comment text <a href="/wiki/Main_Page#External_links" title="Main Page">→External links</a>‎<span dir="auto"><span class="autocomment">: </span> removed bogus entries</span>
+pre-comment text <span dir="auto"><span class="autocomment"><a href="/wiki/Main_Page#External_links" title="Main Page">→‎External links</a>: </span> removed bogus entries</span>
 !!end
 
 !! test
@@ -24442,9 +24533,29 @@ comment local title=[[Main Page]]
 !! wikitext
 /* External links */ removed bogus entries
 !! html/php
-<a href="#External_links">→External links</a>‎<span dir="auto"><span class="autocomment">: </span> removed bogus entries</span>
+<span dir="auto"><span class="autocomment"><a href="#External_links">→‎External links</a>: </span> removed bogus entries</span>
 !!end
 
+!! test
+Edit comment with section link that has a link in it
+!! options
+comment local title=[[Main Page]]
+!! wikitext
+/* [[A link]] */
+!! html/php
+<span dir="auto"><span class="autocomment"><a href="#A_link">→‎&#91;[A link]]</a></span></span>
+!! end
+
+!! test
+Edit comment with section link that has a template in it
+!! options
+comment local title=[[Main Page]]
+!! wikitext
+/* {{foobar|param}} */
+!! html/php
+<span dir="auto"><span class="autocomment"><a href="#.7B.7Bfoobar.7Cparam.7D.7D">→‎{{foobar|param}}</a></span></span>
+!! end
+
 !! test
 Edit comment with subpage link (T16080)
 !! options
@@ -24553,7 +24664,7 @@ title=[[Main Page]]
 !! wikitext
 /* __hello__world__ */
 !! html/php
-<a href="/wiki/Main_Page#hello_world" title="Main Page">→__hello__world__</a>‎
+<span dir="auto"><span class="autocomment"><a href="/wiki/Main_Page#hello_world" title="Main Page">→‎__hello__world__</a></span></span>
 !! end
 
 !! test
@@ -26801,6 +26912,33 @@ parsoid=html2wt
 
 !! end
 
+!! test
+Tables: 4e. Escape }
+!! options
+parsoid=html2wt
+!! html/parsoid
+<table>
+<tr><td>}</td></tr>
+<tr><td>x</td><td data-parsoid='{"stx":"row"}'>}</td></tr></table>
+</table>
+!! wikitext
+{|
+|<nowiki>}</nowiki>
+|-
+|x||}
+|}
+!! html/php
+<table>
+<tr>
+<td>}
+</td></tr>
+<tr>
+<td>x</td>
+<td>}
+</td></tr></table>
+
+!! end
+
 !! test
 Tables: 5. Empty table cells should get whitespace to avoid need for nowikis
 !! options
@@ -28881,6 +29019,27 @@ Image: Invalid title as link
 <p><figure-inline class="mw-default-size" typeof="mw:Image" data-parsoid='{"optList":[{"ck":"link","ak":"link=&lt;"}]}' data-mw='{"caption":"link=&amp;lt;"}'><a href="./File:Foobar.jpg" data-parsoid='{"a":{"href":"./File:Foobar.jpg"},"sa":{}}'><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
 !! end
 
+!! test
+Various link types in alt and link options
+!! wikitext
+[[File:Foobar.jpg|link=[[Main Page]]|alt=[[Main Page]]|caption]]
+
+[[File:Foobar.jpg|link=[[Media:Thumb.png]]|alt=[[Media:Thumb.png]]|caption]]
+
+[[File:Foobar.jpg|link=[[wikipedia:Foo]]|alt=[[wikipedia:Foo]]|caption]]
+!! html/php+tidy
+<p><a href="/wiki/Main_Page" title="caption"><img alt="Main Page" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p><p><a href="/wiki/Media:Thumb.png" title="caption"><img alt="Media:Thumb.png" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p><p><a href="http://en.wikipedia.org/wiki/Foo" title="caption"><img alt="wikipedia:Foo" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>
+</p>
+!! html/parsoid
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Main_Page" data-parsoid='{"a":{"href":"./Main_Page"},"sa":{"href":"link=[[Main Page]]"}}'><img alt="Main Page" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Main Page","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Main Page]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="./Media:Thumb.png" data-parsoid='{"a":{"href":"./Media:Thumb.png"},"sa":{"href":"link=[[Media:Thumb.png]]"}}'><img alt="Media:Thumb.png" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"Media:Thumb.png","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[Media:Thumb.png]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+
+<p><figure-inline class="mw-default-size" typeof="mw:Image" data-mw='{"caption":"caption"}'><a href="http://en.wikipedia.org/wiki/Foo" data-parsoid='{"a":{"href":"http://en.wikipedia.org/wiki/Foo"},"sa":{"href":"link=[[wikipedia:Foo]]"}}'><img alt="wikipedia:Foo" resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" data-file-width="1941" data-file-height="220" data-file-type="bitmap" height="220" width="1941" data-parsoid='{"a":{"alt":"wikipedia:Foo","resource":"./File:Foobar.jpg","height":"220","width":"1941"},"sa":{"alt":"alt=[[wikipedia:Foo]]","resource":"File:Foobar.jpg"}}'/></a></figure-inline></p>
+!! end
+
 !! test
 Lists: Serialize correctly even when list content is wrapped in p-tags (like VE does)
 !! options
@@ -30693,6 +30852,7 @@ parsoid={
 <tr><td>a</td></tr>
 <tr><td>-</td></tr>
 <tr><td>+</td></tr>
+<tr><td>}</td></tr>
 </table>
 !! wikitext
 {|
@@ -30701,6 +30861,8 @@ parsoid={
 |<nowiki>-</nowiki>
 |-
 |<nowiki>+</nowiki>
+|-
+|<nowiki>}</nowiki>
 |}
 !! end
 
@@ -30716,6 +30878,7 @@ parsoid={
 <tr><td>a</td></tr>
 <tr><td>-</td></tr>
 <tr><td>+</td></tr>
+<tr><td>}</td></tr>
 </table>
 !! wikitext
 {|
@@ -30724,6 +30887,8 @@ parsoid={
 | -
 |-
 | +
+|-
+| }
 |}
 !! end
 
@@ -30891,6 +31056,170 @@ parsoid={
 <font>foo</font>
 !! end
 
+!! test
+Ignore empty <p></p> when scrubWikitext is false
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": false
+}
+!! html/parsoid
+<div>1</div>
+<p>a</p><p></p><p>b</p>
+<div>2</div>
+<p>a</p>
+<p></p>
+<p>b</p>
+<div>3</div>
+<p>a</p>
+<p></p>
+<p></p>
+<p></p>
+<p></p>
+<p>b</p>
+!! wikitext
+<div>1</div>
+a
+
+b
+<div>2</div>
+a
+
+b
+<div>3</div>
+a
+
+b
+!! html/php+tidy
+<div>1</div>
+<p>a
+</p><p>b
+</p>
+<div>2</div>
+<p>a
+</p><p>b
+</p>
+<div>3</div>
+<p>a
+</p><p>b
+</p>
+!! end
+
+!! test
+Normalize empty paragraphs to HTML form that html2wt expects
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<div>1</div>
+<p>a</p><p></p><p>b</p>
+<div>2</div>
+<p>a</p>
+<p></p>
+<p>b</p>
+<div>3</div>
+<p>a</p>
+<p></p>
+<p></p>
+<p></p>
+<p></p>
+<p>b</p>
+<div>4</div>
+<p>a</p>
+<p></p>
+<div>foo</div>
+!! wikitext
+<div>1</div>
+a
+
+
+b
+<div>2</div>
+a
+
+
+b
+<div>3</div>
+a
+
+
+
+
+
+b
+<div>4</div>
+a
+
+<br />
+<div>foo</div>
+!! html/php+tidy
+<div>1</div>
+<p>a
+</p><p><br />
+b
+</p>
+<div>2</div>
+<p>a
+</p><p><br />
+b
+</p>
+<div>3</div>
+<p>a
+</p><p><br />
+</p><p><br />
+</p><p>b
+</p>
+<div>4</div>
+<p>a
+</p><p><br />
+</p>
+<div>foo</div>
+!! end
+
+!! test
+Empty paragraphs (marked with mw-empty-elt) found in source should not be normalized away
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<table>
+<tbody>
+<tr>
+<td><div>foo
+</div>
+<p class="mw-empty-elt"></p>
+</td>
+</tr>
+</tbody>
+<caption></caption>
+</table>
+!! wikitext
+{|
+|<div>foo
+</div>
+|+
+|}
+!! end
+
+!! test
+Templated content should be skipped over by normalization
+!! options
+parsoid={
+  "modes": ["html2wt"],
+  "scrubWikitext": true
+}
+!! html/parsoid
+<p about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"SomeTemplate1","href":"./Template:SomeTemplate1"},"params":{"1":{"wt":"boo"}},"i":0}}]}'>foobar</p><p about="#mwt2" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"SomeTemplate2","href":"./Template:SomeTemplate2"},"params":{"1":{"wt":"booboo"}},"i":0}}]}'>foobar</p><span about="#mwt2">
+</span><p about="#mwt2"></p><span about="#mwt2">
+</span>
+!! wikitext
+{{SomeTemplate1|boo}}{{SomeTemplate2|booboo}}
+!! end
+
 !! test
 Escape nowiki DOM elements
 !! options
@@ -31350,7 +31679,7 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 </p>
 !! html/parsoid
 <h2 id="A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"><span id="A.26B.26C.26amp.3BD.26amp.3Bamp.3BE" typeof="mw:FallbackId" data-parsoid="{}"></span>A&amp;B<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>C<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;D<span typeof="mw:Entity" data-parsoid='{"src":"&amp;amp;","srcContent":"&amp;"}'>&amp;</span>amp;amp;E</h2>
-<p><a rel="mw:WikiLink" href="./Main_Page#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"},"sa":{"href":"#A&amp;B&amp;amp;C&amp;amp;amp;D&amp;amp;amp;amp;E"}}'>#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E"},"sa":{"href":"#A&amp;B&amp;amp;C&amp;amp;amp;D&amp;amp;amp;amp;E"}}'>#A&amp;B&amp;C&amp;amp;D&amp;amp;amp;E</a></p>
 !! end
 
 !! test
@@ -31463,12 +31792,12 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 <h2 id="тест"><span id=".D1.82.D0.B5.D1.81.D1.82" typeof="mw:FallbackId"></span>тест</h2>
 
 <h2 id="Hey_&lt;_#_&quot;_>_%_:_'"><span id="Hey_.3C_.23_.22_.3E_.25_:_.27" typeof="mw:FallbackId"></span>Hey &lt; # " > %<span typeof="mw:DisplaySpace mw:Placeholder" data-parsoid='{"src":" ","isDisplayHack":true}'> </span>: '</h2>
-<p><a rel="mw:WikiLink" href="./Main_Page#Foo_bar">#Foo bar</a> <a rel="mw:WikiLink" href="./Main_Page#foo_Bar">#foo Bar</a> <a rel="mw:WikiLink" href="./Main_Page#Тест">#Тест</a> <a rel="mw:WikiLink" href="./Main_Page#тест">#тест</a> <a rel="mw:WikiLink" href="./Main_Page#Hey_&lt;_#_&quot;_>_%_:_'" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Hey_&lt;_#_\"_>_%_:_&#39;"},"sa":{"href":"#Hey &lt; # \" > % : &#39;"}}'>#Hey &lt; # " > % : '</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#Foo_bar">#Foo bar</a> <a rel="mw:WikiLink" href="./Parser_test#foo_Bar">#foo Bar</a> <a rel="mw:WikiLink" href="./Parser_test#Тест">#Тест</a> <a rel="mw:WikiLink" href="./Parser_test#тест">#тест</a> <a rel="mw:WikiLink" href="./Parser_test#Hey_&lt;_#_&quot;_>_%_:_'" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Hey_&lt;_#_\"_>_%_:_&#39;"},"sa":{"href":"#Hey &lt; # \" > % : &#39;"}}'>#Hey &lt; # " > % : '</a></p>
 
 <p><span about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"anchorencode:💩","function":"anchorencode"},"params":{},"i":0}}]}'>💩</span> <span id="💩" about="#mwt3" typeof="mw:ExpandedAttrs" data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span about=\"#mwt2\" typeof=\"mw:Transclusion\" data-parsoid=&#39;{\"pi\":[[]],\"dsr\":[178,197,null,null]}&#39; data-mw=&#39;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:💩\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&#39;>💩&lt;/span>"}]]}'></span></p>
 
 <!-- These two links should produce identical HTML -->
-<p><a rel="mw:WikiLink" href="./Main_Page#啤酒">#啤酒</a> <a rel="mw:WikiLink" href="./Main_Page#啤酒" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#啤酒"},"sa":{"href":"#%E5%95%A4%E9%85%92"}}'>#啤酒</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#啤酒">#啤酒</a> <a rel="mw:WikiLink" href="./Parser_test#啤酒" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#啤酒"},"sa":{"href":"#%E5%95%A4%E9%85%92"}}'>#啤酒</a></p>
 !! end
 
 # Parsoid doesn't support this mode
@@ -31581,7 +31910,7 @@ wgFragmentMode=[ 'html5', 'legacy' ]
 </p>
 !! html/parsoid
 <h2 id="Foo_bar"> Foo<span typeof="mw:Entity" data-parsoid='{"src":"&amp;nbsp;","srcContent":" "}'> </span>bar </h2>
-<p><a rel="mw:WikiLink" href="./Main_Page#Foo_bar" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#Foo_bar"},"sa":{"href":"#Foo&amp;nbsp;bar"}}'>#Foo bar</a></p>
+<p><a rel="mw:WikiLink" href="./Parser_test#Foo_bar" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#Foo_bar"},"sa":{"href":"#Foo&amp;nbsp;bar"}}'>#Foo bar</a></p>
 !! end
 
 !! test
@@ -31638,7 +31967,7 @@ wgFragmentMode=[ 'html5' ]
 <p><span id="&#91;foo&#93;"></span><a href="#[foo]">#&#91;foo&#93;</a>
 </p>
 !! html/parsoid
-<p><span id="[foo]" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"id":"[foo]"},"sa":{"id":"{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[10,32,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'></span><a typeof="mw:ExpandedAttrs" about="#mwt4" rel="mw:WikiLink" href="./Main_Page#[foo]" data-parsoid='{"stx":"simple","a":{"href":"./Main_Page#[foo]"},"sa":{"href":"#{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"href"},{"html":"#&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[44,66,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt2\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'>#[foo]</a></p>
+<p><span id="[foo]" about="#mwt3" typeof="mw:ExpandedAttrs" data-parsoid='{"stx":"html","a":{"id":"[foo]"},"sa":{"id":"{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"id"},{"html":"&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[10,32,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt1\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt1\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'></span><a typeof="mw:ExpandedAttrs" about="#mwt4" rel="mw:WikiLink" href="./Parser_test#[foo]" data-parsoid='{"stx":"simple","a":{"href":"./Parser_test#[foo]"},"sa":{"href":"#{{anchorencode:[foo]}}"}}' data-mw='{"attribs":[[{"txt":"href"},{"html":"#&lt;span typeof=\"mw:Transclusion mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"srcContent\":\"[\",\"dsr\":[44,66,null,null],\"pi\":[[]]}&apos; data-mw=&apos;{\"parts\":[{\"template\":{\"target\":{\"wt\":\"anchorencode:[foo]\",\"function\":\"anchorencode\"},\"params\":{},\"i\":0}}]}&apos;>[&lt;/span>&lt;span about=\"#mwt2\" data-parsoid=\"{}\">foo&lt;/span>&lt;span typeof=\"mw:Entity\" about=\"#mwt2\" data-parsoid=&apos;{\"src\":\"&amp;amp;#x5D;\",\"srcContent\":\"]\"}&apos;>]&lt;/span>"}]]}'>#[foo]</a></p>
 !! end
 
 ## ------------------------------
index 52a3c91..34e5593 100644 (file)
@@ -152,58 +152,58 @@ class LinkerTest extends MediaWikiLangTestCase {
                        ],
                        // Linker::formatAutocomments
                        [
-                               '<a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>‎',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→‎autocomment</a></span></span>',
                                "/* autocomment */",
                        ],
                        [
-                               '<a href="/wiki/Special:BlankPage#linkie.3F" title="Special:BlankPage">→<a href="/wiki/index.php?title=Linkie%3F&amp;action=edit&amp;redlink=1" class="new" title="Linkie? (page does not exist)">linkie?</a></a>‎',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#linkie.3F" title="Special:BlankPage">→‎&#91;[linkie?]]</a></span></span>',
                                "/* [[linkie?]] */",
                        ],
                        [
-                               '<a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>‎<span dir="auto"><span class="autocomment">: </span> post</span>',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→‎autocomment</a>: </span> post</span>',
                                "/* autocomment */ post",
                        ],
                        [
-                               'pre <a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>‎',
+                               'pre <span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→‎autocomment</a></span></span>',
                                "pre /* autocomment */",
                        ],
                        [
-                               'pre <a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>‎<span dir="auto"><span class="autocomment">: </span> post</span>',
+                               'pre <span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→‎autocomment</a>: </span> post</span>',
                                "pre /* autocomment */ post",
                        ],
                        [
-                               '<a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>‎<span dir="auto"><span class="autocomment">: </span> multiple? <a href="/wiki/Special:BlankPage#autocomment2" title="Special:BlankPage">→autocomment2</a>‎</span>',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→‎autocomment</a>: </span> multiple? <span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment2" title="Special:BlankPage">→‎autocomment2</a></span></span></span>',
                                "/* autocomment */ multiple? /* autocomment2 */",
                        ],
                        [
-                               '<a href="/wiki/Special:BlankPage#autocomment_containing_.2F.2A" title="Special:BlankPage">→autocomment containing /*</a>‎<span dir="auto"><span class="autocomment">: </span> T70361</span>',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment_containing_.2F.2A" title="Special:BlankPage">→‎autocomment containing /*</a>: </span> T70361</span>',
                                "/* autocomment containing /* */ T70361"
                        ],
                        [
-                               '<a href="/wiki/Special:BlankPage#autocomment_containing_.22quotes.22" title="Special:BlankPage">→autocomment containing &quot;quotes&quot;</a>‎',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment_containing_.22quotes.22" title="Special:BlankPage">→‎autocomment containing &quot;quotes&quot;</a></span></span>',
                                "/* autocomment containing \"quotes\" */"
                        ],
                        [
-                               '<a href="/wiki/Special:BlankPage#autocomment_containing_.3Cscript.3Etags.3C.2Fscript.3E" title="Special:BlankPage">→autocomment containing &lt;script&gt;tags&lt;/script&gt;</a>‎',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment_containing_.3Cscript.3Etags.3C.2Fscript.3E" title="Special:BlankPage">→‎autocomment containing &lt;script&gt;tags&lt;/script&gt;</a></span></span>',
                                "/* autocomment containing <script>tags</script> */"
                        ],
                        [
-                               '<a href="#autocomment">→autocomment</a>‎',
+                               '<span dir="auto"><span class="autocomment"><a href="#autocomment">→‎autocomment</a></span></span>',
                                "/* autocomment */",
                                false, true
                        ],
                        [
-                               '<span dir="auto"><span class="autocomment">autocomment</span></span>',
+                               '<span dir="auto"><span class="autocomment">autocomment</span></span>',
                                "/* autocomment */",
                                null
                        ],
                        [
-                               '<a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>‎',
+                               '<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→‎autocomment</a></span></span>',
                                "/* autocomment */",
                                false, false
                        ],
                        [
-                               '<a class="external" rel="nofollow" href="//en.example.org/w/Special:BlankPage#autocomment">→autocomment</a>‎',
+                               '<span dir="auto"><span class="autocomment"><a class="external" rel="nofollow" href="//en.example.org/w/Special:BlankPage#autocomment">→‎autocomment</a></span></span>',
                                "/* autocomment */",
                                false, false, $wikiId
                        ],
diff --git a/tests/phpunit/includes/Revision/FallbackSlotRoleHandlerTest.php b/tests/phpunit/includes/Revision/FallbackSlotRoleHandlerTest.php
new file mode 100644 (file)
index 0000000..aedf292
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+namespace MediaWiki\Tests\Revision;
+
+use MediaWiki\Revision\FallbackSlotRoleHandler;
+use MediaWikiTestCase;
+use Title;
+
+/**
+ * @covers \MediaWiki\Revision\FallbackSlotRoleHandler
+ */
+class FallbackSlotRoleHandlerTest extends MediaWikiTestCase {
+
+       private function makeBlankTitleObject() {
+               /** @var Title $title */
+               $title = $this->getMockBuilder( Title::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               return $title;
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\FallbackSlotRoleHandler::__construct
+        * @covers \MediaWiki\Revision\FallbackSlotRoleHandler::getRole()
+        * @covers \MediaWiki\Revision\FallbackSlotRoleHandler::getNameMessageKey()
+        * @covers \MediaWiki\Revision\FallbackSlotRoleHandler::getDefaultModel()
+        * @covers \MediaWiki\Revision\FallbackSlotRoleHandler::getOutputLayoutHints()
+        */
+       public function testConstruction() {
+               $handler = new FallbackSlotRoleHandler( 'foo' );
+               $this->assertSame( 'foo', $handler->getRole() );
+               $this->assertSame( 'slot-name-foo', $handler->getNameMessageKey() );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertSame( CONTENT_MODEL_TEXT, $handler->getDefaultModel( $title ) );
+
+               $hints = $handler->getOutputLayoutHints();
+               $this->assertArrayHasKey( 'display', $hints );
+               $this->assertArrayHasKey( 'region', $hints );
+               $this->assertArrayHasKey( 'placement', $hints );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\FallbackSlotRoleHandler::isAllowedModel()
+        */
+       public function testIsAllowedModel() {
+               $handler = new FallbackSlotRoleHandler( 'foo', 'FooModel' );
+
+               // For the fallback handler, no models are allowed
+               $title = $this->makeBlankTitleObject();
+               $this->assertFalse( $handler->isAllowedModel( 'FooModel', $title ) );
+               $this->assertFalse( $handler->isAllowedModel( 'QuaxModel', $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleHandler::isAllowedModel()
+        */
+       public function testIsAllowedOn() {
+               $handler = new FallbackSlotRoleHandler( 'foo', 'FooModel' );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertFalse( $handler->isAllowedOn( $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\FallbackSlotRoleHandler::supportsArticleCount()
+        */
+       public function testSupportsArticleCount() {
+               $handler = new FallbackSlotRoleHandler( 'foo', 'FooModel' );
+
+               $this->assertFalse( $handler->supportsArticleCount() );
+       }
+
+}
diff --git a/tests/phpunit/includes/Revision/MainSlotRoleHandlerTest.php b/tests/phpunit/includes/Revision/MainSlotRoleHandlerTest.php
new file mode 100644 (file)
index 0000000..f2f3da8
--- /dev/null
@@ -0,0 +1,79 @@
+<?php
+
+namespace MediaWiki\Tests\Revision;
+
+use MediaWiki\Revision\MainSlotRoleHandler;
+use MediaWikiTestCase;
+use PHPUnit\Framework\MockObject\MockObject;
+use Title;
+
+/**
+ * @covers \MediaWiki\Revision\MainSlotRoleHandler
+ */
+class MainSlotRoleHandlerTest extends MediaWikiTestCase {
+
+       private function makeTitleObject( $ns ) {
+               /** @var Title|MockObject $title */
+               $title = $this->getMockBuilder( Title::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $title->method( 'getNamespace' )
+                       ->willReturn( $ns );
+
+               return $title;
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\MainSlotRoleHandler::__construct
+        * @covers \MediaWiki\Revision\MainSlotRoleHandler::getRole()
+        * @covers \MediaWiki\Revision\MainSlotRoleHandler::getNameMessageKey()
+        * @covers \MediaWiki\Revision\MainSlotRoleHandler::getOutputLayoutHints()
+        */
+       public function testConstruction() {
+               $handler = new MainSlotRoleHandler( [] );
+               $this->assertSame( 'main', $handler->getRole() );
+               $this->assertSame( 'slot-name-main', $handler->getNameMessageKey() );
+
+               $hints = $handler->getOutputLayoutHints();
+               $this->assertArrayHasKey( 'display', $hints );
+               $this->assertArrayHasKey( 'region', $hints );
+               $this->assertArrayHasKey( 'placement', $hints );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\MainSlotRoleHandler::getDefaultModel()
+        */
+       public function testFetDefaultModel() {
+               $handler = new MainSlotRoleHandler( [ 100 => CONTENT_MODEL_TEXT ] );
+
+               // For the main handler, the namespace determins the defualt model
+               $titleMain = $this->makeTitleObject( NS_MAIN );
+               $this->assertSame( CONTENT_MODEL_WIKITEXT, $handler->getDefaultModel( $titleMain ) );
+
+               $title100 = $this->makeTitleObject( 100 );
+               $this->assertSame( CONTENT_MODEL_TEXT, $handler->getDefaultModel( $title100 ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\MainSlotRoleHandler::isAllowedModel()
+        */
+       public function testIsAllowedModel() {
+               $handler = new MainSlotRoleHandler( [] );
+
+               // For the main handler, (nearly) all models are allowed
+               $title = $this->makeTitleObject( NS_MAIN );
+               $this->assertTrue( $handler->isAllowedModel( CONTENT_MODEL_WIKITEXT, $title ) );
+               $this->assertTrue( $handler->isAllowedModel( CONTENT_MODEL_TEXT, $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\MainSlotRoleHandler::supportsArticleCount()
+        */
+       public function testSupportsArticleCount() {
+               $handler = new MainSlotRoleHandler( [] );
+
+               $this->assertTrue( $handler->supportsArticleCount() );
+       }
+
+}
index 08a8fa6..43fccee 100644 (file)
@@ -483,6 +483,23 @@ class RenderedRevisionTest extends MediaWikiTestCase {
                $this->assertContains( 'time:20180101000003!', $html );
        }
 
+       public function testSetRevisionParserOutput() {
+               $title = $this->getMockTitle( 3, 21 );
+               $rev = $this->getMockRevision( RevisionStoreRecord::class, $title );
+
+               $options = ParserOptions::newCanonical( 'canonical' );
+               $rr = new RenderedRevision( $title, $rev, $options, $this->combinerCallback );
+
+               $output = new ParserOutput( 'Kittens' );
+               $rr->setRevisionParserOutput( $output );
+
+               $this->assertSame( $output, $rr->getRevisionParserOutput() );
+               $this->assertSame( 'Kittens', $rr->getRevisionParserOutput()->getText() );
+
+               $this->assertSame( $output, $rr->getSlotParserOutput( SlotRecord::MAIN ) );
+               $this->assertSame( 'Kittens', $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
+       }
+
        public function testNoHtml() {
                /** @var MockObject|Content $mockContent */
                $mockContent = $this->getMockBuilder( WikitextContent::class )
index 469f281..59b5a2c 100644 (file)
@@ -7,9 +7,12 @@ use Content;
 use Language;
 use LogicException;
 use MediaWiki\Revision\MutableRevisionRecord;
+use MediaWiki\Revision\MainSlotRoleHandler;
 use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\Revision\RevisionRenderer;
 use MediaWiki\Revision\SlotRecord;
+use MediaWiki\Revision\SlotRoleRegistry;
+use MediaWiki\Storage\NameTableStore;
 use MediaWikiTestCase;
 use MediaWiki\User\UserIdentityValue;
 use ParserOptions;
@@ -126,7 +129,20 @@ class RevisionRendererTest extends MediaWikiTestCase {
                        ->with( $dbIndex )
                        ->willReturn( $db );
 
-               return new RevisionRenderer( $lb );
+               /** @var NameTableStore|MockObject $slotRoles */
+               $slotRoles = $this->getMockBuilder( NameTableStore::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $slotRoles->method( 'getMap' )
+                       ->willReturn( [] );
+
+               $roleReg = new SlotRoleRegistry( $slotRoles );
+               $roleReg->defineRole( 'main', function () {
+                       return new MainSlotRoleHandler( [] );
+               } );
+               $roleReg->defineRoleWithModel( 'aux', CONTENT_MODEL_WIKITEXT );
+
+               return new RevisionRenderer( $lb, $roleReg );
        }
 
        private function selectFieldCallback( $table, $fields, $cond, $maxRev ) {
@@ -240,6 +256,34 @@ class RevisionRendererTest extends MediaWikiTestCase {
                $this->assertSame( $html, $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
        }
 
+       public function testGetRenderedRevision_known() {
+               $renderer = $this->newRevisionRenderer( 100, true ); // use master
+               $title = $this->getMockTitle( 7, 21 );
+
+               $rev = new MutableRevisionRecord( $title );
+               $rev->setId( 21 ); // current!
+               $rev->setUser( new UserIdentityValue( 9, 'Frank', 0 ) );
+               $rev->setTimestamp( '20180101000003' );
+               $rev->setComment( CommentStoreComment::newUnsavedComment( '' ) );
+
+               $text = "uncached text";
+               $rev->setContent( SlotRecord::MAIN, new WikitextContent( $text ) );
+
+               $output = new ParserOutput( 'cached text' );
+
+               $options = ParserOptions::newCanonical( 'canonical' );
+               $rr = $renderer->getRenderedRevision(
+                       $rev,
+                       $options,
+                       null,
+                       [ 'known-revision-output' => $output ]
+               );
+
+               $this->assertSame( $output, $rr->getRevisionParserOutput() );
+               $this->assertSame( 'cached text', $rr->getRevisionParserOutput()->getText() );
+               $this->assertSame( 'cached text', $rr->getSlotParserOutput( SlotRecord::MAIN )->getText() );
+       }
+
        public function testGetRenderedRevision_old() {
                $renderer = $this->newRevisionRenderer( 100 );
                $title = $this->getMockTitle( 7, 21 );
index 0d6a439..cf5e808 100644 (file)
@@ -12,7 +12,9 @@ use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Revision\IncompleteRevisionException;
 use MediaWiki\Revision\MutableRevisionRecord;
+use MediaWiki\Revision\RevisionArchiveRecord;
 use MediaWiki\Revision\RevisionRecord;
+use MediaWiki\Revision\RevisionSlots;
 use MediaWiki\Revision\RevisionStore;
 use MediaWiki\Revision\SlotRecord;
 use MediaWiki\Storage\BlobStoreFactory;
@@ -78,7 +80,7 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
                $this->setMwGlobals( [
                        'wgMultiContentRevisionSchemaMigrationStage' => $this->getMcrMigrationStage(),
                        'wgContentHandlerUseDB' => $this->getContentHandlerUseDB(),
-                       'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
+                       'wgCommentTableSchemaMigrationStage' => MIGRATION_NEW,
                        'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                ] );
 
@@ -231,6 +233,7 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
                        MediaWikiServices::getInstance()->getCommentStore(),
                        MediaWikiServices::getInstance()->getContentModelStore(),
                        MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleRegistry(),
                        $this->getMcrMigrationStage(),
                        MediaWikiServices::getInstance()->getActorMigration(),
                        $wikiId
@@ -1354,6 +1357,44 @@ abstract class RevisionStoreDbTestBase extends MediaWikiTestCase {
                );
        }
 
+       public function provideNonHistoryRevision() {
+               $title = Title::newFromText( __METHOD__ );
+               $rev = new MutableRevisionRecord( $title );
+               yield [ $rev ];
+
+               $user = new UserIdentityValue( 7, 'Frank', 0 );
+               $comment = CommentStoreComment::newUnsavedComment( 'Test' );
+               $row = (object)[
+                       'ar_id' => 3,
+                       'ar_rev_id' => 34567,
+                       'ar_page_id' => 5,
+                       'ar_deleted' => 0,
+                       'ar_minor_edit' => 0,
+                       'ar_timestamp' => '20180101020202',
+               ];
+               $slots = new RevisionSlots( [] );
+               $rev = new RevisionArchiveRecord( $title, $user, $comment, $row, $slots );
+               yield [ $rev ];
+       }
+
+       /**
+        * @dataProvider provideNonHistoryRevision
+        * @covers \MediaWiki\Revision\RevisionStore::getPreviousRevision
+        */
+       public function testGetPreviousRevision_bad( RevisionRecord $rev ) {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $this->assertNull( $store->getPreviousRevision( $rev ) );
+       }
+
+       /**
+        * @dataProvider provideNonHistoryRevision
+        * @covers \MediaWiki\Revision\RevisionStore::getNextRevision
+        */
+       public function testGetNextRevision_bad( RevisionRecord $rev ) {
+               $store = MediaWikiServices::getInstance()->getRevisionStore();
+               $this->assertNull( $store->getNextRevision( $rev ) );
+       }
+
        /**
         * @covers \MediaWiki\Revision\RevisionStore::getTimestampFromId
         */
index 9904b3b..2e61745 100644 (file)
@@ -7,6 +7,7 @@ use CommentStore;
 use MediaWiki\Logger\Spi as LoggerSpi;
 use MediaWiki\Revision\RevisionStore;
 use MediaWiki\Revision\RevisionStoreFactory;
+use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Storage\BlobStore;
 use MediaWiki\Storage\BlobStoreFactory;
 use MediaWiki\Storage\NameTableStore;
@@ -27,6 +28,7 @@ class RevisionStoreFactoryTest extends MediaWikiTestCase {
                        $this->getMockLoadBalancerFactory(),
                        $this->getMockBlobStoreFactory(),
                        $this->getNameTableStoreFactory(),
+                       $this->getMockSlotRoleRegistry(),
                        $this->getHashWANObjectCache(),
                        $this->getMockCommentStore(),
                        ActorMigration::newMigration(),
@@ -56,6 +58,7 @@ class RevisionStoreFactoryTest extends MediaWikiTestCase {
                $lbFactory = $this->getMockLoadBalancerFactory();
                $blobStoreFactory = $this->getMockBlobStoreFactory();
                $nameTableStoreFactory = $this->getNameTableStoreFactory();
+               $slotRoleRegistry = $this->getMockSlotRoleRegistry();
                $cache = $this->getHashWANObjectCache();
                $commentStore = $this->getMockCommentStore();
                $actorMigration = ActorMigration::newMigration();
@@ -65,6 +68,7 @@ class RevisionStoreFactoryTest extends MediaWikiTestCase {
                        $lbFactory,
                        $blobStoreFactory,
                        $nameTableStoreFactory,
+                       $slotRoleRegistry,
                        $cache,
                        $commentStore,
                        $actorMigration,
@@ -142,6 +146,16 @@ class RevisionStoreFactoryTest extends MediaWikiTestCase {
                return $mock;
        }
 
+       /**
+        * @return \PHPUnit_Framework_MockObject_MockObject|SlotRoleRegistry
+        */
+       private function getMockSlotRoleRegistry() {
+               $mock = $this->getMockBuilder( SlotRoleRegistry::class )
+                       ->disableOriginalConstructor()->getMock();
+
+               return $mock;
+       }
+
        /**
         * @return NameTableStoreFactory
         */
index 2093b41..efc2952 100644 (file)
@@ -9,6 +9,7 @@ use Language;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Revision\RevisionAccessException;
 use MediaWiki\Revision\RevisionStore;
+use MediaWiki\Revision\SlotRoleRegistry;
 use MediaWiki\Revision\SlotRecord;
 use MediaWiki\Storage\SqlBlobStore;
 use MediaWikiTestCase;
@@ -51,6 +52,7 @@ class RevisionStoreTest extends MediaWikiTestCase {
                        MediaWikiServices::getInstance()->getCommentStore(),
                        MediaWikiServices::getInstance()->getContentModelStore(),
                        MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleRegistry(),
                        $wgMultiContentRevisionSchemaMigrationStage,
                        MediaWikiServices::getInstance()->getActorMigration()
                );
@@ -88,6 +90,14 @@ class RevisionStoreTest extends MediaWikiTestCase {
                        ->disableOriginalConstructor()->getMock();
        }
 
+       /**
+        * @return \PHPUnit_Framework_MockObject_MockObject|SlotRoleRegistry
+        */
+       private function getMockSlotRoleRegistry() {
+               return $this->getMockBuilder( SlotRoleRegistry::class )
+                       ->disableOriginalConstructor()->getMock();
+       }
+
        private function getHashWANObjectCache() {
                return new WANObjectCache( [ 'cache' => new \HashBagOStuff() ] );
        }
@@ -127,6 +137,7 @@ class RevisionStoreTest extends MediaWikiTestCase {
                        $this->getMockCommentStore(),
                        $nameTables->getContentModels(),
                        $nameTables->getSlotRoles(),
+                       $this->getMockSlotRoleRegistry(),
                        $migrationMode,
                        MediaWikiServices::getInstance()->getActorMigration()
                );
@@ -541,6 +552,7 @@ class RevisionStoreTest extends MediaWikiTestCase {
                $nameTables = $services->getNameTableStoreFactory();
                $contentModelStore = $nameTables->getContentModels();
                $slotRoleStore = $nameTables->getSlotRoles();
+               $slotRoleRegistry = $services->getSlotRoleRegistry();
                $store = new RevisionStore(
                        $loadBalancer,
                        $blobStore,
@@ -548,6 +560,7 @@ class RevisionStoreTest extends MediaWikiTestCase {
                        $commentStore,
                        $nameTables->getContentModels(),
                        $nameTables->getSlotRoles(),
+                       $slotRoleRegistry,
                        $migration,
                        $services->getActorMigration()
                );
diff --git a/tests/phpunit/includes/Revision/SlotRoleHandlerTest.php b/tests/phpunit/includes/Revision/SlotRoleHandlerTest.php
new file mode 100644 (file)
index 0000000..67e9464
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+namespace MediaWiki\Tests\Revision;
+
+use MediaWiki\Revision\SlotRoleHandler;
+use MediaWikiTestCase;
+use Title;
+
+/**
+ * @covers \MediaWiki\Revision\SlotRoleHandler
+ */
+class SlotRoleHandlerTest extends MediaWikiTestCase {
+
+       private function makeBlankTitleObject() {
+               /** @var Title $title */
+               $title = $this->getMockBuilder( Title::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               return $title;
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleHandler::__construct
+        * @covers \MediaWiki\Revision\SlotRoleHandler::getRole()
+        * @covers \MediaWiki\Revision\SlotRoleHandler::getNameMessageKey()
+        * @covers \MediaWiki\Revision\SlotRoleHandler::getDefaultModel()
+        * @covers \MediaWiki\Revision\SlotRoleHandler::getOutputLayoutHints()
+        */
+       public function testConstruction() {
+               $handler = new SlotRoleHandler( 'foo', 'FooModel', [ 'frob' => 'niz' ] );
+               $this->assertSame( 'foo', $handler->getRole() );
+               $this->assertSame( 'slot-name-foo', $handler->getNameMessageKey() );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertSame( 'FooModel', $handler->getDefaultModel( $title ) );
+
+               $hints = $handler->getOutputLayoutHints();
+               $this->assertArrayHasKey( 'frob', $hints );
+               $this->assertSame( 'niz', $hints['frob'] );
+
+               $this->assertArrayHasKey( 'display', $hints );
+               $this->assertArrayHasKey( 'region', $hints );
+               $this->assertArrayHasKey( 'placement', $hints );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleHandler::isAllowedModel()
+        */
+       public function testIsAllowedModel() {
+               $handler = new SlotRoleHandler( 'foo', 'FooModel' );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertTrue( $handler->isAllowedModel( 'FooModel', $title ) );
+               $this->assertFalse( $handler->isAllowedModel( 'QuaxModel', $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleHandler::supportsArticleCount()
+        */
+       public function testSupportsArticleCount() {
+               $handler = new SlotRoleHandler( 'foo', 'FooModel' );
+
+               $this->assertFalse( $handler->supportsArticleCount() );
+       }
+
+}
diff --git a/tests/phpunit/includes/Revision/SlotRoleRegistryTest.php b/tests/phpunit/includes/Revision/SlotRoleRegistryTest.php
new file mode 100644 (file)
index 0000000..4d8030d
--- /dev/null
@@ -0,0 +1,194 @@
+<?php
+
+namespace MediaWiki\Tests\Revision;
+
+use InvalidArgumentException;
+use LogicException;
+use MediaWiki\Revision\MainSlotRoleHandler;
+use MediaWiki\Revision\SlotRoleHandler;
+use MediaWiki\Revision\SlotRoleRegistry;
+use MediaWiki\Storage\NameTableStore;
+use MediaWikiTestCase;
+use Title;
+use Wikimedia\Assert\PostconditionException;
+
+/**
+ * @covers \MediaWiki\Revision\SlotRoleRegistry
+ */
+class SlotRoleRegistryTest extends MediaWikiTestCase {
+
+       private function makeBlankTitleObject() {
+               /** @var Title $title */
+               $title = $this->getMockBuilder( Title::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               return $title;
+       }
+
+       private function makeNameTableStore( array $names = [] ) {
+               $mock = $this->getMockBuilder( NameTableStore::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $mock->method( 'getMap' )
+                       ->willReturn( $names );
+
+               return $mock;
+       }
+
+       private function newSlotRoleRegistry( NameTableStore $roleNameStore = null ) {
+               if ( !$roleNameStore ) {
+                       $roleNameStore = $this->makeNameTableStore();
+               }
+
+               return new SlotRoleRegistry( $roleNameStore );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::defineRole()
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getDefinedRoles()
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getKnownRoles()
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getRoleHandler()
+        */
+       public function testDefineRole() {
+               $registry = $this->newSlotRoleRegistry();
+               $registry->defineRole( 'foo', function ( $role ) {
+                       return new SlotRoleHandler( $role, 'FooModel' );
+               } );
+
+               $this->assertTrue( $registry->isDefinedRole( 'foo' ) );
+               $this->assertContains( 'foo', $registry->getDefinedRoles() );
+               $this->assertContains( 'foo', $registry->getKnownRoles() );
+
+               $handler = $registry->getRoleHandler( 'foo' );
+               $this->assertSame( 'foo', $handler->getRole() );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertSame( 'FooModel', $handler->getDefaultModel( $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::defineRole()
+        */
+       public function testDefineRoleFailsForDupe() {
+               $registry = $this->newSlotRoleRegistry();
+               $registry->defineRole( 'foo', function ( $role ) {
+                       return new SlotRoleHandler( $role, 'FooModel' );
+               } );
+
+               $this->setExpectedException( LogicException::class );
+               $registry->defineRole( 'foo', function ( $role ) {
+                       return new SlotRoleHandler( $role, 'FooModel' );
+               } );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::defineRoleWithModel()
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getDefinedRoles()
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getKnownRoles()
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getRoleHandler()
+        */
+       public function testDefineRoleWithContentModel() {
+               $registry = $this->newSlotRoleRegistry();
+               $registry->defineRoleWithModel( 'foo', 'FooModel' );
+
+               $this->assertTrue( $registry->isDefinedRole( 'foo' ) );
+               $this->assertContains( 'foo', $registry->getDefinedRoles() );
+               $this->assertContains( 'foo', $registry->getKnownRoles() );
+
+               $handler = $registry->getRoleHandler( 'foo' );
+               $this->assertSame( 'foo', $handler->getRole() );
+
+               /** @var Title $title */
+               $title = $this->getMockBuilder( Title::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $this->assertSame( 'FooModel', $handler->getDefaultModel( $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getRoleHandler()
+        */
+       public function testGetRoleHandlerForUnknownModel() {
+               $registry = $this->newSlotRoleRegistry();
+
+               $this->setExpectedException( InvalidArgumentException::class );
+
+               $registry->getRoleHandler( 'foo' );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getRoleHandler()
+        */
+       public function testGetRoleHandlerFallbackHandler() {
+               $registry = $this->newSlotRoleRegistry(
+                       $this->makeNameTableStore( [ 1 => 'foo' ] )
+               );
+
+               \Wikimedia\suppressWarnings();
+               $handler = $registry->getRoleHandler( 'foo' );
+               $this->assertSame( 'foo', $handler->getRole() );
+
+               \Wikimedia\restoreWarnings();
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getRoleHandler()
+        */
+       public function testGetRoleHandlerWithBadInstantiator() {
+               $registry = $this->newSlotRoleRegistry();
+               $registry->defineRole( 'foo', function ( $role ) {
+                       return 'Not a SlotRoleHandler instance';
+               } );
+
+               $this->setExpectedException( PostconditionException::class );
+               $registry->getRoleHandler( 'foo' );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getRequiredRoles()
+        */
+       public function testGetRequiredRoles() {
+               $registry = $this->newSlotRoleRegistry();
+               $registry->defineRole( 'main', function ( $role ) {
+                       return new MainSlotRoleHandler( [] );
+               } );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertEquals( [ 'main' ], $registry->getRequiredRoles( $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getAllowedRoles()
+        */
+       public function testGetAllowedRoles() {
+               $registry = $this->newSlotRoleRegistry();
+               $registry->defineRole( 'main', function ( $role ) {
+                       return new MainSlotRoleHandler( [] );
+               } );
+               $registry->defineRoleWithModel( 'foo', CONTENT_MODEL_TEXT );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertEquals( [ 'main', 'foo' ], $registry->getAllowedRoles( $title ) );
+       }
+
+       /**
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::getKnownRoles()
+        * @covers \MediaWiki\Revision\SlotRoleRegistry::isKnownRole()
+        */
+       public function testGetKnownRoles() {
+               $registry = $this->newSlotRoleRegistry(
+                       $this->makeNameTableStore( [ 1 => 'foo' ] )
+               );
+               $registry->defineRoleWithModel( 'bar', CONTENT_MODEL_TEXT );
+
+               $this->assertTrue( $registry->isKnownRole( 'foo' ) );
+               $this->assertTrue( $registry->isKnownRole( 'bar' ) );
+               $this->assertFalse( $registry->isKnownRole( 'xyzzy' ) );
+
+               $title = $this->makeBlankTitleObject();
+               $this->assertArrayEquals( [ 'foo', 'bar' ], $registry->getKnownRoles( $title ) );
+       }
+
+}
index e5e5551..a2f2796 100644 (file)
@@ -90,7 +90,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                $this->setMwGlobals( [
                        'wgMultiContentRevisionSchemaMigrationStage' => $this->getMcrMigrationStage(),
                        'wgContentHandlerUseDB' => $this->getContentHandlerUseDB(),
-                       'wgCommentTableSchemaMigrationStage' => MIGRATION_OLD,
+                       'wgCommentTableSchemaMigrationStage' => MIGRATION_NEW,
                        'wgActorTableSchemaMigrationStage' => SCHEMA_COMPAT_OLD,
                ] );
 
@@ -458,6 +458,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase {
                        $services->getCommentStore(),
                        $services->getContentModelStore(),
                        $services->getSlotRoleStore(),
+                       $services->getSlotRoleRegistry(),
                        $this->getMcrMigrationStage(),
                        $services->getActorMigration()
                );
index c053104..7ee800a 100644 (file)
@@ -281,10 +281,14 @@ class RevisionTest extends MediaWikiTestCase {
         * @covers \MediaWiki\Revision\RevisionStore::newMutableRevisionFromArray
         */
        public function testConstructFromRowWithBadPageId() {
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_NEW );
                $this->overrideMwServices();
                Wikimedia\suppressWarnings();
-               $rev = new Revision( (object)[ 'rev_page' => 77777777 ] );
+               $rev = new Revision( (object)[
+                       'rev_page' => 77777777,
+                       'rev_comment_text' => '',
+                       'rev_comment_data' => null,
+               ] );
                $this->assertSame( 77777777, $rev->getPage() );
                Wikimedia\restoreWarnings();
        }
@@ -474,6 +478,7 @@ class RevisionTest extends MediaWikiTestCase {
                        MediaWikiServices::getInstance()->getCommentStore(),
                        MediaWikiServices::getInstance()->getContentModelStore(),
                        MediaWikiServices::getInstance()->getSlotRoleStore(),
+                       MediaWikiServices::getInstance()->getSlotRoleRegistry(),
                        MIGRATION_OLD,
                        MediaWikiServices::getInstance()->getActorMigration()
                );
@@ -597,7 +602,7 @@ class RevisionTest extends MediaWikiTestCase {
         * @covers Revision::loadFromTitle
         */
        public function testLoadFromTitle() {
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_NEW );
                $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_OLD );
                $this->overrideMwServices();
                $title = $this->getMockTitle();
@@ -634,7 +639,10 @@ class RevisionTest extends MediaWikiTestCase {
                $db->expects( $this->once() )
                        ->method( 'selectRow' )
                        ->with(
-                               $this->equalTo( [ 'revision', 'page', 'user' ] ),
+                               $this->equalTo( [
+                                       'revision', 'page', 'user',
+                                       'temp_rev_comment' => 'revision_comment_temp', 'comment_rev_comment' => 'comment',
+                               ] ),
                                // We don't really care about the fields are they come from the selectField methods
                                $this->isType( 'array' ),
                                $this->equalTo( $conditions ),
index 7320305..5f3cba3 100644 (file)
@@ -102,6 +102,9 @@ class DerivedPageDataUpdaterTest extends MediaWikiTestCase {
                }
 
                $rev = $updater->saveRevision( $comment );
+               if ( !$updater->wasSuccessful() ) {
+                       $this->fail( $updater->getStatus()->getWikiText() );
+               }
 
                $this->getDerivedPageDataUpdater( $page ); // flush cached instance after.
                return $rev;
@@ -186,6 +189,11 @@ class DerivedPageDataUpdaterTest extends MediaWikiTestCase {
         * @covers \MediaWiki\Storage\DerivedPageDataUpdater::getCanonicalParserOutput()
         */
        public function testPrepareContent() {
+               MediaWikiServices::getInstance()->getSlotRoleRegistry()->defineRoleWithModel(
+                       'aux',
+                       CONTENT_MODEL_WIKITEXT
+               );
+
                $sysop = $this->getTestUser( [ 'sysop' ] )->getUser();
                $updater = $this->getDerivedPageDataUpdater( __METHOD__ );
 
@@ -584,9 +592,7 @@ class DerivedPageDataUpdaterTest extends MediaWikiTestCase {
        }
 
        public function testGetSecondaryDataUpdatesWithSlotRemoval() {
-               global $wgMultiContentRevisionSchemaMigrationStage;
-
-               if ( ! ( $wgMultiContentRevisionSchemaMigrationStage & SCHEMA_COMPAT_READ_NEW ) ) {
+               if ( !$this->hasMultiSlotSupport() ) {
                        $this->markTestSkipped( 'Slot removal cannot happen with MCR being enabled' );
                }
 
@@ -594,6 +600,11 @@ class DerivedPageDataUpdaterTest extends MediaWikiTestCase {
                $a1 = $this->defineMockContentModelForUpdateTesting( 'A1' );
                $m2 = $this->defineMockContentModelForUpdateTesting( 'M2' );
 
+               MediaWikiServices::getInstance()->getSlotRoleRegistry()->defineRoleWithModel(
+                       'aux',
+                       $a1->getModelID()
+               );
+
                $mainContent1 = $this->createMockContent( $m1, 'main 1' );
                $auxContent1 = $this->createMockContent( $a1, 'aux 1' );
                $mainContent2 = $this->createMockContent( $m2, 'main 2' );
@@ -866,6 +877,11 @@ class DerivedPageDataUpdaterTest extends MediaWikiTestCase {
 
                if ( $this->hasMultiSlotSupport() ) {
                        $content['aux'] = new WikitextContent( 'Aux [[Nix]]' );
+
+                       MediaWikiServices::getInstance()->getSlotRoleRegistry()->defineRoleWithModel(
+                               'aux',
+                               CONTENT_MODEL_WIKITEXT
+                       );
                }
 
                $rev = $this->createRevision( $page, 'first', $content );
index 3ba9032..4e09077 100644 (file)
@@ -22,6 +22,15 @@ use WikiPage;
  */
 class PageUpdaterTest extends MediaWikiTestCase {
 
+       public function setUp() {
+               parent::setUp();
+
+               MediaWikiServices::getInstance()->getSlotRoleRegistry()->defineRoleWithModel(
+                       'aux',
+                       CONTENT_MODEL_WIKITEXT
+               );
+       }
+
        private function getDummyTitle( $method ) {
                return Title::newFromText( $method, $this->getDefaultWikitextNS() );
        }
@@ -337,6 +346,34 @@ class PageUpdaterTest extends MediaWikiTestCase {
                $this->assertTrue( $status->hasMessage( 'edit-already-exists' ), 'edit-already-exists' );
        }
 
+       /**
+        * @covers \MediaWiki\Storage\PageUpdater::saveRevision()
+        */
+       public function testFailureOnBadContentModel() {
+               $user = $this->getTestUser()->getUser();
+               $title = $this->getDummyTitle( __METHOD__ );
+
+               // start editing non-existing page
+               $page = WikiPage::factory( $title );
+               $updater = $page->newPageUpdater( $user );
+
+               // plain text content should fail in aux slot (the main slot doesn't care)
+               $updater->setContent( 'main', new TextContent( 'Main Content' ) );
+               $updater->setContent( 'aux', new TextContent( 'Aux Content' ) );
+
+               $summary = CommentStoreComment::newUnsavedComment( 'udpate?!' );
+               $updater->saveRevision( $summary, EDIT_UPDATE );
+               $status = $updater->getStatus();
+
+               $this->assertFalse( $updater->wasSuccessful(), 'wasSuccessful()' );
+               $this->assertNull( $updater->getNewRevision(), 'getNewRevision()' );
+               $this->assertFalse( $status->isOK(), 'getStatus()->isOK()' );
+               $this->assertTrue(
+                       $status->hasMessage( 'content-not-allowed-here' ),
+                       'content-not-allowed-here'
+               );
+       }
+
        public function provideSetRcPatrolStatus( $patrolled ) {
                yield [ RecentChange::PRC_UNPATROLLED ];
                yield [ RecentChange::PRC_AUTOPATROLLED ];
index cb5e1f8..11b9c01 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 
-use MediaWiki\Block\Restriction\PageRestriction;
 use MediaWiki\MediaWikiServices;
 
 /**
@@ -893,7 +892,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        'wgEmailAuthentication' => true,
                ] );
 
-               $this->setUserPerm( [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ] );
+               $this->setUserPerm( [ "createpage", "move" ] );
                $this->setTitle( NS_HELP, "test page" );
 
                # $wgEmailConfirmToEdit only applies to 'edit' action
@@ -965,24 +964,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        'expiry' => 10,
                        'systemBlock' => 'test',
                ] );
-
-               $errors = [ [ 'systemblockedtext',
+               $this->assertEquals( [ [ 'systemblockedtext',
                                '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
                                'Useruser', 'test', '23:00, 31 December 1969', '127.0.8.1',
-                               $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
-
-               $this->assertEquals( $errors,
-                       $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
-               $this->assertEquals( $errors,
+                               $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
-               $this->assertEquals( $errors,
-                       $this->title->getUserPermissionsErrors( 'rollback', $this->user ) );
-               $this->assertEquals( $errors,
-                       $this->title->getUserPermissionsErrors( 'patrol', $this->user ) );
-               $this->assertEquals( $errors,
-                       $this->title->getUserPermissionsErrors( 'upload', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'purge', $this->user ) );
 
                // partial block message test
                $this->user->mBlockedby = $this->user->getName();
@@ -995,39 +981,10 @@ class TitlePermissionTest extends MediaWikiLangTestCase {
                        'expiry' => 10,
                ] );
 
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'rollback', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'patrol', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'upload', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'purge', $this->user ) );
-
-               $this->user->mBlock->setRestrictions( [
-                               ( new PageRestriction( 0, $this->title->getArticleID() ) )->setTitle( $this->title ),
-               ] );
-
-               $errors = [ [ 'blockedtext-partial',
+               $this->assertEquals( [ [ 'blockedtext-partial',
                                '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
                                'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
-                               $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
-
-               $this->assertEquals( $errors,
-                       $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
-               $this->assertEquals( $errors,
+                               $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
                        $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
-               $this->assertEquals( $errors,
-                       $this->title->getUserPermissionsErrors( 'rollback', $this->user ) );
-               $this->assertEquals( $errors,
-                       $this->title->getUserPermissionsErrors( 'patrol', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'upload', $this->user ) );
-               $this->assertEquals( [],
-                       $this->title->getUserPermissionsErrors( 'purge', $this->user ) );
        }
 }
index 563d5e3..9898e53 100644 (file)
@@ -116,24 +116,6 @@ class ApiBlockTest extends ApiTestCase {
        }
 
        public function testBlockWithTag() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               ChangeTags::defineTag( 'custom tag' );
-
-               $this->doBlock( [ 'tags' => 'custom tag' ] );
-
-               $dbw = wfGetDB( DB_MASTER );
-               $this->assertSame( 1, (int)$dbw->selectField(
-                       [ 'change_tag', 'logging' ],
-                       'COUNT(*)',
-                       [ 'log_type' => 'block', 'ct_tag' => 'custom tag' ],
-                       __METHOD__,
-                       [],
-                       [ 'change_tag' => [ 'INNER JOIN', 'ct_log_id = log_id' ] ]
-               ) );
-       }
-
-       public function testBlockWithTagNewBackend() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
                ChangeTags::defineTag( 'custom tag' );
 
                $this->doBlock( [ 'tags' => 'custom tag' ] );
index f2db1b2..fc546ff 100644 (file)
@@ -74,37 +74,6 @@ class ApiDeleteTest extends ApiTestCase {
        }
 
        public function testDeleteWithTag() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $name = 'Help:' . ucfirst( __FUNCTION__ );
-
-               ChangeTags::defineTag( 'custom tag' );
-
-               $this->editPage( $name, 'Some text' );
-
-               $this->doApiRequestWithToken( [
-                       'action' => 'delete',
-                       'title' => $name,
-                       'tags' => 'custom tag',
-               ] );
-
-               $this->assertFalse( Title::newFromText( $name )->exists() );
-
-               $dbw = wfGetDB( DB_MASTER );
-               $this->assertSame( 'custom tag', $dbw->selectField(
-                       [ 'change_tag', 'logging' ],
-                       'ct_tag',
-                       [
-                               'log_namespace' => NS_HELP,
-                               'log_title' => ucfirst( __FUNCTION__ ),
-                       ],
-                       __METHOD__,
-                       [],
-                       [ 'change_tag' => [ 'INNER JOIN', 'ct_log_id = log_id' ] ]
-               ) );
-       }
-
-       public function testDeleteWithTagNewBackend() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
                $name = 'Help:' . ucfirst( __FUNCTION__ );
 
                ChangeTags::defineTag( 'custom tag' );
index 847316a..2161093 100644 (file)
@@ -1332,25 +1332,6 @@ class ApiEditPageTest extends ApiTestCase {
        }
 
        public function testEditWithTag() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $name = 'Help:' . ucfirst( __FUNCTION__ );
-
-               ChangeTags::defineTag( 'custom tag' );
-
-               $revId = $this->doApiRequestWithToken( [
-                       'action' => 'edit',
-                       'title' => $name,
-                       'text' => 'Some text',
-                       'tags' => 'custom tag',
-               ] )[0]['edit']['newrevid'];
-
-               $dbw = wfGetDB( DB_MASTER );
-               $this->assertSame( 'custom tag', $dbw->selectField(
-                       'change_tag', 'ct_tag', [ 'ct_rev_id' => $revId ], __METHOD__ ) );
-       }
-
-       public function testEditWithTagNewBackend() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
                $name = 'Help:' . ucfirst( __FUNCTION__ );
 
                ChangeTags::defineTag( 'custom tag' );
index d11e314..312ef55 100644 (file)
@@ -599,7 +599,9 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                                [
                                        'text' => '&#60;b&#62;Something broke!&#60;/b&#62;',
                                        'code' => 'internal_api_error_RuntimeException',
-                                       'data' => [],
+                                       'data' => [
+                                               'errorclass' => 'RuntimeException',
+                                       ],
                                ]
                        ],
                        'Normal exception, wrapped' => [
@@ -632,4 +634,23 @@ class ApiErrorFormatterTest extends MediaWikiLangTestCase {
                ];
        }
 
+       /**
+        * @dataProvider provideIsValidApiCode
+        * @covers ApiErrorFormatter::isValidApiCode
+        * @param string $code
+        * @param bool $expect
+        */
+       public function testIsValidApiCode( $code, $expect ) {
+               $this->assertSame( $expect, ApiErrorFormatter::isValidApiCode( $code ) );
+       }
+
+       public static function provideIsValidApiCode() {
+               return [
+                       [ 'foo-bar_Baz123', true ],
+                       [ 'foo bar', false ],
+                       [ 'foo\\bar', false ],
+                       [ 'internal_api_error_foo\\bar baz', true ],
+               ];
+       }
+
 }
index a6083cd..9cb84e2 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\DBQueryError;
 use Wikimedia\TestingAccessWrapper;
 
 /**
@@ -1010,6 +1011,15 @@ class ApiMainTest extends ApiTestCase {
                        MWExceptionHandler::getRedactedTraceAsString( $dbex )
                )->inLanguage( 'en' )->useDatabase( false )->text();
 
+               // The specific exception doesn't matter, as long as it's namespaced.
+               $nsex = new MediaWiki\ShellDisabledError();
+               $nstrace = wfMessage( 'api-exception-trace',
+                       get_class( $nsex ),
+                       $nsex->getFile(),
+                       $nsex->getLine(),
+                       MWExceptionHandler::getRedactedTraceAsString( $nsex )
+               )->inLanguage( 'en' )->useDatabase( false )->text();
+
                $apiEx1 = new ApiUsageException( null,
                        StatusValue::newFatal( new ApiRawMessage( 'An error', 'sv-error1' ) ) );
                TestingAccessWrapper::newFromObject( $apiEx1 )->modulePath = 'foo+bar';
@@ -1017,6 +1027,13 @@ class ApiMainTest extends ApiTestCase {
                $apiEx1->getStatusValue()->warning( new ApiRawMessage( 'Another warning', 'sv-warn2' ) );
                $apiEx1->getStatusValue()->fatal( new ApiRawMessage( 'Another error', 'sv-error2' ) );
 
+               $badMsg = $this->getMockBuilder( ApiRawMessage::class )
+                        ->setConstructorArgs( [ 'An error', 'ignored' ] )
+                        ->setMethods( [ 'getApiCode' ] )
+                        ->getMock();
+               $badMsg->method( 'getApiCode' )->willReturn( "bad\nvalue" );
+               $apiEx2 = new ApiUsageException( null, StatusValue::newFatal( $badMsg ) );
+
                return [
                        [
                                $ex,
@@ -1030,6 +1047,9 @@ class ApiMainTest extends ApiTestCase {
                                                [
                                                        'code' => 'internal_api_error_InvalidArgumentException',
                                                        'text' => "[$reqId] Exception caught: Random exception",
+                                                       'data' => [
+                                                               'errorclass' => InvalidArgumentException::class,
+                                                       ],
                                                ]
                                        ],
                                        'trace' => $trace,
@@ -1049,12 +1069,36 @@ class ApiMainTest extends ApiTestCase {
                                                        'code' => 'internal_api_error_DBQueryError',
                                                        'text' => "[$reqId] Exception caught: A database query error has occurred. " .
                                                                "This may indicate a bug in the software.",
+                                                       'data' => [
+                                                               'errorclass' => DBQueryError::class,
+                                                       ],
                                                ]
                                        ],
                                        'trace' => $dbtrace,
                                        'servedby' => wfHostname(),
                                ]
                        ],
+                       [
+                               $nsex,
+                               [ 'existing-error', 'internal_api_error_MediaWiki\ShellDisabledError' ],
+                               [
+                                       'warnings' => [
+                                               [ 'code' => 'existing-warning', 'text' => 'existing warning', 'module' => 'main' ],
+                                       ],
+                                       'errors' => [
+                                               [ 'code' => 'existing-error', 'text' => 'existing error', 'module' => 'main' ],
+                                               [
+                                                       'code' => 'internal_api_error_MediaWiki\ShellDisabledError',
+                                                       'text' => "[$reqId] Exception caught: " . $nsex->getMessage(),
+                                                       'data' => [
+                                                               'errorclass' => MediaWiki\ShellDisabledError::class,
+                                                       ],
+                                               ]
+                                       ],
+                                       'trace' => $nstrace,
+                                       'servedby' => wfHostname(),
+                               ]
+                       ],
                        [
                                $apiEx1,
                                [ 'existing-error', 'sv-error1', 'sv-error2' ],
@@ -1075,6 +1119,23 @@ class ApiMainTest extends ApiTestCase {
                                        'servedby' => wfHostname(),
                                ]
                        ],
+                       [
+                               $apiEx2,
+                               [ 'existing-error', '<invalid-code>' ],
+                               [
+                                       'warnings' => [
+                                               [ 'code' => 'existing-warning', 'text' => 'existing warning', 'module' => 'main' ],
+                                       ],
+                                       'errors' => [
+                                               [ 'code' => 'existing-error', 'text' => 'existing error', 'module' => 'main' ],
+                                               [ 'code' => "bad\nvalue", 'text' => 'An error' ],
+                                       ],
+                                       'docref' => "See $doclink for API usage. Subscribe to the mediawiki-api-announce mailing " .
+                                               "list at &lt;https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce&gt; " .
+                                               "for notice of API deprecations and breaking changes.",
+                                       'servedby' => wfHostname(),
+                               ]
+                       ]
                ];
        }
 
index c6f5a8e..70114c2 100644 (file)
@@ -38,6 +38,10 @@ class ApiMessageTest extends MediaWikiTestCase {
                $msg = new ApiMessage( 'apiwarn-baz' );
                $this->assertSame( 'baz', $msg->getApiCode() );
 
+               // Weird "message key"
+               $msg = new ApiMessage( "<foo> bar\nbaz" );
+               $this->assertSame( '_foo__bar_baz', $msg->getApiCode() );
+
                // BC case
                $msg = new ApiMessage( 'actionthrottledtext' );
                $this->assertSame( 'ratelimited', $msg->getApiCode() );
@@ -72,6 +76,9 @@ class ApiMessageTest extends MediaWikiTestCase {
                return [
                        [ '' ],
                        [ 42 ],
+                       [ 'A bad code' ],
+                       [ 'Project:A_page_title' ],
+                       [ "WTF\nnewlines" ],
                ];
        }
 
index 24744df..6ebd835 100644 (file)
@@ -114,26 +114,7 @@ class ApiUnblockTest extends ApiTestCase {
                $this->doUnblock( [ 'user' => $this->blocker->getName() ] );
        }
 
-       // XXX These three tests copy-pasted from ApiBlockTest.php
-       public function testUnblockWithTag() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               ChangeTags::defineTag( 'custom tag' );
-
-               $this->doUnblock( [ 'tags' => 'custom tag' ] );
-
-               $dbw = wfGetDB( DB_MASTER );
-               $this->assertSame( 1, (int)$dbw->selectField(
-                       [ 'change_tag', 'logging' ],
-                       'COUNT(*)',
-                       [ 'log_type' => 'block', 'ct_tag' => 'custom tag' ],
-                       __METHOD__,
-                       [],
-                       [ 'change_tag' => [ 'INNER JOIN', 'ct_log_id = log_id' ] ]
-               ) );
-       }
-
        public function testUnblockWithTagNewBackend() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
                ChangeTags::defineTag( 'custom tag' );
 
                $this->doUnblock( [ 'tags' => 'custom tag' ] );
index 2534ad3..8cc0217 100644 (file)
@@ -188,31 +188,6 @@ class ApiUserrightsTest extends ApiTestCase {
        }
 
        public function testWithTag() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               ChangeTags::defineTag( 'custom tag' );
-
-               $user = $this->getMutableTestUser()->getUser();
-
-               $this->doSuccessfulRightsChange( 'sysop', [ 'tags' => 'custom tag' ], $user );
-
-               $dbr = wfGetDB( DB_REPLICA );
-               $this->assertSame(
-                       'custom tag',
-                       $dbr->selectField(
-                               [ 'change_tag', 'logging' ],
-                               'ct_tag',
-                               [
-                                       'ct_log_id = log_id',
-                                       'log_namespace' => NS_USER,
-                                       'log_title' => strtr( $user->getName(), ' ', '_' )
-                               ],
-                               __METHOD__
-                       )
-               );
-       }
-
-       public function testWithTagNewBackend() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
                ChangeTags::defineTag( 'custom tag' );
 
                $user = $this->getMutableTestUser()->getUser();
index cb9dd41..8265af8 100644 (file)
@@ -331,74 +331,10 @@ class ChangeTagsTest extends MediaWikiTestCase {
                $this->assertEquals( $expected, $actual );
        }
 
-       public function testUpdateTagsMigrationOld() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_OLD );
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'change_tag', '*' );
-               $dbw->delete( 'change_tag_def', '*' );
-
-               $rcId = 123;
-               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
-
-               $dbr = wfGetDB( DB_REPLICA );
-
-               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
-               $this->assertEquals( [], iterator_to_array( $res, false ) );
-
-               $expected2 = [
-                       (object)[
-                               'ct_tag' => 'tag1',
-                               'ct_tag_id' => null,
-                               'ct_rc_id' => 123
-                       ],
-                       (object)[
-                               'ct_tag' => 'tag2',
-                               'ct_tag_id' => null,
-                               'ct_rc_id' => 123
-                       ],
-               ];
-               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
-               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
-
-               $rcId = 124;
-               ChangeTags::updateTags( [ 'tag1', 'tag3' ], [], $rcId );
-
-               $dbr = wfGetDB( DB_REPLICA );
-
-               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
-               $this->assertEquals( [], iterator_to_array( $res, false ) );
-
-               $expected2 = [
-                       (object)[
-                               'ct_tag' => 'tag1',
-                               'ct_tag_id' => null,
-                               'ct_rc_id' => 123
-                       ],
-                       (object)[
-                               'ct_tag' => 'tag2',
-                               'ct_tag_id' => null,
-                               'ct_rc_id' => 123
-                       ],
-                       (object)[
-                               'ct_tag' => 'tag1',
-                               'ct_tag_id' => null,
-                               'ct_rc_id' => 124
-                       ],
-                       (object)[
-                               'ct_tag' => 'tag3',
-                               'ct_tag_id' => null,
-                               'ct_rc_id' => 124
-                       ],
-               ];
-               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
-               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
-       }
-
-       public function testUpdateTagsMigrationWriteBoth() {
+       public function testUpdateTags() {
                // FIXME: fails under postgres
                $this->markTestSkippedIfDbType( 'postgres' );
 
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
                $dbw = wfGetDB( DB_MASTER );
                $dbw->delete( 'change_tag', '*' );
                $dbw->delete( 'change_tag_def', '*' );
@@ -425,17 +361,15 @@ class ChangeTagsTest extends MediaWikiTestCase {
 
                $expected2 = [
                        (object)[
-                               'ct_tag' => 'tag1',
                                'ct_tag_id' => 1,
                                'ct_rc_id' => 123
                        ],
                        (object)[
-                               'ct_tag' => 'tag2',
                                'ct_tag_id' => 2,
                                'ct_rc_id' => 123
                        ],
                ];
-               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag_id', 'ct_rc_id' ], '' );
                $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
 
                $rcId = 124;
@@ -467,59 +401,27 @@ class ChangeTagsTest extends MediaWikiTestCase {
 
                $expected2 = [
                        (object)[
-                               'ct_tag' => 'tag1',
                                'ct_tag_id' => 1,
                                'ct_rc_id' => 123
                        ],
                        (object)[
-                               'ct_tag' => 'tag2',
                                'ct_tag_id' => 2,
                                'ct_rc_id' => 123
                        ],
                        (object)[
-                               'ct_tag' => 'tag1',
                                'ct_tag_id' => 1,
                                'ct_rc_id' => 124
                        ],
                        (object)[
-                               'ct_tag' => 'tag3',
                                'ct_tag_id' => 3,
                                'ct_rc_id' => 124
                        ],
                ];
-               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
-               $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
-       }
-
-       public function testDeleteTagsMigrationOld() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_OLD );
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'change_tag', '*' );
-               $dbw->delete( 'change_tag_def', '*' );
-
-               $rcId = 123;
-               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
-
-               ChangeTags::updateTags( [], [ 'tag2' ], $rcId );
-
-               $dbr = wfGetDB( DB_REPLICA );
-
-               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_id', 'ctd_count' ], '' );
-               $this->assertEquals( [], iterator_to_array( $res, false ) );
-
-               $expected2 = [
-                       (object)[
-                               'ct_tag' => 'tag1',
-                               'ct_tag_id' => null,
-                               'ct_rc_id' => 123
-                       ]
-               ];
-               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag_id', 'ct_rc_id' ], '' );
                $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
        }
 
-       public function testDeleteTagsMigrationWriteBoth() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
+       public function testDeleteTags() {
                $dbw = wfGetDB( DB_MASTER );
                $dbw->delete( 'change_tag', '*' );
                $dbw->delete( 'change_tag_def', '*' );
@@ -544,54 +446,15 @@ class ChangeTagsTest extends MediaWikiTestCase {
 
                $expected2 = [
                        (object)[
-                               'ct_tag' => 'tag1',
                                'ct_tag_id' => 1,
                                'ct_rc_id' => 123
                        ]
                ];
-               $res2 = $dbr->select( 'change_tag', [ 'ct_tag', 'ct_tag_id', 'ct_rc_id' ], '' );
+               $res2 = $dbr->select( 'change_tag', [ 'ct_tag_id', 'ct_rc_id' ], '' );
                $this->assertEquals( $expected2, iterator_to_array( $res2, false ) );
        }
 
-       public function testTagUsageStatisticsOldBackend() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_OLD );
-               $this->setMwGlobals( 'wgTagStatisticsNewTable', false );
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'change_tag', '*' );
-               $dbw->delete( 'change_tag_def', '*' );
-
-               $rcId = 123;
-               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
-
-               $rcId = 124;
-               ChangeTags::updateTags( [ 'tag1' ], [], $rcId );
-
-               $this->assertEquals( [ 'tag1' => 2, 'tag2' => 1 ], ChangeTags::tagUsageStatistics() );
-       }
-
-       public function testTagUsageStatisticsNewMigrationOldBackedn() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $this->setMwGlobals( 'wgTagStatisticsNewTable', false );
-
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'change_tag', '*' );
-               $dbw->delete( 'change_tag_def', '*' );
-               MediaWikiServices::getInstance()->resetServiceForTesting( 'NameTableStoreFactory' );
-
-               $rcId = 123;
-               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
-
-               $rcId = 124;
-               ChangeTags::updateTags( [ 'tag1' ], [], $rcId );
-
-               $this->assertEquals( [ 'tag1' => 2, 'tag2' => 1 ], ChangeTags::tagUsageStatistics() );
-       }
-
-       public function testTagUsageStatisticsNewBackend() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $this->setMwGlobals( 'wgTagStatisticsNewTable', true );
-
+       public function testTagUsageStatistics() {
                $dbw = wfGetDB( DB_MASTER );
                $dbw->delete( 'change_tag', '*' );
                $dbw->delete( 'change_tag_def', '*' );
@@ -606,57 +469,7 @@ class ChangeTagsTest extends MediaWikiTestCase {
                $this->assertEquals( [ 'tag1' => 2, 'tag2' => 1 ], ChangeTags::tagUsageStatistics() );
        }
 
-       public function testListExplicitlyDefinedTagsOld() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_OLD );
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'change_tag', '*' );
-               $dbw->delete( 'change_tag_def', '*' );
-               $dbw->delete( 'valid_tag', '*' );
-
-               $rcId = 123;
-               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
-               ChangeTags::defineTag( 'tag2' );
-
-               $this->assertEquals( [ 'tag2' ], ChangeTags::listExplicitlyDefinedTags() );
-               $dbr = wfGetDB( DB_REPLICA );
-               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_user_defined' ], '' );
-               $this->assertEquals( [], iterator_to_array( $res, false ) );
-
-               $this->assertEquals( [ 'tag2' ], $dbr->selectFieldValues( 'valid_tag', 'vt_tag', '' ) );
-       }
-
-       public function testListExplicitlyDefinedTagsWriteBoth() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->delete( 'change_tag', '*' );
-               $dbw->delete( 'change_tag_def', '*' );
-               $dbw->delete( 'valid_tag', '*' );
-
-               $rcId = 123;
-               ChangeTags::updateTags( [ 'tag1', 'tag2' ], [], $rcId );
-               ChangeTags::defineTag( 'tag2' );
-
-               $this->assertEquals( [ 'tag2' ], ChangeTags::listExplicitlyDefinedTags() );
-               $dbr = wfGetDB( DB_REPLICA );
-
-               $expected = [
-                       (object)[
-                               'ctd_name' => 'tag1',
-                               'ctd_user_defined' => 0
-                       ],
-                       (object)[
-                               'ctd_name' => 'tag2',
-                               'ctd_user_defined' => 1
-                       ],
-               ];
-               $res = $dbr->select( 'change_tag_def', [ 'ctd_name', 'ctd_user_defined' ], '' );
-               $this->assertEquals( $expected, iterator_to_array( $res, false ) );
-
-               $this->assertEquals( [ 'tag2' ], $dbr->selectFieldValues( 'valid_tag', 'vt_tag', '' ) );
-       }
-
-       public function testListExplicitlyDefinedTagsNew() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
+       public function testListExplicitlyDefinedTags() {
                $dbw = wfGetDB( DB_MASTER );
                $dbw->delete( 'change_tag', '*' );
                $dbw->delete( 'change_tag_def', '*' );
index e865e79..58f9654 100644 (file)
@@ -493,7 +493,7 @@ class LBFactoryTest extends MediaWikiTestCase {
                $lb->reuseConnection( $db ); // don't care
 
                $db = $lb->getConnection( DB_MASTER ); // local domain connection
-               $factory->setDomainPrefix( 'my_' );
+               $factory->setLocalDomainPrefix( 'my_' );
 
                $this->assertEquals( $wgDBname, $db->getDBname() );
                $this->assertEquals(
@@ -556,7 +556,7 @@ class LBFactoryTest extends MediaWikiTestCase {
 
                $lb->reuseConnection( $db ); // don't care
 
-               $factory->setDomainPrefix( 'my_' );
+               $factory->setLocalDomainPrefix( 'my_' );
                $db = $lb->getConnection( DB_MASTER, [], "$wgDBname-my_" );
 
                $this->assertEquals(
@@ -621,6 +621,50 @@ class LBFactoryTest extends MediaWikiTestCase {
                }
        }
 
+       public function testRedefineLocalDomain() {
+               global $wgDBname;
+
+               if ( wfGetDB( DB_MASTER )->databasesAreIndependent() ) {
+                       self::markTestSkipped( "Skipping tests about selecting DBs: not applicable" );
+                       return;
+               }
+
+               $factory = $this->newLBFactoryMulti(
+                       [],
+                       []
+               );
+               $lb = $factory->getMainLB();
+
+               $conn1 = $lb->getConnectionRef( DB_MASTER );
+               $this->assertEquals(
+                       wfWikiID(),
+                       $conn1->getDomainID()
+               );
+               unset( $conn1 );
+
+               $factory->redefineLocalDomain( 'somedb-prefix' );
+               $this->assertEquals( 'somedb-prefix', $factory->getLocalDomainID() );
+
+               $domain = new DatabaseDomain( $wgDBname, null, 'pref' );
+               $factory->redefineLocalDomain( $domain );
+
+               $n = 0;
+               $lb->forEachOpenConnection( function () use ( &$n ) {
+                       ++$n;
+               } );
+               $this->assertEquals( 0, $n, "Connections closed" );
+
+               $conn2 = $lb->getConnectionRef( DB_MASTER );
+               $this->assertEquals(
+                       $domain->getId(),
+                       $conn2->getDomainID()
+               );
+               unset( $conn2 );
+
+               $factory->closeAll();
+               $factory->destroy();
+       }
+
        private function quoteTable( Database $db, $table ) {
                if ( $db->getType() === 'sqlite' ) {
                        return $table;
index 1f73324..9f88cd7 100644 (file)
@@ -61,13 +61,16 @@ class CategoryMembershipChangeJobTest extends MediaWikiTestCase {
         * @return RecentChange|null
         */
        private function getCategorizeRecentChangeForRevId( $revId ) {
-               return RecentChange::newFromConds(
+               $rc = RecentChange::newFromConds(
                        [
                                'rc_type' => RC_CATEGORIZE,
                                'rc_this_oldid' => $revId,
                        ],
                        __METHOD__
                );
+
+               $this->assertNotNull( $rc, 'rev__id = ' . $revId );
+               return $rc;
        }
 
        public function testRun_normalCategoryAddedAndRemoved() {
index 7665b78..215177d 100644 (file)
@@ -48,6 +48,11 @@ class RefreshLinksJobTest extends MediaWikiTestCase {
        // TODO: test partition
 
        public function testRunForSinglePage() {
+               MediaWikiServices::getInstance()->getSlotRoleRegistry()->defineRoleWithModel(
+                       'aux',
+                       CONTENT_MODEL_WIKITEXT
+               );
+
                $mainContent = new WikitextContent( 'MAIN [[Kittens]]' );
                $auxContent = new WikitextContent( 'AUX [[Category:Goats]]' );
                $page = $this->createPage( __METHOD__, [ 'main' => $mainContent, 'aux' => $auxContent ] );
index 1e16097..ba4b2e2 100644 (file)
@@ -52,7 +52,7 @@ class PageArchiveMcrTest extends PageArchiveTestBase {
                                'ar_page_id' => strval( $this->ipRev->getPageId() ),
                                'ar_comment_text' => 'just a test',
                                'ar_comment_data' => null,
-                               'ar_comment_cid' => null,
+                               'ar_comment_cid' => '2',
                                'ts_tags' => null,
                                'ar_id' => '2',
                                'ar_namespace' => '0',
@@ -72,7 +72,7 @@ class PageArchiveMcrTest extends PageArchiveTestBase {
                                'ar_page_id' => strval( $this->firstRev->getPageId() ),
                                'ar_comment_text' => 'testing',
                                'ar_comment_data' => null,
-                               'ar_comment_cid' => null,
+                               'ar_comment_cid' => '1',
                                'ts_tags' => null,
                                'ar_id' => '1',
                                'ar_namespace' => '0',
index 4df4ee1..f8d4ef9 100644 (file)
@@ -54,7 +54,7 @@ class PageArchivePreMcrTest extends PageArchiveTestBase {
                                'ar_page_id' => strval( $this->ipRev->getPageId() ),
                                'ar_comment_text' => 'just a test',
                                'ar_comment_data' => null,
-                               'ar_comment_cid' => null,
+                               'ar_comment_cid' => '2',
                                'ar_content_format' => null,
                                'ar_content_model' => null,
                                'ts_tags' => null,
@@ -79,7 +79,7 @@ class PageArchivePreMcrTest extends PageArchiveTestBase {
                                'ar_page_id' => strval( $this->firstRev->getPageId() ),
                                'ar_comment_text' => 'testing',
                                'ar_comment_data' => null,
-                               'ar_comment_cid' => null,
+                               'ar_comment_cid' => '1',
                                'ar_content_format' => null,
                                'ar_content_model' => null,
                                'ts_tags' => null,
index ade8efd..26b6b52 100644 (file)
@@ -43,12 +43,14 @@ abstract class PageArchiveTestBase extends MediaWikiTestCase {
                        [
                                'page',
                                'revision',
+                               'revision_comment_temp',
                                'ip_changes',
                                'text',
                                'archive',
                                'recentchanges',
                                'logging',
                                'page_props',
+                               'comment',
                        ]
                );
        }
@@ -80,7 +82,7 @@ abstract class PageArchiveTestBase extends MediaWikiTestCase {
 
                $this->tablesUsed += $this->getMcrTablesToReset();
 
-               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_OLD );
+               $this->setMwGlobals( 'wgCommentTableSchemaMigrationStage', MIGRATION_NEW );
                $this->setMwGlobals( 'wgActorTableSchemaMigrationStage', SCHEMA_COMPAT_OLD );
                $this->setMwGlobals( 'wgContentHandlerUseDB', $this->getContentHandlerUseDB() );
                $this->setMwGlobals(
index fee4583..f7e5bd1 100644 (file)
@@ -135,6 +135,9 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                }
 
                $updater->saveRevision( CommentStoreComment::newUnsavedComment( "testing" ) );
+               if ( !$updater->wasSuccessful() ) {
+                       $this->fail( $updater->getStatus()->getWikiText() );
+               }
 
                return $page;
        }
@@ -463,12 +466,13 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                );
                $logId = $status->getValue();
                $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+               $commentQuery = MediaWikiServices::getInstance()->getCommentStore()->getJoin( 'log_comment' );
                $this->assertSelect(
-                       [ 'logging' ] + $actorQuery['tables'], /* table */
+                       [ 'logging' ] + $actorQuery['tables'] + $commentQuery['tables'], /* table */
                        [
                                'log_type',
                                'log_action',
-                               'log_comment',
+                               'log_comment' => $commentQuery['fields']['log_comment_text'],
                                'log_user' => $actorQuery['fields']['log_user'],
                                'log_user_text' => $actorQuery['fields']['log_user_text'],
                                'log_namespace',
@@ -485,7 +489,7 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                $page->getTitle()->getDBkey(),
                        ] ],
                        [],
-                       $actorQuery['joins']
+                       $actorQuery['joins'] + $commentQuery['joins']
                );
        }
 
@@ -512,12 +516,13 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                );
                $logId = $status->getValue();
                $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+               $commentQuery = MediaWikiServices::getInstance()->getCommentStore()->getJoin( 'log_comment' );
                $this->assertSelect(
-                       [ 'logging' ] + $actorQuery['tables'], /* table */
+                       [ 'logging' ] + $actorQuery['tables'] + $commentQuery['tables'], /* table */
                        [
                                'log_type',
                                'log_action',
-                               'log_comment',
+                               'log_comment' => $commentQuery['fields']['log_comment_text'],
                                'log_user' => $actorQuery['fields']['log_user'],
                                'log_user_text' => $actorQuery['fields']['log_user_text'],
                                'log_namespace',
@@ -534,7 +539,7 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                $page->getTitle()->getDBkey(),
                        ] ],
                        [],
-                       $actorQuery['joins']
+                       $actorQuery['joins'] + $commentQuery['joins']
                );
        }
 
@@ -563,12 +568,13 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                );
                $logId = $status->getValue();
                $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+               $commentQuery = MediaWikiServices::getInstance()->getCommentStore()->getJoin( 'log_comment' );
                $this->assertSelect(
-                       [ 'logging' ] + $actorQuery['tables'], /* table */
+                       [ 'logging' ] + $actorQuery['tables'] + $commentQuery['tables'], /* table */
                        [
                                'log_type',
                                'log_action',
-                               'log_comment',
+                               'log_comment' => $commentQuery['fields']['log_comment_text'],
                                'log_user' => $actorQuery['fields']['log_user'],
                                'log_user_text' => $actorQuery['fields']['log_user_text'],
                                'log_namespace',
@@ -585,7 +591,7 @@ abstract class WikiPageDbTestBase extends MediaWikiLangTestCase {
                                $page->getTitle()->getDBkey(),
                        ] ],
                        [],
-                       $actorQuery['joins']
+                       $actorQuery['joins'] + $commentQuery['joins']
                );
 
                $this->assertNull(
@@ -2266,10 +2272,11 @@ more stuff
                // Make sure the log entry looks good
                // log_params is not checked here
                $actorQuery = ActorMigration::newMigration()->getJoin( 'log_user' );
+               $commentQuery = MediaWikiServices::getInstance()->getCommentStore()->getJoin( 'log_comment' );
                $this->assertSelect(
-                       [ 'logging' ] + $actorQuery['tables'],
+                       [ 'logging' ] + $actorQuery['tables'] + $commentQuery['tables'],
                        [
-                               'log_comment',
+                               'log_comment' => $commentQuery['fields']['log_comment_text'],
                                'log_user' => $actorQuery['fields']['log_user'],
                                'log_user_text' => $actorQuery['fields']['log_user_text'],
                                'log_namespace',
@@ -2284,7 +2291,7 @@ more stuff
                                $page->getTitle()->getDBkey(),
                        ] ],
                        [],
-                       $actorQuery['joins']
+                       $actorQuery['joins'] + $commentQuery['joins']
                );
        }
 
index 69d12e3..78c0ac3 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+
+use MediaWiki\MediaWikiServices;
 use MediaWiki\Tests\Revision\McrReadNewSchemaOverride;
 
 /**
@@ -24,6 +26,11 @@ class WikiPageMcrReadNewDbTest extends WikiPageDbTestBase {
                $m1 = $this->defineMockContentModelForUpdateTesting( 'M1' );
                $a1 = $this->defineMockContentModelForUpdateTesting( 'A1' );
 
+               MediaWikiServices::getInstance()->getSlotRoleRegistry()->defineRoleWithModel(
+                       'aux',
+                       $a1->getModelID()
+               );
+
                $mainContent1 = $this->createMockContent( $m1, 'main 1' );
                $auxContent1 = $this->createMockContent( $a1, 'aux 1' );
 
index 6ce01ca..58441f0 100644 (file)
@@ -124,9 +124,8 @@ class LocalIdLookupTest extends MediaWikiTestCase {
         * @param bool $localDBSet $wgLocalDatabases contains the shared DB
         */
        public function testIsAttachedShared( $sharedDB, $sharedTable, $localDBSet ) {
-               global $wgDBName;
                $this->setMwGlobals( [
-                       'wgSharedDB' => $sharedDB ? $wgDBName : null,
+                       'wgSharedDB' => $sharedDB ? "dummy" : null,
                        'wgSharedTables' => $sharedTable ? [ 'user' ] : [],
                        'wgLocalDatabases' => $localDBSet ? [ 'shared' ] : [],
                ] );
index f1c049b..b9289db 100644 (file)
@@ -1285,8 +1285,17 @@ class UserTest extends MediaWikiTestCase {
                                'pageRestrictions' => [ 'Test page' ],
                        ] ],
                        'Partial block, overriding allowUsertalk' => [ self::USER_TALK_PAGE, true, [
+                               'allowUsertalk' => false,
                                'pageRestrictions' => [ self::USER_TALK_PAGE ],
                        ] ],
+                       'Partial block, allowing user talk' => [ self::USER_TALK_PAGE, false, [
+                               'allowUsertalk' => true,
+                               'pageRestrictions' => [ 'Test page' ],
+                       ] ],
+                       'Partial block, not allowing user talk' => [ self::USER_TALK_PAGE, true, [
+                               'allowUsertalk' => false,
+                               'pageRestrictions' => [ 'Test page' ],
+                       ] ],
                ];
        }
 
diff --git a/tests/phpunit/maintenance/populateChangeTagDefTest.php b/tests/phpunit/maintenance/populateChangeTagDefTest.php
deleted file mode 100644 (file)
index 8a88f19..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-<?php
-
-namespace MediaWiki\Tests\Maintenance;
-
-use PopulateChangeTagDef;
-
-/**
- * @group Database
- * @covers PopulateChangeTagDef
- */
-class PopulateChangeTagDefTest extends MaintenanceBaseTestCase {
-
-       public function getMaintenanceClass() {
-               return PopulateChangeTagDef::class;
-       }
-
-       public function setUp() {
-               parent::setUp();
-               $this->tablesUsed = [ 'change_tag', 'change_tag_def', 'updatelog' ];
-
-               $this->cleanChangeTagTables();
-               $this->insertChangeTagData();
-       }
-
-       private function cleanChangeTagTables() {
-               wfGetDB( DB_MASTER )->delete( 'change_tag', '*' );
-               wfGetDB( DB_MASTER )->delete( 'change_tag_def', '*' );
-               wfGetDB( DB_MASTER )->delete( 'updatelog', '*' );
-       }
-
-       private function insertChangeTagData() {
-               $changeTags = [];
-
-               $changeTags[] = [
-                       'ct_rc_id' => 1234,
-                       'ct_tag' => 'One Tag',
-               ];
-
-               $changeTags[] = [
-                       'ct_rc_id' => 1235,
-                       'ct_tag' => 'Two Tags',
-               ];
-
-               $changeTags[] = [
-                       'ct_log_id' => 1236,
-                       'ct_tag' => 'Two Tags',
-               ];
-
-               $changeTags[] = [
-                       'ct_rev_id' => 1237,
-                       'ct_tag' => 'Three Tags',
-               ];
-
-               $changeTags[] = [
-                       'ct_rc_id' => 1238,
-                       'ct_tag' => 'Three Tags',
-               ];
-
-               $changeTags[] = [
-                       'ct_log_id' => 1239,
-                       'ct_tag' => 'Three Tags',
-               ];
-
-               wfGetDB( DB_MASTER )->insert( 'change_tag', $changeTags );
-       }
-
-       public function testRun() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $this->maintenance->loadWithArgv( [ '--sleep', '0' ] );
-
-               $this->maintenance->execute();
-
-               $changeTagDefRows = [
-                       (object)[
-                               'ctd_name' => 'One Tag',
-                               'ctd_count' => 1,
-                       ],
-                       (object)[
-                               'ctd_name' => 'Two Tags',
-                               'ctd_count' => 2,
-                       ],
-                       (object)[
-                               'ctd_name' => 'Three Tags',
-                               'ctd_count' => 3,
-                       ],
-               ];
-
-               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag_def' ],
-                       [ 'ctd_name', 'ctd_count' ],
-                       [],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'ctd_count' ]
-               );
-
-               $this->assertEquals( $changeTagDefRows, iterator_to_array( $actualChangeTagDefs, false ) );
-
-               // Check if change_tag is also backpopulated
-               $actualChangeTags = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag', 'change_tag_def' ],
-                       [ 'ct_tag', 'ct_tag_id', 'ctd_count' ],
-                       [],
-                       __METHOD__,
-                       [],
-                       [ 'change_tag_def' => [ 'LEFT JOIN', 'ct_tag_id=ctd_id' ] ]
-               );
-               $mapping = [
-                       'One Tag' => 1,
-                       'Two Tags' => 2,
-                       'Three Tags' => 3
-               ];
-               foreach ( $actualChangeTags as $row ) {
-                       $this->assertNotNull( $row->ct_tag_id );
-                       $this->assertEquals( $row->ctd_count, $mapping[$row->ct_tag] );
-               }
-       }
-
-       public function testRunUpdateHitCountMigrationNew() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
-               $changeTagDefBadRows = [
-                       [
-                               'ctd_name' => 'One Tag',
-                               'ctd_user_defined' => 0,
-                               'ctd_count' => 50,
-                       ],
-                       [
-                               'ctd_name' => 'Two Tags',
-                               'ctd_user_defined' => 0,
-                               'ctd_count' => 4,
-                       ],
-                       [
-                               'ctd_name' => 'Three Tags',
-                               'ctd_user_defined' => 0,
-                               'ctd_count' => 3,
-                       ],
-               ];
-               wfGetDB( DB_MASTER )->insert(
-                       'change_tag_def',
-                       $changeTagDefBadRows
-               );
-
-               $mapping = [
-                       'One Tag' => 1,
-                       'Two Tags' => 2,
-                       'Three Tags' => 3
-               ];
-               foreach ( $mapping as $tagName => $tagId ) {
-                       wfGetDB( DB_MASTER )->update(
-                               'change_tag',
-                               [ 'ct_tag_id' => $tagId ],
-                               [ 'ct_tag' => $tagName ]
-                       );
-               }
-
-               $this->maintenance->loadWithArgv( [ '--sleep', '0' ] );
-
-               $this->maintenance->execute();
-
-               $changeTagDefRows = [
-                       (object)[
-                               'ctd_name' => 'One Tag',
-                               'ctd_count' => 1,
-                       ],
-                       (object)[
-                               'ctd_name' => 'Two Tags',
-                               'ctd_count' => 2,
-                       ],
-                       (object)[
-                               'ctd_name' => 'Three Tags',
-                               'ctd_count' => 3,
-                       ],
-               ];
-
-               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag_def' ],
-                       [ 'ctd_name', 'ctd_count' ],
-                       [],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'ctd_count' ]
-               );
-
-               $this->assertEquals( $changeTagDefRows, iterator_to_array( $actualChangeTagDefs, false ) );
-       }
-
-       public function testRunUpdateHitCountMigrationWriteBoth() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $changeTagDefBadRows = [
-                       [
-                               'ctd_name' => 'One Tag',
-                               'ctd_user_defined' => 0,
-                               'ctd_count' => 50,
-                       ],
-                       [
-                               'ctd_name' => 'Two Tags',
-                               'ctd_user_defined' => 0,
-                               'ctd_count' => 4,
-                       ],
-                       [
-                               'ctd_name' => 'Three Tags',
-                               'ctd_user_defined' => 0,
-                               'ctd_count' => 3,
-                       ],
-               ];
-               wfGetDB( DB_MASTER )->insert(
-                       'change_tag_def',
-                       $changeTagDefBadRows
-               );
-
-               $this->maintenance->loadWithArgv( [ '--sleep', '0' ] );
-
-               $this->maintenance->execute();
-
-               $changeTagDefRows = [
-                       (object)[
-                               'ctd_name' => 'One Tag',
-                               'ctd_count' => 1,
-                       ],
-                       (object)[
-                               'ctd_name' => 'Two Tags',
-                               'ctd_count' => 2,
-                       ],
-                       (object)[
-                               'ctd_name' => 'Three Tags',
-                               'ctd_count' => 3,
-                       ],
-               ];
-
-               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag_def' ],
-                       [ 'ctd_name', 'ctd_count' ],
-                       [],
-                       __METHOD__,
-                       [ 'ORDER BY' => 'ctd_count' ]
-               );
-
-               $this->assertEquals( $changeTagDefRows, iterator_to_array( $actualChangeTagDefs, false ) );
-       }
-
-       public function testDryRunMigrationNew() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_NEW );
-               $this->maintenance->loadWithArgv( [ '--dry-run', '--sleep', '0' ] );
-
-               $this->maintenance->execute();
-
-               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag_def' ],
-                       [ 'ctd_id', 'ctd_name' ]
-               );
-
-               $this->assertEquals( [], iterator_to_array( $actualChangeTagDefs, false ) );
-
-               $actualChangeTags = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag' ],
-                       [ 'ct_tag_id', 'ct_tag' ]
-               );
-
-               foreach ( $actualChangeTags as $row ) {
-                       $this->assertNull( $row->ct_tag_id );
-                       $this->assertNotNull( $row->ct_tag );
-               }
-       }
-
-       public function testDryRunMigrationWriteBoth() {
-               $this->setMwGlobals( 'wgChangeTagsSchemaMigrationStage', MIGRATION_WRITE_BOTH );
-               $this->maintenance->loadWithArgv( [ '--dry-run', '--sleep', '0' ] );
-
-               $this->maintenance->execute();
-
-               $actualChangeTagDefs = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag_def' ],
-                       [ 'ctd_id', 'ctd_name' ]
-               );
-
-               $this->assertEquals( [], iterator_to_array( $actualChangeTagDefs, false ) );
-
-               $actualChangeTags = wfGetDB( DB_REPLICA )->select(
-                       [ 'change_tag' ],
-                       [ 'ct_tag_id', 'ct_tag' ]
-               );
-
-               foreach ( $actualChangeTags as $row ) {
-                       $this->assertNull( $row->ct_tag_id );
-                       $this->assertNotNull( $row->ct_tag );
-               }
-       }
-
-}
index acdf2f1..3f3cc2c 100644 (file)
                assert.strictEqual( title.getFragment(), null, 'getTalkPage does not copy the fragment' );
        } );
 
+       QUnit.test( 'wantSignaturesNamespace', function ( assert ) {
+               var namespaces = mw.config.values.wgExtraSignatureNamespaces;
+
+               mw.config.values.wgExtraSignatureNamespaces = [];
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 0 ), false, 'Main namespace has no signatures' );
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 1 ), true, 'Talk namespace has signatures' );
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 2 ), false, 'NS2 has no signatures' );
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 3 ), true, 'NS3 has signatures' );
+
+               mw.config.values.wgExtraSignatureNamespaces = [ 0 ];
+               assert.strictEqual( mw.Title.wantSignaturesNamespace( 0 ), true, 'Main namespace has signatures when explicitly defined' );
+
+               // Restore
+               mw.config.values.wgExtraSignatureNamespaces = namespaces;
+       } );
+
        QUnit.test( 'Throw error on invalid title', function ( assert ) {
                assert.throws( function () {
                        return new mw.Title( '' );
index 347614c..1118279 100644 (file)
                        assert.strictEqual( siteFromUser, 1, 'site ran before user' );
                } ).always( function () {
                        // Reset
-                       mw.loader.moduleRegistry[ 'site' ].state = 'registered';
-                       mw.loader.moduleRegistry[ 'user' ].state = 'registered';
+                       mw.loader.moduleRegistry.site.state = 'registered';
+                       mw.loader.moduleRegistry.user.state = 'registered';
                } );
        } );