Merge "Set relevant title on Special:RecentChangesLinked"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 15 Aug 2014 20:26:17 +0000 (20:26 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 15 Aug 2014 20:26:17 +0000 (20:26 +0000)
256 files changed:
RELEASE-NOTES-1.24
docs/hooks.txt
extensions/README
includes/Block.php
includes/Category.php
includes/DefaultSettings.php
includes/EditPage.php
includes/Feed.php
includes/ForkController.php
includes/FormOptions.php
includes/Linker.php
includes/OutputPage.php
includes/Setup.php
includes/User.php
includes/UserMailer.php
includes/WebResponse.php
includes/actions/CreditsAction.php
includes/actions/HistoryAction.php
includes/actions/InfoAction.php
includes/actions/RawAction.php
includes/api/ApiBase.php
includes/api/ApiDelete.php
includes/api/ApiEditPage.php
includes/api/ApiExpandTemplates.php
includes/api/ApiFormatBase.php
includes/api/ApiFormatDbg.php
includes/api/ApiFormatDump.php
includes/api/ApiFormatTxt.php
includes/api/ApiFormatWddx.php
includes/api/ApiFormatYaml.php
includes/api/ApiHelp.php
includes/api/ApiModuleManager.php
includes/api/ApiMove.php
includes/api/ApiPageSet.php
includes/api/ApiProtect.php
includes/api/ApiQueryLangLinks.php
includes/api/ApiQuerySearch.php
includes/api/ApiQuerySiteinfo.php
includes/api/ApiQueryStashImageInfo.php
includes/api/ApiQueryUserContributions.php
includes/api/ApiResult.php
includes/api/ApiUpload.php
includes/api/ApiWatch.php
includes/cache/LocalisationCache.php
includes/changes/RecentChange.php
includes/content/JSONContent.php
includes/content/JSONContentHandler.php
includes/context/RequestContext.php
includes/db/DatabaseMssql.php
includes/db/DatabasePostgres.php
includes/db/DatabaseUtility.php
includes/deferred/SearchUpdate.php
includes/diff/DifferenceEngine.php
includes/exception/MWException.php
includes/filebackend/FileBackend.php
includes/filebackend/SwiftFileBackend.php
includes/filerepo/FileRepo.php
includes/filerepo/LocalRepo.php
includes/filerepo/RepoGroup.php
includes/filerepo/file/File.php
includes/filerepo/file/LocalFile.php
includes/gallery/ImageGalleryBase.php
includes/gallery/PackedImageGallery.php
includes/htmlform/HTMLEditTools.php
includes/htmlform/HTMLHiddenField.php
includes/htmlform/HTMLInfoField.php
includes/installer/DatabaseUpdater.php
includes/installer/MssqlInstaller.php
includes/installer/i18n/haw.json
includes/installer/i18n/pl.json
includes/installer/i18n/zh-hant.json
includes/libs/MultiHttpClient.php
includes/media/BitmapMetadataHandler.php
includes/media/Exif.php
includes/media/MediaHandler.php
includes/media/SVG.php
includes/media/XCF.php
includes/objectcache/MemcachedBagOStuff.php
includes/objectcache/RedisBagOStuff.php
includes/objectcache/SqlBagOStuff.php
includes/objectcache/WinCacheBagOStuff.php
includes/page/Article.php
includes/page/WikiPage.php
includes/parser/ParserOptions.php
includes/parser/ParserOutput.php
includes/poolcounter/PoolCounterWork.php
includes/poolcounter/PoolWorkArticleView.php
includes/profiler/ProfilerSimpleUDP.php
includes/profiler/ProfilerStandard.php
includes/rcfeed/RCFeedEngine.php
includes/resourceloader/ResourceLoader.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/resourceloader/ResourceLoaderModule.php
includes/resourceloader/ResourceLoaderStartUpModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/revisiondelete/RevisionDeleteAbstracts.php
includes/revisiondelete/RevisionDeleter.php
includes/search/SearchEngine.php
includes/search/SearchHighlighter.php
includes/search/SearchMssql.php
includes/search/SearchMySQL.php
includes/search/SearchOracle.php
includes/search/SearchSqlite.php
includes/skins/Skin.php
includes/skins/SkinFactory.php
includes/skins/SkinFallback.php
includes/skins/SkinFallbackTemplate.php
includes/skins/SkinTemplate.php
includes/specials/SpecialActiveusers.php
includes/specials/SpecialChangePassword.php
includes/specials/SpecialContributions.php
includes/specials/SpecialExpandTemplates.php
includes/specials/SpecialImport.php
includes/specials/SpecialListgrouprights.php
includes/specials/SpecialRedirect.php
includes/specials/SpecialResetTokens.php
includes/specials/SpecialRevisiondelete.php
includes/specials/SpecialSearch.php
includes/specials/SpecialUnwatchedpages.php
includes/specials/SpecialUserlogin.php
includes/specials/SpecialVersion.php
includes/templates/Usercreate.php
includes/templates/Userlogin.php
includes/upload/UploadBase.php
includes/upload/UploadFromChunks.php
includes/utils/MWCryptHKDF.php
includes/utils/UIDGenerator.php
languages/Language.php
languages/i18n/bcc.json
languages/i18n/be-tarask.json
languages/i18n/be.json
languages/i18n/bn.json
languages/i18n/br.json
languages/i18n/es.json
languages/i18n/fi.json
languages/i18n/haw.json
languages/i18n/hi.json
languages/i18n/hsb.json
languages/i18n/it.json
languages/i18n/lb.json
languages/i18n/lrc.json
languages/i18n/lzh.json
languages/i18n/ms.json
languages/i18n/mzn.json
languages/i18n/ro.json
languages/i18n/sl.json
languages/i18n/sr-ec.json
languages/i18n/sr-el.json
languages/i18n/sv.json
languages/i18n/yi.json
languages/i18n/zh-hant.json
languages/utils/CLDRPluralRuleConverter.php
maintenance/cleanupTitles.php
maintenance/namespaceDupes.php
maintenance/populateBacklinkNamespace.php
resources/Resources.php
resources/lib/moment/lang/af.js [new file with mode: 0644]
resources/lib/moment/lang/ar-ma.js
resources/lib/moment/lang/ar-sa.js
resources/lib/moment/lang/ar.js
resources/lib/moment/lang/az.js
resources/lib/moment/lang/be.js [new file with mode: 0644]
resources/lib/moment/lang/bg.js
resources/lib/moment/lang/bn.js
resources/lib/moment/lang/bo.js [new file with mode: 0644]
resources/lib/moment/lang/br.js
resources/lib/moment/lang/bs.js
resources/lib/moment/lang/ca.js
resources/lib/moment/lang/cs.js
resources/lib/moment/lang/cv.js
resources/lib/moment/lang/cy.js
resources/lib/moment/lang/da.js
resources/lib/moment/lang/de-at.js
resources/lib/moment/lang/de.js
resources/lib/moment/lang/el.js
resources/lib/moment/lang/en-au.js
resources/lib/moment/lang/en-ca.js
resources/lib/moment/lang/en-gb.js
resources/lib/moment/lang/eo.js
resources/lib/moment/lang/es.js
resources/lib/moment/lang/et.js
resources/lib/moment/lang/eu.js
resources/lib/moment/lang/fa.js
resources/lib/moment/lang/fi.js
resources/lib/moment/lang/fo.js
resources/lib/moment/lang/fr-ca.js
resources/lib/moment/lang/fr.js
resources/lib/moment/lang/gl.js
resources/lib/moment/lang/he.js
resources/lib/moment/lang/hi.js
resources/lib/moment/lang/hr.js
resources/lib/moment/lang/hu.js
resources/lib/moment/lang/hy-am.js
resources/lib/moment/lang/id.js
resources/lib/moment/lang/is.js
resources/lib/moment/lang/it.js
resources/lib/moment/lang/ja.js
resources/lib/moment/lang/ka.js
resources/lib/moment/lang/km.js
resources/lib/moment/lang/ko.js
resources/lib/moment/lang/lb.js
resources/lib/moment/lang/lt.js
resources/lib/moment/lang/lv.js
resources/lib/moment/lang/mk.js
resources/lib/moment/lang/ml.js
resources/lib/moment/lang/mr.js
resources/lib/moment/lang/ms-my.js
resources/lib/moment/lang/my.js [new file with mode: 0644]
resources/lib/moment/lang/nb.js
resources/lib/moment/lang/ne.js
resources/lib/moment/lang/nl.js
resources/lib/moment/lang/nn.js
resources/lib/moment/lang/pl.js
resources/lib/moment/lang/pt-br.js
resources/lib/moment/lang/pt.js
resources/lib/moment/lang/ro.js
resources/lib/moment/lang/ru.js
resources/lib/moment/lang/sk.js
resources/lib/moment/lang/sl.js
resources/lib/moment/lang/sq.js
resources/lib/moment/lang/sr-cyrl.js
resources/lib/moment/lang/sr.js
resources/lib/moment/lang/sv.js
resources/lib/moment/lang/ta.js
resources/lib/moment/lang/th.js
resources/lib/moment/lang/tl-ph.js
resources/lib/moment/lang/tr.js
resources/lib/moment/lang/tzm-latn.js
resources/lib/moment/lang/tzm.js
resources/lib/moment/lang/uk.js
resources/lib/moment/lang/uz.js
resources/lib/moment/lang/vi.js
resources/lib/moment/lang/zh-cn.js
resources/lib/moment/lang/zh-tw.js
resources/lib/moment/moment.js
resources/src/jquery/jquery.tablesorter.js
resources/src/mediawiki/mediawiki.notify.js
skins/README [new file with mode: 0644]
tests/TestsAutoLoader.php
tests/parser/parserTest.inc
tests/parser/parserTests.txt
tests/phpunit/includes/ImagePageTest.php
tests/phpunit/includes/api/ApiModuleManagerTest.php
tests/phpunit/includes/api/ApiTestCase.php
tests/phpunit/includes/api/query/ApiQueryContinueTestBase.php
tests/phpunit/includes/api/query/ApiQueryTest.php
tests/phpunit/includes/content/JSONContentTest.php
tests/phpunit/includes/media/XCFTest.php
tests/phpunit/includes/parser/NewParserTest.php
tests/phpunit/includes/resourceloader/ResourceLoaderModuleTest.php
tests/phpunit/includes/skins/SkinFactoryTest.php
tests/phpunit/maintenance/DumpTestCase.php
tests/phpunit/maintenance/fetchTextTest.php
tests/qunit/suites/resources/jquery/jquery.tablesorter.test.js
tests/testHelpers.inc
thumb.php

index fb260e1..30d59ba 100644 (file)
@@ -48,6 +48,15 @@ production.
 * $wgSortSpecialPages was removed, the listing on Special:SpecialPages is
   now always sorted.
 * Users must be able to edit a page to be able to delete it.
+* $wgHTCPMulticastAddress, $wgHTCPMulticastRouting and $wgHTCPPort were removed.
+* $wgRC2UDPAddress, $wgRC2UDPInterwikiPrefix, $wgRC2UDPOmitBots, $wgRC2UDPPort
+  and $wgRC2UDPPrefix have been removed.
+* The default password type for MediaWiki has been changed from MD5 to PBKDF2.
+  Password hashes will automatically be updated as users log in. If necessary, the
+  old MD5 hashing can be restored by changing $wgPasswordDefault to 'B'. In addition,
+  there is a maintenance script wrapOldPassword.php that can wrap all passwords in
+  PBKDF2 (or the hashing algorithm of your choice) if you don't want to wait for your
+  users to log in.
 
 === New features in 1.24 ===
 * Added a new hook, "WhatLinksHereProps", to allow extensions to annotate
@@ -122,7 +131,7 @@ production.
   Special:PageLanguage. All pages are set to wiki language by default.
   The feature needs to be enabled with $wgPageLanguageUseDB=true and
   permission needs to be set for 'pagelang'.
-* Upgrade Moment.js to v2.7.0.
+* Upgrade Moment.js to v2.8.1.
 * (bug 67042) Added support for the HTML5 <rtc> tag for East Asian typography.
 * Upgrade Sinon.JS to 1.10.3.
 * Added the es5-shim polyfill for older or non-compliant javascript engines.
@@ -219,6 +228,7 @@ production.
   limited use and are generally inaccurate, unmaintained, and impossible to
   properly maintain. Also removed the corresponding methods from ApiBase and
   the 'APIGetPossibleErrors' and 'APIGetResultProperties' hooks.
+* Formats dbg, dump, txt, wddx, and yaml are now deprecated.
 
 === Languages updated in 1.24 ===
 
@@ -239,10 +249,12 @@ changes to languages because of Bugzilla reports.
 * Added pp_sortkey column to page_props table, so pages can be efficiently
   queried and sorted by property value (bug 58032).
   See $wgPagePropsHaveSortkey if you want to postpone the schema change.
-* BREAKING CHANGE: The Modern and Cologne Blue skins were moved out of MediaWiki
-  core to their own respective repositories. See also
-  https://www.mediawiki.org/wiki/Skin:Modern and
-  https://www.mediawiki.org/wiki/Skin:CologneBlue.
+* BREAKING CHANGE: All four built-in MediaWiki skins (Vector, MonoBook, Modern
+  and Cologne Blue) were moved out of MediaWiki core to their own respective
+  repositories. They will be installed with the release tarball, but you must
+  install them separately if installing MediaWiki from source code. A warning
+  message displayed until you do it should guide you through the process. See
+  also <https://www.mediawiki.org/wiki/Manual:Skin_configuration>.
 * BREAKING CHANGE: Skins built for MediaWiki 1.15 and earlier that do not use
   the "headelement" template key are no longer supported. Setting
   $useHeadElement = false; is no longer supported and will not cause old keys
@@ -319,6 +331,8 @@ changes to languages because of Bugzilla reports.
   existed purely to provide support for MSIE versions below 7 and which was
   conditionally loaded for those browsers, was also removed.
 * Action::checkCanExecute() no longer has a return value.
+* Removed cleanupForIRC(), loadFromCurRow(), newFromCurRow(), notifyRC2UDP()
+  and sendToUDP() from RecentChange.php. (deprecated since 1.22)
 
 ==== Renamed classes ====
 * CLDRPluralRuleConverter_Expression to CLDRPluralRuleConverterExpression
index 31590ae..fc29858 100644 (file)
@@ -2368,7 +2368,7 @@ $sp: SpecialPage object, for context
 &$fields: Current HTMLForm fields
 
 'SpecialContributionsBeforeMainOutput': Before the form on Special:Contributions
-$id: User id number, only provided for backwards-compatability
+$id: User id number, only provided for backwards-compatibility
 $user: User object representing user contributions are being fetched for
 $sp: SpecialPage instance, providing context
 
index b665001..bad230e 100644 (file)
@@ -1,23 +1,19 @@
-Extensions (such as the hieroglyphic module WikiHiero) are distributed
-separately. Drop them into this extensions directory and enable as
-per the extension's directions.
+Extensions are distributed separately. Drop them into this directory and enable
+as per the extension's installation instructions.
 
-You can find a list of extensions and documentation on the MediaWiki website:
-    https://www.mediawiki.org/wiki/Category:Extensions
+You can find a list of extensions and documentation at
+<https://www.mediawiki.org/wiki/Category:Extensions>.
 
 
-If you are a developer, you want to fetch the extension tree in another
+If you are a developer, you might want to fetch the extension tree in another
 directory and make a symbolic link:
 
- mediawiki/extensions$ ln -s ../../extensions-trunk/FooBarExt
+ mediawiki/extensions$ ln -s ../../extensions-trunk/FooBar
 
 Most extensions are available through Git:
-    https://gerrit.wikimedia.org/r/#/admin/projects/
+    https://gerrit.wikimedia.org/r/#/admin/projects/?filter=mediawiki%252Fextensions%252F
     https://git.wikimedia.org/project/mediawiki
 
-Old extensions are on Subversion:
-    https://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions/
-
 
 Please note that under POSIX systems (Linux...), parent of a symbolic path
 refers to the link source, NOT to the target! You should check the env
index 45bae28..5881353 100644 (file)
@@ -1105,11 +1105,11 @@ class Block {
         *  - If there are multiple exact or range blocks at the same level, the one chosen
         *    is random
         *
+        * @param array $blocks Array of blocks
         * @param array $ipChain List of IPs (strings). This is used to determine how "close"
         *        a block is to the server, and if a block matches exactly, or is in a range.
         *        The order is furthest from the server to nearest e.g., (Browser, proxy1, proxy2,
         *        local-squid, ...)
-        * @param array $block Array of blocks
         * @return Block|null The "best" block from the list
         */
        public static function chooseBlock( array $blocks, array $ipChain ) {
index 7bab464..322b053 100644 (file)
@@ -291,6 +291,7 @@ class Category {
 
        /**
         * Generic accessor
+        * @param string $key
         * @return bool
         */
        private function getX( $key ) {
index 80b8e52..304a75f 100644 (file)
@@ -2447,42 +2447,6 @@ $wgSquidPurgeUseHostHeader = true;
  */
 $wgHTCPRouting = array();
 
-/**
- * @deprecated since 1.22, please use $wgHTCPRouting instead.
- *
- * Whenever this is set and $wgHTCPRouting evaluates to false, $wgHTCPRouting
- * will be set to this value.
- * This is merely for back compatibility.
- *
- * @since 1.20
- */
-$wgHTCPMulticastRouting = null;
-
-/**
- * HTCP multicast address. Set this to a multicast IP address to enable HTCP.
- *
- * Note that MediaWiki uses the old non-RFC compliant HTCP format, which was
- * present in the earliest Squid implementations of the protocol.
- *
- * This setting is DEPRECATED in favor of $wgHTCPRouting , and kept for
- * backwards compatibility only. If $wgHTCPRouting is set, this setting is
- * ignored. If $wgHTCPRouting is not set and this setting is, it is used to
- * populate $wgHTCPRouting.
- *
- * @deprecated since 1.20 in favor of $wgHTCPMulticastRouting and since 1.22 in
- * favor of $wgHTCPRouting.
- */
-$wgHTCPMulticastAddress = false;
-
-/**
- * HTCP multicast port.
- * @deprecated since 1.20 in favor of $wgHTCPMulticastRouting and since 1.22 in
- * favor of $wgHTCPRouting.
- *
- * @see $wgHTCPMulticastAddress
- */
-$wgHTCPPort = 4827;
-
 /**
  * HTCP multicast TTL.
  * @see $wgHTCPRouting
@@ -4134,7 +4098,7 @@ $wgInvalidPasswordReset = true;
  *
  * @since 1.24
  */
-$wgPasswordDefault = 'B';
+$wgPasswordDefault = 'pbkdf2';
 
 /**
  * Configuration for built-in password types. Maps the password type
@@ -5311,9 +5275,9 @@ $wgUDPProfilerPort = '3811';
 
 /**
  * Format string for the UDP profiler. The UDP profiler invokes sprintf() with
- * (profile id, count, cpu, cpu_sq, real, real_sq, entry name) as arguments.
- * You can use sprintf's argument numbering/swapping capability to repeat,
- * re-order or omit fields.
+ * (profile id, count, cpu, cpu_sq, real, real_sq, entry name, memory) as
+ * arguments. You can use sprintf's argument numbering/swapping capability to
+ * repeat, re-order or omit fields.
  *
  * @see $wgStatsFormatString
  * @since 1.22
@@ -5717,48 +5681,6 @@ $wgRCLinkLimits = array( 50, 100, 250, 500 );
  */
 $wgRCLinkDays = array( 1, 3, 7, 14, 30 );
 
-/**
- * Send recent changes updates via UDP. The updates will be formatted for IRC.
- * Set this to the IP address of the receiver.
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPAddress = false;
-
-/**
- * Port number for RC updates
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPPort = false;
-
-/**
- * Prefix to prepend to each UDP packet.
- * This can be used to identify the wiki. A script is available called
- * mxircecho.py which listens on a UDP port, and uses a prefix ending in a
- * tab to identify the IRC channel to send the log line to.
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPPrefix = '';
-
-/**
- * If this is set to true, the first entry in the $wgLocalInterwikis array (or
- * the value of $wgLocalInterwiki, if set) will be prepended to links in the IRC
- * feed. If this is set to a string, that string will be used as the prefix.
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPInterwikiPrefix = false;
-
-/**
- * Set to true to omit "bot" edits (by users with the bot permission) from the
- * UDP feed.
- *
- * @deprecated since 1.22, use $wgRCFeeds
- */
-$wgRC2UDPOmitBots = false;
-
 /**
  * Destinations to which notifications about recent changes
  * should be sent.
@@ -5786,9 +5708,6 @@ $wgRC2UDPOmitBots = false;
  *  The JSON-specific options are:
  *   * 'channel' -- if set, the 'channel' parameter is also set in JSON values.
  *
- *  To ensure backwards-compatibility, whenever $wgRC2UDPAddress is set, a
- *  'default' feed will be created reusing the deprecated $wgRC2UDP* variables.
- *
  * @example $wgRCFeeds['example'] = array(
  *             'formatter' => 'JSONRCFeedFormatter',
  *             'uri' => "udp://localhost:1336",
@@ -7311,7 +7230,7 @@ $wgPageLanguageUseDB = false;
  * @var bool
  * @since 1.24
  */
-$wgUseLinkNamespaceDBFields = false;
+$wgUseLinkNamespaceDBFields = true;
 
 /**
  * For really cool vim folding this needs to be at the end:
index dafbbe3..f97e3f8 100644 (file)
@@ -1468,9 +1468,8 @@ class EditPage {
                        $cleanSummary = $wgParser->stripSectionName( $this->summary );
                        return wfMessage( 'newsectionsummary' )
                                ->rawParams( $cleanSummary )->inContentLanguage()->text();
-               } else {
-                       return $this->summary;
                }
+               return $this->summary;
        }
 
        /**
index 58f3ebd..60e623b 100644 (file)
@@ -348,6 +348,7 @@ class RSSFeed extends ChannelFeed {
 class AtomFeed extends ChannelFeed {
        /**
         * @todo document
+        * @param string|int $ts
         * @return string
         */
        function formatTime( $ts ) {
index 0582230..c1765e2 100644 (file)
@@ -160,6 +160,7 @@ class ForkController {
        /**
         * Fork a number of worker processes.
         *
+        * @param int $numProcs
         * @return string
         */
        protected function forkWorkers( $numProcs ) {
index 079267a..c91c336 100644 (file)
@@ -375,6 +375,7 @@ class FormOptions implements ArrayAccess {
        /* @{ */
        /**
         * Whether the option exists.
+        * @param string $name
         * @return bool
         */
        public function offsetExists( $name ) {
@@ -383,6 +384,7 @@ class FormOptions implements ArrayAccess {
 
        /**
         * Retrieve an option value.
+        * @param string $name
         * @return mixed
         */
        public function offsetGet( $name ) {
@@ -391,6 +393,8 @@ class FormOptions implements ArrayAccess {
 
        /**
         * Set an option to given value.
+        * @param string $name
+        * @param mixed $value
         */
        public function offsetSet( $name, $value ) {
                $this->setValue( $name, $value );
@@ -398,6 +402,7 @@ class FormOptions implements ArrayAccess {
 
        /**
         * Delete the option.
+        * @param string $name
         */
        public function offsetUnset( $name ) {
                $this->delete( $name );
index 9f578a9..abc9404 100644 (file)
@@ -702,6 +702,7 @@ class Linker {
         * frame parameters supplied by the Parser.
         * @param array $frameParams The frame parameters
         * @param string $query An optional query string to add to description page links
+        * @param Parser|null $parser
         * @return array
         */
        private static function getImageLinkMTOParams( $frameParams, $query = '', $parser = null ) {
index cb25036..6ea4953 100644 (file)
@@ -311,6 +311,7 @@ class OutputPage extends ContextSource {
         * Constructor for OutputPage. This should not be called directly.
         * Instead a new RequestContext should be created and it will implicitly create
         * a OutputPage tied to that context.
+        * @param IContextSource|null $context
         */
        function __construct( IContextSource $context = null ) {
                if ( $context === null ) {
@@ -388,6 +389,7 @@ class OutputPage extends ContextSource {
        /**
         * Set the URL to be used for the <link rel=canonical>. This should be used
         * in preference to addLink(), to avoid duplicate link tags.
+        * @param string $url
         */
        function setCanonicalUrl( $url ) {
                $this->mCanonicalUrl = $url;
index 935fa15..8574105 100644 (file)
@@ -263,8 +263,21 @@ if ( $wgSkipSkin ) {
        $wgSkipSkins[] = $wgSkipSkin;
 }
 
-// Register a hidden "fallback" skin
-$wgValidSkinNames['fallback'] = 'Fallback'; // SkinFallback
+// Register skins
+// Use a closure to avoid leaking into global state
+call_user_func( function() use ( $wgValidSkinNames ) {
+       $factory = SkinFactory::getDefaultInstance();
+       foreach ( $wgValidSkinNames as $name => $skin ) {
+               $factory->register( $name, $skin, function() use ( $name, $skin ) {
+                       $class = "Skin$skin";
+                       return new $class( $name );
+               } );
+       }
+       // Register a hidden "fallback" skin
+       $factory->register( 'fallback', 'Fallback', function() {
+               return new SkinFallback;
+       } );
+} );
 $wgSkipSkins[] = 'fallback';
 
 if ( $wgLocalInterwiki ) {
@@ -392,15 +405,6 @@ if ( $wgCookieSecure === 'detect' ) {
        $wgCookieSecure = ( WebRequest::detectProtocol() === 'https' );
 }
 
-if ( $wgRC2UDPAddress ) {
-       $wgRCFeeds['default'] = array(
-               'formatter' => 'IRCColourfulRCFeedFormatter',
-               'uri' => "udp://$wgRC2UDPAddress:$wgRC2UDPPort/$wgRC2UDPPrefix",
-               'add_interwiki_prefix' => &$wgRC2UDPInterwikiPrefix,
-               'omit_bots' => &$wgRC2UDPOmitBots,
-       );
-}
-
 wfProfileOut( $fname . '-defaults' );
 
 // Disable MWDebug for command line mode, this prevents MWDebug from eating up
@@ -465,23 +469,6 @@ if ( $wgTmpDirectory === false ) {
        wfProfileOut( $fname . '-tempDir' );
 }
 
-// $wgHTCPMulticastRouting got renamed to $wgHTCPRouting in MediaWiki 1.22
-// ensure back compatibility.
-if ( !$wgHTCPRouting && $wgHTCPMulticastRouting ) {
-       $wgHTCPRouting = $wgHTCPMulticastRouting;
-}
-
-// Initialize $wgHTCPRouting from backwards-compatible settings that
-// comes from pre 1.20 version.
-if ( !$wgHTCPRouting && $wgHTCPMulticastAddress ) {
-       $wgHTCPRouting = array(
-               '' => array(
-                       'host' => $wgHTCPMulticastAddress,
-                       'port' => $wgHTCPPort,
-               )
-       );
-}
-
 // Back compatibility for $wgRateLimitLog deprecated with 1.23
 if ( $wgRateLimitLog && !array_key_exists( 'ratelimit', $wgDebugLogGroups ) ) {
        $wgDebugLogGroups['ratelimit'] = $wgRateLimitLog;
@@ -554,15 +541,15 @@ wfRunHooks( 'SetupAfterCache' );
 
 wfProfileIn( $fname . '-session' );
 
-// If session.auto_start is there, we can't touch session name
-if ( !wfIniGetBool( 'session.auto_start' ) ) {
-       session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' );
-}
+if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
+       // If session.auto_start is there, we can't touch session name
+       if ( !wfIniGetBool( 'session.auto_start' ) ) {
+               session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' );
+       }
 
-if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode &&
-       ( $wgRequest->checkSessionCookie() || isset( $_COOKIE[$wgCookiePrefix . 'Token'] ) )
-) {
-       wfSetupSession();
+       if ( $wgRequest->checkSessionCookie() || isset( $_COOKIE[$wgCookiePrefix . 'Token'] ) ) {
+               wfSetupSession();
+       }
 }
 
 wfProfileOut( $fname . '-session' );
index fe41187..7e846ad 100644 (file)
@@ -2733,7 +2733,7 @@ class User implements IDBAccessObject {
 
                                foreach ( $columns as $column ) {
                                        foreach ( $rows as $row ) {
-                                               $checkmatrixOptions["$prefix-$column-$row"] = true;
+                                               $checkmatrixOptions["$prefix$column-$row"] = true;
                                        }
                                }
 
index 913b430..0ce9b5a 100644 (file)
@@ -448,6 +448,8 @@ class UserMailer {
         * This method is doing Q encoding inside encoded-words as defined by RFC 2047
         * This is for email headers.
         * The built in quoted_printable_encode() is for email bodies
+        * @param string $string
+        * @param string $charset
         * @return string
         */
        public static function quotedPrintable( $string, $charset = '' ) {
index adccf9c..ad9f4e6 100644 (file)
@@ -51,7 +51,7 @@ class WebResponse {
         *     secure: bool, secure attribute ($wgCookieSecure)
         *     httpOnly: bool, httpOnly attribute ($wgCookieHttpOnly)
         *     raw: bool, if true uses PHP's setrawcookie() instead of setcookie()
-        *   For backwards compatability, if $options is not an array then it and
+        *   For backwards compatibility, if $options is not an array then it and
         *   the following two parameters will be interpreted as values for
         *   'prefix', 'domain', and 'secure'
         * @since 1.22 Replaced $prefix, $domain, and $forceSecure with $options
@@ -61,7 +61,7 @@ class WebResponse {
                global $wgCookieSecure, $wgCookieExpiration, $wgCookieHttpOnly;
 
                if ( !is_array( $options ) ) {
-                       // Backwards compatability
+                       // Backwards compatibility
                        $options = array( 'prefix' => $options );
                        if ( func_num_args() >= 5 ) {
                                $options['domain'] = func_get_arg( 4 );
index dd5195d..e064aab 100644 (file)
@@ -100,6 +100,17 @@ class CreditsAction extends FormlessAction {
                        $this->userLink( $user ) )->params( $user->getName() )->escaped();
        }
 
+       /**
+        * Whether we can display the user's real name (not a hidden pref)
+        *
+        * @since 1.24
+        * @return bool
+        */
+       protected function canShowRealUserName() {
+               $hiddenPrefs = $this->context->getConfig()->get( 'HiddenPrefs' );
+               return !in_array( 'realname', $hiddenPrefs );
+       }
+
        /**
         * Get a list of contributors of $article
         * @param int $cnt Maximum list of contributors to show
@@ -107,8 +118,6 @@ class CreditsAction extends FormlessAction {
         * @return string Html
         */
        protected function getContributors( $cnt, $showIfMax ) {
-               global $wgHiddenPrefs;
-
                $contributors = $this->page->getContributors();
 
                $others_link = false;
@@ -132,7 +141,7 @@ class CreditsAction extends FormlessAction {
                        $cnt--;
                        if ( $user->isLoggedIn() ) {
                                $link = $this->link( $user );
-                               if ( !in_array( 'realname', $wgHiddenPrefs ) && $user->getRealName() ) {
+                               if ( $this->canShowRealUserName() && $user->getRealName() ) {
                                        $real_names[] = $link;
                                } else {
                                        $user_names[] = $link;
@@ -192,8 +201,7 @@ class CreditsAction extends FormlessAction {
         * @return string Html
         */
        protected function link( User $user ) {
-               global $wgHiddenPrefs;
-               if ( !in_array( 'realname', $wgHiddenPrefs ) && !$user->isAnon() ) {
+               if ( $this->canShowRealUserName() && !$user->isAnon() ) {
                        $real = $user->getRealName();
                } else {
                        $real = false;
@@ -216,8 +224,7 @@ class CreditsAction extends FormlessAction {
                if ( $user->isAnon() ) {
                        return $this->msg( 'anonuser' )->rawParams( $link )->parse();
                } else {
-                       global $wgHiddenPrefs;
-                       if ( !in_array( 'realname', $wgHiddenPrefs ) && $user->getRealName() ) {
+                       if ( $this->canShowRealUserName() && $user->getRealName() ) {
                                return $link;
                        } else {
                                return $this->msg( 'siteuser' )->rawParams( $link )->params( $user->getName() )->escaped();
index 4992313..7ca8f3a 100644 (file)
@@ -92,8 +92,6 @@ class HistoryAction extends FormlessAction {
         * Print the history page for an article.
         */
        function onView() {
-               global $wgScript, $wgUseFileCache;
-
                $out = $this->getOutput();
                $request = $this->getRequest();
 
@@ -109,7 +107,8 @@ class HistoryAction extends FormlessAction {
                $this->preCacheMessages();
 
                # Fill in the file cache if not set already
-               if ( $wgUseFileCache && HTMLFileCache::useFileCache( $this->getContext() ) ) {
+               $useFileCache = $this->context->getConfig()->get( 'UseFileCache' );
+               if ( $useFileCache && HTMLFileCache::useFileCache( $this->getContext() ) ) {
                        $cache = HTMLFileCache::newFromTitle( $this->getTitle(), 'history' );
                        if ( !$cache->isCacheGood( /* Assume up to date */ ) ) {
                                ob_start( array( &$cache, 'saveToFileCache' ) );
@@ -173,7 +172,7 @@ class HistoryAction extends FormlessAction {
                }
 
                // Add the general form
-               $action = htmlspecialchars( $wgScript );
+               $action = htmlspecialchars( wfScript() );
                $out->addHTML(
                        "<form action=\"$action\" method=\"get\" id=\"mw-history-searchform\">" .
                        Xml::fieldset(
@@ -254,14 +253,14 @@ class HistoryAction extends FormlessAction {
         * @param string $type Feed type
         */
        function feed( $type ) {
-               global $wgFeedClasses, $wgFeedLimit;
                if ( !FeedUtils::checkFeedOutput( $type ) ) {
                        return;
                }
                $request = $this->getRequest();
 
+               $feedClasses = $this->context->getConfig()->get( 'FeedClasses' );
                /** @var RSSFeed|AtomFeed $feed */
-               $feed = new $wgFeedClasses[$type](
+               $feed = new $feedClasses[$type](
                        $this->getTitle()->getPrefixedText() . ' - ' .
                        $this->msg( 'history-feed-title' )->inContentLanguage()->text(),
                        $this->msg( 'history-feed-description' )->inContentLanguage()->text(),
@@ -271,7 +270,10 @@ class HistoryAction extends FormlessAction {
                // Get a limit on number of feed entries. Provide a sane default
                // of 10 if none is defined (but limit to $wgFeedLimit max)
                $limit = $request->getInt( 'limit', 10 );
-               $limit = min( max( $limit, 1 ), $wgFeedLimit );
+               $limit = min(
+                       max( $limit, 1 ),
+                       $this->context->getConfig()->get( 'FeedLimit' )
+               );
 
                $items = $this->fetchRevisions( $limit, 0, self::DIR_NEXT );
 
@@ -462,13 +464,12 @@ class HistoryPager extends ReverseChronologicalPager {
         * @return string HTML output
         */
        function getStartBody() {
-               global $wgScript;
                $this->lastRow = false;
                $this->counter = 1;
                $this->oldIdChecked = 0;
 
                $this->getOutput()->wrapWikiMsg( "<div class='mw-history-legend'>\n$1\n</div>", 'histlegend' );
-               $s = Html::openElement( 'form', array( 'action' => $wgScript,
+               $s = Html::openElement( 'form', array( 'action' => wfScript(),
                        'id' => 'mw-history-compare' ) ) . "\n";
                $s .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n";
                $s .= Html::hidden( 'action', 'historysubmit' ) . "\n";
@@ -873,6 +874,7 @@ class HistoryPager extends ReverseChronologicalPager {
 
        /**
         * This is called if a write operation is possible from the generated HTML
+        * @param bool $enable
         */
        function preventClickjacking( $enable = true ) {
                $this->preventClickjacking = $enable;
index c2c1ff5..f932a40 100644 (file)
@@ -193,13 +193,13 @@ class InfoAction extends FormlessAction {
         * @return array
         */
        protected function pageInfo() {
-               global $wgContLang, $wgRCMaxAge, $wgMemc, $wgMiserMode,
-                       $wgUnwatchedPageThreshold, $wgPageInfoTransclusionLimit, $wgPageLanguageUseDB;
+               global $wgContLang, $wgMemc;
 
                $user = $this->getUser();
                $lang = $this->getLanguage();
                $title = $this->getTitle();
                $id = $title->getArticleID();
+               $config = $this->context->getConfig();
 
                $memcKey = wfMemcKey( 'infoaction',
                        sha1( $title->getPrefixedText() ), $this->page->getLatest() );
@@ -207,7 +207,7 @@ class InfoAction extends FormlessAction {
                $version = isset( $pageCounts['cacheversion'] ) ? $pageCounts['cacheversion'] : false;
                if ( $pageCounts === false || $version !== self::CACHE_VERSION ) {
                        // Get page information that would be too "expensive" to retrieve by normal means
-                       $pageCounts = self::pageCounts( $title );
+                       $pageCounts = $this->pageCounts( $title );
                        $pageCounts['cacheversion'] = self::CACHE_VERSION;
 
                        $wgMemc->set( $memcKey, $pageCounts );
@@ -276,7 +276,7 @@ class InfoAction extends FormlessAction {
                // Language in which the page content is (supposed to be) written
                $pageLang = $title->getPageLanguage()->getCode();
 
-               if ( $wgPageLanguageUseDB && $this->getTitle()->userCan( 'pagelang' ) ) {
+               if ( $config->get( 'PageLanguageUseDB' ) && $this->getTitle()->userCan( 'pagelang' ) ) {
                        // Link to Special:PageLanguage with pre-filled page title if user has permissions
                        $titleObj = SpecialPage::getTitleFor( 'PageLanguage', $title->getPrefixedText() );
                        $langDisp = Linker::link(
@@ -321,19 +321,20 @@ class InfoAction extends FormlessAction {
                        );
                }
 
+               $unwatchedPageThreshold = $config->get( 'UnwatchedPageThreshold' );
                if (
                        $user->isAllowed( 'unwatchedpages' ) ||
-                       ( $wgUnwatchedPageThreshold !== false &&
-                               $pageCounts['watchers'] >= $wgUnwatchedPageThreshold )
+                       ( $unwatchedPageThreshold !== false &&
+                               $pageCounts['watchers'] >= $unwatchedPageThreshold )
                ) {
                        // Number of page watchers
                        $pageInfo['header-basic'][] = array(
                                $this->msg( 'pageinfo-watchers' ), $lang->formatNum( $pageCounts['watchers'] )
                        );
-               } elseif ( $wgUnwatchedPageThreshold !== false ) {
+               } elseif ( $unwatchedPageThreshold !== false ) {
                        $pageInfo['header-basic'][] = array(
                                $this->msg( 'pageinfo-watchers' ),
-                               $this->msg( 'pageinfo-few-watchers' )->numParams( $wgUnwatchedPageThreshold )
+                               $this->msg( 'pageinfo-few-watchers' )->numParams( $unwatchedPageThreshold )
                        );
                }
 
@@ -521,7 +522,7 @@ class InfoAction extends FormlessAction {
 
                // Recent number of edits (within past 30 days)
                $pageInfo['header-edits'][] = array(
-                       $this->msg( 'pageinfo-recent-edits', $lang->formatDuration( $wgRCMaxAge ) ),
+                       $this->msg( 'pageinfo-recent-edits', $lang->formatDuration( $config->get( 'RCMaxAge' ) ) ),
                        $lang->formatNum( $pageCounts['recent_edits'] )
                );
 
@@ -555,9 +556,9 @@ class InfoAction extends FormlessAction {
                        $pageCounts['transclusion']['from'] > 0 ||
                        $pageCounts['transclusion']['to'] > 0
                ) {
-                       $options = array( 'LIMIT' => $wgPageInfoTransclusionLimit );
+                       $options = array( 'LIMIT' => $config->get( 'PageInfoTransclusionLimit' ) );
                        $transcludedTemplates = $title->getTemplateLinksFrom( $options );
-                       if ( $wgMiserMode ) {
+                       if ( $config->get( 'MiserMode' ) ) {
                                $transcludedTargets = array();
                        } else {
                                $transcludedTargets = $title->getTemplateLinksTo( $options );
@@ -602,7 +603,7 @@ class InfoAction extends FormlessAction {
                                );
                        }
 
-                       if ( !$wgMiserMode && $pageCounts['transclusion']['to'] > 0 ) {
+                       if ( !$config->get( 'MiserMode' ) && $pageCounts['transclusion']['to'] > 0 ) {
                                if ( $pageCounts['transclusion']['to'] > count( $transcludedTargets ) ) {
                                        $more = Linker::link(
                                                $whatLinksHere,
@@ -635,16 +636,15 @@ class InfoAction extends FormlessAction {
         * @param Title $title Title to get counts for
         * @return array
         */
-       protected static function pageCounts( Title $title ) {
-               global $wgRCMaxAge, $wgDisableCounters, $wgMiserMode;
-
+       protected function pageCounts( Title $title ) {
                wfProfileIn( __METHOD__ );
                $id = $title->getArticleID();
+               $config = $this->context->getConfig();
 
                $dbr = wfGetDB( DB_SLAVE );
                $result = array();
 
-               if ( !$wgDisableCounters ) {
+               if ( !$config->get( 'DisableCounters' ) ) {
                        // Number of views
                        $views = (int)$dbr->selectField(
                                'page',
@@ -685,8 +685,8 @@ class InfoAction extends FormlessAction {
                );
                $result['authors'] = $authors;
 
-               // "Recent" threshold defined by $wgRCMaxAge
-               $threshold = $dbr->timestamp( time() - $wgRCMaxAge );
+               // "Recent" threshold defined by RCMaxAge setting
+               $threshold = $dbr->timestamp( time() - $config->get( 'RCMaxAge' ) );
 
                // Recent number of edits
                $edits = (int)$dbr->selectField(
@@ -740,7 +740,7 @@ class InfoAction extends FormlessAction {
                }
 
                // Counts for the number of transclusion links (to/from)
-               if ( $wgMiserMode ) {
+               if ( $config->get( 'MiserMode' ) ) {
                        $result['transclusion']['to'] = 0;
                } else {
                        $result['transclusion']['to'] = (int)$dbr->selectField(
@@ -780,8 +780,6 @@ class InfoAction extends FormlessAction {
         * @return string Html
         */
        protected function getContributors() {
-               global $wgHiddenPrefs;
-
                $contributors = $this->page->getContributors();
                $real_names = array();
                $user_names = array();
@@ -794,9 +792,10 @@ class InfoAction extends FormlessAction {
                                ? SpecialPage::getTitleFor( 'Contributions', $user->getName() )
                                : $user->getUserPage();
 
+                       $hiddenPrefs = $this->context->getConfig()->get( 'HiddenPrefs' );
                        if ( $user->getID() == 0 ) {
                                $anon_ips[] = Linker::link( $page, htmlspecialchars( $user->getName() ) );
-                       } elseif ( !in_array( 'realname', $wgHiddenPrefs ) && $user->getRealName() ) {
+                       } elseif ( !in_array( 'realname', $hiddenPrefs ) && $user->getRealName() ) {
                                $real_names[] = Linker::link( $page, htmlspecialchars( $user->getRealName() ) );
                        } else {
                                $user_names[] = Linker::link( $page, htmlspecialchars( $user->getName() ) );
index 37e6e66..cd4e4ba 100644 (file)
@@ -48,10 +48,9 @@ class RawAction extends FormlessAction {
        }
 
        function onView() {
-               global $wgSquidMaxage, $wgForcedRawSMaxage;
-
                $this->getOutput()->disable();
                $request = $this->getRequest();
+               $config = $this->context->getConfig();
 
                if ( !$request->checkUrlExtension() ) {
                        return;
@@ -69,7 +68,7 @@ class RawAction extends FormlessAction {
                if ( $gen == 'css' || $gen == 'js' ) {
                        $this->mGen = $gen;
                        if ( $smaxage === null ) {
-                               $smaxage = $wgSquidMaxage;
+                               $smaxage = $config->get( 'SquidMaxage' );
                        }
                } else {
                        $this->mGen = false;
@@ -81,13 +80,13 @@ class RawAction extends FormlessAction {
                # Note: If using a canonical url for userpage css/js, we send an HTCP purge.
                if ( $smaxage === null ) {
                        if ( $contentType == 'text/css' || $contentType == 'text/javascript' ) {
-                               $smaxage = intval( $wgForcedRawSMaxage );
+                               $smaxage = intval( $config->get( 'ForcedRawSMaxage' ) );
                        } else {
                                $smaxage = 0;
                        }
                }
 
-               $maxage = $request->getInt( 'maxage', $wgSquidMaxage );
+               $maxage = $request->getInt( 'maxage', $config->get( 'SquidMaxage' ) );
 
                $response = $request->response();
 
index a280ddf..db62be0 100644 (file)
@@ -1349,7 +1349,7 @@ abstract class ApiBase extends ContextSource {
                        $msg = wfMessage( $code, $errors[0] );
                }
                if ( isset( ApiBase::$messageMap[$code] ) ) {
-                       // Translate message to code, for backwards compatability
+                       // Translate message to code, for backwards compatibility
                        $code = ApiBase::$messageMap[$code]['code'];
                }
 
@@ -2068,7 +2068,7 @@ abstract class ApiBase extends ContextSource {
        /**
         * @see self::getPossibleErrors()
         * @deprecated since 1.24
-        * @retun array
+        * @return array
         */
        public function getFinalPossibleErrors() {
                wfDeprecated( __METHOD__, '1.24' );
@@ -2227,4 +2227,19 @@ abstract class ApiBase extends ContextSource {
                }
                print "\n</pre>\n";
        }
+
+       /**
+        * Write logging information for API features to a debug log, for usage
+        * analysis.
+        * @param string $feature Feature being used.
+        */
+       protected function logFeatureUsage( $feature ) {
+               $request = $this->getRequest();
+               $s = $feature .
+                       ' ' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) .
+                       ' ' . $request->getIP() .
+                       ' "' . $request->getHeader( 'Referer' ) . '"' .
+                       ' "' . $request->getHeader( 'User-agent' ) . '"';
+               wfDebugLog( 'api-feature-usage', $s, 'private' );
+       }
 }
index f26d58b..aab0303 100644 (file)
@@ -72,8 +72,10 @@ class ApiDelete extends ApiBase {
 
                // Deprecated parameters
                if ( $params['watch'] ) {
+                       $this->logFeatureUsage( 'action=delete&watch' );
                        $watch = 'watch';
                } elseif ( $params['unwatch'] ) {
+                       $this->logFeatureUsage( 'action=delete&unwatch' );
                        $watch = 'unwatch';
                } else {
                        $watch = $params['watchlist'];
index fff061f..9126ad3 100644 (file)
@@ -309,8 +309,10 @@ class ApiEditPage extends ApiBase {
 
                // Deprecated parameters
                if ( $params['watch'] ) {
+                       $this->logFeatureUsage( 'action=edit&watch' );
                        $watch = true;
                } elseif ( $params['unwatch'] ) {
+                       $this->logFeatureUsage( 'action=edit&unwatch' );
                        $watch = false;
                }
 
index c2cec6d..8a3b534 100644 (file)
@@ -42,6 +42,7 @@ class ApiExpandTemplates extends ApiBase {
                $this->requireMaxOneParameter( $params, 'prop', 'generatexml' );
 
                if ( $params['prop'] === null ) {
+                       $this->logFeatureUsage( 'action=expandtemplates&!prop' );
                        $this->setWarning( 'Because no values have been specified for the prop parameter, a ' .
                                'legacy format has been used for the output. This format is deprecated, and in ' .
                                'the future, a default value will be set for the prop parameter, causing the new' .
@@ -70,6 +71,10 @@ class ApiExpandTemplates extends ApiBase {
                $retval = array();
 
                if ( isset( $prop['parsetree'] ) || $params['generatexml'] ) {
+                       if ( !isset( $prop['parsetree'] ) ) {
+                               $this->logFeatureUsage( 'action=expandtemplates&generatexml' );
+                       }
+
                        $wgParser->startExternalParse( $title_obj, $options, OT_PREPROCESS );
                        $dom = $wgParser->preprocessToDom( $params['text'] );
                        if ( is_callable( array( $dom, 'saveXML' ) ) ) {
index 3a0ed46..2e3fc11 100644 (file)
@@ -338,6 +338,18 @@ See the <a href='https://www.mediawiki.org/wiki/API'>complete documentation</a>,
        public function getDescription() {
                return $this->getIsHtml() ? ' (pretty-print in HTML)' : '';
        }
+
+       /**
+        * To avoid code duplication with the deprecation of dbg, dump, txt, wddx,
+        * and yaml, this method is added to do the necessary work. It should be
+        * removed when those deprecated formats are removed.
+        */
+       protected function markDeprecated() {
+               $fm = $this->getIsHtml() ? 'fm' : '';
+               $name = $this->getModuleName();
+               $this->logFeatureUsage( "format=$name" );
+               $this->setWarning( "format=$name has been deprecated. Please use format=json$fm instead." );
+       }
 }
 
 /**
index 1b2e02c..61ed18f 100644 (file)
@@ -38,10 +38,11 @@ class ApiFormatDbg extends ApiFormatBase {
        }
 
        public function execute() {
+               $this->markDeprecated();
                $this->printText( var_export( $this->getResultData(), true ) );
        }
 
        public function getDescription() {
-               return 'Output data in PHP\'s var_export() format' . parent::getDescription();
+               return 'DEPRECATED! Output data in PHP\'s var_export() format' . parent::getDescription();
        }
 }
index 62253e1..7d32246 100644 (file)
@@ -38,6 +38,7 @@ class ApiFormatDump extends ApiFormatBase {
        }
 
        public function execute() {
+               $this->markDeprecated();
                ob_start();
                var_dump( $this->getResultData() );
                $result = ob_get_contents();
@@ -46,6 +47,6 @@ class ApiFormatDump extends ApiFormatBase {
        }
 
        public function getDescription() {
-               return 'Output data in PHP\'s var_dump() format' . parent::getDescription();
+               return 'DEPRECATED! Output data in PHP\'s var_dump() format' . parent::getDescription();
        }
 }
index 4130e70..3de2943 100644 (file)
@@ -38,10 +38,11 @@ class ApiFormatTxt extends ApiFormatBase {
        }
 
        public function execute() {
+               $this->markDeprecated();
                $this->printText( print_r( $this->getResultData(), true ) );
        }
 
        public function getDescription() {
-               return 'Output data in PHP\'s print_r() format' . parent::getDescription();
+               return 'DEPRECATED! Output data in PHP\'s print_r() format' . parent::getDescription();
        }
 }
index 2e58c72..a08c3ab 100644 (file)
@@ -35,6 +35,8 @@ class ApiFormatWddx extends ApiFormatBase {
        }
 
        public function execute() {
+               $this->markDeprecated();
+
                // Some versions of PHP have a broken wddx_serialize_value, see
                // PHP bug 45314. Test encoding an affected character (U+00A0)
                // to avoid this.
@@ -107,6 +109,6 @@ class ApiFormatWddx extends ApiFormatBase {
        }
 
        public function getDescription() {
-               return 'Output data in WDDX format' . parent::getDescription();
+               return 'DEPRECATED! Output data in WDDX format' . parent::getDescription();
        }
 }
index 700d4a5..9f9b057 100644 (file)
@@ -34,7 +34,12 @@ class ApiFormatYaml extends ApiFormatJson {
                return 'application/yaml';
        }
 
+       public function execute() {
+               $this->markDeprecated();
+               parent::execute();
+       }
+
        public function getDescription() {
-               return 'Output data in YAML format' . ApiFormatBase::getDescription();
+               return 'DEPRECATED! Output data in YAML format' . ApiFormatBase::getDescription();
        }
 }
index b0b8328..bcd6c12 100644 (file)
@@ -51,6 +51,7 @@ class ApiHelp extends ApiBase {
                }
 
                if ( is_array( $params['querymodules'] ) ) {
+                       $this->logFeatureUsage( 'action=help&querymodules' );
                        $queryModules = $params['querymodules'];
                        foreach ( $queryModules as $m ) {
                                $modules[] = 'query+' . $m;
index fdf3f02..f7d0ccf 100644 (file)
@@ -195,7 +195,7 @@ class ApiModuleManager extends ContextSource {
                        // create instance from factory
                        $instance = call_user_func( $factory, $this->mParent, $name );
 
-                       if ( ! $instance instanceof $class ) {
+                       if ( !$instance instanceof $class ) {
                                throw new MWException( "The factory function for module $name did not return an instance of $class!" );
                        }
                } else {
index cc58573..602a905 100644 (file)
@@ -134,8 +134,10 @@ class ApiMove extends ApiBase {
                        $watch = $params['watchlist'];
                } elseif ( $params['watch'] ) {
                        $watch = 'watch';
+                       $this->logFeatureUsage( 'action=move&watch' );
                } elseif ( $params['unwatch'] ) {
                        $watch = 'unwatch';
+                       $this->logFeatureUsage( 'action=move&unwatch' );
                }
 
                // Watch pages
index dfb87fd..0f26467 100644 (file)
@@ -61,6 +61,7 @@ class ApiPageSet extends ApiBase {
        private $mSpecialTitles = array();
        private $mNormalizedTitles = array();
        private $mInterwikiTitles = array();
+       /** @var Title[] */
        private $mPendingRedirectIDs = array();
        private $mConvertedTitles = array();
        private $mGoodRevIDs = array();
@@ -68,9 +69,7 @@ class ApiPageSet extends ApiBase {
        private $mFakePageId = -1;
        private $mCacheMode = 'public';
        private $mRequestedPageFields = array();
-       /**
-        * @var int
-        */
+       /** @var int */
        private $mDefaultNamespace = NS_MAIN;
 
        /**
@@ -389,7 +388,7 @@ class ApiPageSet extends ApiBase {
        /**
         * Get a list of redirect resolutions - maps a title to its redirect
         * target, as an array of output-ready arrays
-        * @return array
+        * @return Title[]
         */
        public function getRedirectTitles() {
                return $this->mRedirectTitles;
@@ -598,7 +597,7 @@ class ApiPageSet extends ApiBase {
 
        /**
         * Get the list of titles with negative namespace
-        * @return array Title
+        * @return Title[]
         */
        public function getSpecialTitles() {
                return $this->mSpecialTitles;
index 828fc22..844d1cc 100644 (file)
@@ -102,6 +102,9 @@ class ApiProtect extends ApiBase {
 
                $cascade = $params['cascade'];
 
+               if ( $params['watch'] ) {
+                       $this->logFeatureUsage( 'action=protect&watch' );
+               }
                $watch = $params['watch'] ? 'watch' : $params['watchlist'];
                $this->setWatch( $watch, $titleObj, 'watchdefault' );
 
index d04e5b4..da05f27 100644 (file)
@@ -50,6 +50,7 @@ class ApiQueryLangLinks extends ApiQueryBase {
                // Handle deprecated param
                $this->requireMaxOneParameter( $params, 'url', 'prop' );
                if ( $params['url'] ) {
+                       $this->logFeatureUsage( 'prop=langlinks&llurl' );
                        $prop = array( 'url' => 1 );
                }
 
index 6bf2612..be6bc68 100644 (file)
@@ -197,7 +197,6 @@ class ApiQuerySearch extends ApiQueryGeneratorBase {
                $hasInterwikiResults = false;
                if ( $interwiki && $resultPageSet === null && $matches->hasInterwikiResults() ) {
                        $matches = $matches->getInterwikiResults();
-                       $iwprefixes = array();
                        $hasInterwikiResults = true;
 
                        // Include number of results if requested
index 818080c..90683a9 100644 (file)
@@ -166,7 +166,7 @@ class ApiQuerySiteinfo extends ApiQueryBase {
                if ( $wgContLang->linkPrefixExtension() ) {
                        $linkPrefixCharset = $wgContLang->linkPrefixCharset();
                        $data['linkprefixcharset'] = $linkPrefixCharset;
-                       // For backwards compatability
+                       // For backwards compatibility
                        $data['linkprefix'] = "/^((?>.*[^$linkPrefixCharset]|))(.+)$/sDu";
                } else {
                        $data['linkprefixcharset'] = '';
index d7904d4..db92856 100644 (file)
@@ -47,6 +47,7 @@ class ApiQueryStashImageInfo extends ApiQueryImageInfo {
 
                // Alias sessionkey to filekey, but give an existing filekey precedence.
                if ( !$params['filekey'] && $params['sessionkey'] ) {
+                       $this->logFeatureUsage( 'prop=stashimageinfo&siisessionkey' );
                        $params['filekey'] = $params['sessionkey'];
                }
 
index b8b4e31..4b167b8 100644 (file)
@@ -224,6 +224,7 @@ class ApiQueryContributions extends ApiQueryBase {
 
                $show = $this->params['show'];
                if ( $this->params['toponly'] ) { // deprecated/old param
+                       $this->logFeatureUsage( 'list=usercontribs&uctoponly' );
                        $show[] = 'top';
                }
                if ( !is_null( $show ) ) {
index 97b74e5..2e80447 100644 (file)
@@ -461,7 +461,7 @@ class ApiResult extends ApiBase {
         *
         * @since 1.24
         * @param string|null $continue The "continue" parameter, if any
-        * @param array $allModules Contains ApiBase instances that will be executed
+        * @param ApiBase[] $allModules Contains ApiBase instances that will be executed
         * @param array $generatedModules Names of modules that depend on the generator
         * @return array Two elements: a boolean indicating if the generator is done,
         *   and an array of modules to actually execute.
index 2b840fe..368e7ce 100644 (file)
@@ -28,7 +28,7 @@
  * @ingroup API
  */
 class ApiUpload extends ApiBase {
-       /** @var UploadBase */
+       /** @var UploadBase|UploadFromChunks */
        protected $mUpload = null;
 
        protected $mParams;
@@ -52,6 +52,7 @@ class ApiUpload extends ApiBase {
 
                // Copy the session key to the file key, for backward compatibility.
                if ( !$this->mParams['filekey'] && $this->mParams['sessionkey'] ) {
+                       $this->logFeatureUsage( 'action=upload&sessionkey' );
                        $this->mParams['filekey'] = $this->mParams['sessionkey'];
                }
 
@@ -210,7 +211,6 @@ class ApiUpload extends ApiBase {
                        }
                } else {
                        $filekey = $this->mParams['filekey'];
-                       /** @var $status Status */
                        $status = $this->mUpload->addChunk(
                                $chunkPath, $chunkSize, $this->mParams['offset'] );
                        if ( !$status->isGood() ) {
@@ -467,6 +467,7 @@ class ApiUpload extends ApiBase {
 
        /**
         * Performs file verification, dies on error.
+        * @param array $verification
         */
        protected function checkVerification( array $verification ) {
                // @todo Move them to ApiBase's message map
@@ -551,6 +552,7 @@ class ApiUpload extends ApiBase {
 
                        if ( isset( $warnings['duplicate'] ) ) {
                                $dupes = array();
+                               /** @var File $dupe */
                                foreach ( $warnings['duplicate'] as $dupe ) {
                                        $dupes[] = $dupe->getName();
                                }
@@ -561,6 +563,7 @@ class ApiUpload extends ApiBase {
                        if ( isset( $warnings['exists'] ) ) {
                                $warning = $warnings['exists'];
                                unset( $warnings['exists'] );
+                               /** @var LocalFile $localFile */
                                $localFile = isset( $warning['normalizedFile'] )
                                        ? $warning['normalizedFile']
                                        : $warning['file'];
@@ -602,6 +605,7 @@ class ApiUpload extends ApiBase {
 
                // Deprecated parameters
                if ( $this->mParams['watch'] ) {
+                       $this->logFeatureUsage( 'action=upload&watch' );
                        $watch = true;
                }
 
index 43ff4ec..8060260 100644 (file)
@@ -84,6 +84,7 @@ class ApiWatch extends ApiBase {
                                );
                        }
 
+                       $this->logFeatureUsage( 'action=watch&title' );
                        $title = Title::newFromText( $params['title'] );
                        if ( !$title || !$title->isWatchable() ) {
                                $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
index c0c5977..e2e304a 100644 (file)
@@ -1163,8 +1163,8 @@ class LCStoreDB implements LCStore {
        private $readOnly = false;
 
        public function get( $code, $key ) {
-               if ( $this->writesDone && $this->dbw ) {
-                       $db = $this->dbw;
+               if ( $this->writesDone ) {
+                       $db = wfGetDB( DB_MASTER );
                } else {
                        $db = wfGetDB( DB_SLAVE );
                }
@@ -1184,16 +1184,7 @@ class LCStoreDB implements LCStore {
                        throw new MWException( __METHOD__ . ": Invalid language \"$code\"" );
                }
 
-               // We must keep a separate connection to MySQL in order to avoid breaking
-               // main transactions. However, SQLite deadlocks when using two connections.
-               // @todo get this trick to work on PostgreSQL too
-               if ( wfGetDB( DB_MASTER )->getType() == 'mysql' ) {
-                       $lb = wfGetLBFactory()->newMainLB();
-                       $this->dbw = $lb->getConnection( DB_MASTER );
-                       $this->dbw->clearFlag( DBO_TRX ); // auto-commit mode
-               } else {
-                       $this->dbw = wfGetDB( DB_MASTER );
-               }
+               $this->dbw = wfGetDB( DB_MASTER );
 
                $this->currentLang = $code;
                $this->batch = array();
index cfebf40..e33274e 100644 (file)
@@ -136,7 +136,7 @@ class RecentChange {
        /**
         * Parsing RC_* constants to human-readable test
         * @since 1.24
-        * @param int $rc_type
+        * @param int $rcType
         * @return string $type
         */
        public static function parseFromRCType( $rcType ) {
@@ -160,22 +160,6 @@ class RecentChange {
                return $type;
        }
 
-       /**
-        * No uses left in Gerrit on 2013-11-19.
-        * @deprecated since 1.22
-        * @param mixed $row
-        * @return RecentChange
-        */
-       public static function newFromCurRow( $row ) {
-               wfDeprecated( __METHOD__, '1.22' );
-               $rc = new RecentChange;
-               $rc->loadFromCurRow( $row );
-               $rc->notificationtimestamp = false;
-               $rc->numberofWatchingusers = false;
-
-               return $rc;
-       }
-
        /**
         * Obtain the recent change with a given rc_id value
         *
@@ -350,38 +334,6 @@ class RecentChange {
                }
        }
 
-       /**
-        * @deprecated since 1.22, use notifyRCFeeds instead.
-        */
-       public function notifyRC2UDP() {
-               wfDeprecated( __METHOD__, '1.22' );
-               $this->notifyRCFeeds();
-       }
-
-       /**
-        * Send some text to UDP.
-        * @deprecated since 1.22
-        */
-       public static function sendToUDP( $line, $address = '', $prefix = '', $port = '' ) {
-               global $wgRC2UDPAddress, $wgRC2UDPInterwikiPrefix, $wgRC2UDPPort, $wgRC2UDPPrefix;
-
-               wfDeprecated( __METHOD__, '1.22' );
-
-               # Assume default for standard RC case
-               $address = $address ? $address : $wgRC2UDPAddress;
-               $prefix = $prefix ? $prefix : $wgRC2UDPPrefix;
-               $port = $port ? $port : $wgRC2UDPPort;
-
-               $engine = new UDPRCFeedEngine();
-               $feed = array(
-                       'uri' => "udp://$address:$port/$prefix",
-                       'formatter' => 'IRCColourfulRCFeedFormatter',
-                       'add_interwiki_prefix' => $wgRC2UDPInterwikiPrefix,
-               );
-
-               $engine->send( $feed, $line );
-       }
-
        /**
         * Notify all the feeds about the change.
         * @param array $feeds Optional feeds to send to, defaults to $wgRCFeeds
@@ -452,15 +404,6 @@ class RecentChange {
                return new $wgRCEngines[$scheme];
        }
 
-       /**
-        * @deprecated since 1.22, moved to IRCColourfulRCFeedFormatter
-        */
-       public static function cleanupForIRC( $text ) {
-               wfDeprecated( __METHOD__, '1.22' );
-
-               return IRCColourfulRCFeedFormatter::cleanupForIRC( $text );
-       }
-
        /**
         * Mark a given change as patrolled
         *
@@ -793,42 +736,6 @@ class RecentChange {
                $this->mAttribs['rc_deleted'] = $row->rc_deleted; // MUST be set
        }
 
-       /**
-        * Makes a pseudo-RC entry from a cur row
-        *
-        * @deprecated since 1.22
-        * @param mixed $row
-        */
-       public function loadFromCurRow( $row ) {
-               wfDeprecated( __METHOD__, '1.22' );
-               $this->mAttribs = array(
-                       'rc_timestamp' => wfTimestamp( TS_MW, $row->rev_timestamp ),
-                       'rc_user' => $row->rev_user,
-                       'rc_user_text' => $row->rev_user_text,
-                       'rc_namespace' => $row->page_namespace,
-                       'rc_title' => $row->page_title,
-                       'rc_comment' => $row->rev_comment,
-                       'rc_minor' => $row->rev_minor_edit ? 1 : 0,
-                       'rc_type' => $row->page_is_new ? RC_NEW : RC_EDIT,
-                       'rc_source' => $row->page_is_new ? self::SRC_NEW : self::SRC_EDIT,
-                       'rc_cur_id' => $row->page_id,
-                       'rc_this_oldid' => $row->rev_id,
-                       'rc_last_oldid' => isset( $row->rc_last_oldid ) ? $row->rc_last_oldid : 0,
-                       'rc_bot' => 0,
-                       'rc_ip' => '',
-                       'rc_id' => $row->rc_id,
-                       'rc_patrolled' => $row->rc_patrolled,
-                       'rc_new' => $row->page_is_new, # obsolete
-                       'rc_old_len' => $row->rc_old_len,
-                       'rc_new_len' => $row->rc_new_len,
-                       'rc_params' => isset( $row->rc_params ) ? $row->rc_params : '',
-                       'rc_log_type' => isset( $row->rc_log_type ) ? $row->rc_log_type : null,
-                       'rc_log_action' => isset( $row->rc_log_action ) ? $row->rc_log_action : null,
-                       'rc_logid' => isset( $row->rc_logid ) ? $row->rc_logid : 0,
-                       'rc_deleted' => $row->rc_deleted // MUST be set
-               );
-       }
-
        /**
         * Get an attribute value
         *
index 377d675..e563780 100644 (file)
@@ -80,8 +80,8 @@ class JSONContent extends TextContent {
        }
        /**
         * Constructs an HTML representation of a JSON object.
-        * @param Array $mapping
-        * @return string HTML.
+        * @param array $mapping
+        * @return string HTML
         */
        protected function objectTable( $mapping ) {
                $rows = array();
index 9d001da..6b77527 100644 (file)
@@ -46,12 +46,30 @@ class JSONContentHandler extends TextContentHandler {
                return new $this->contentClass( '' );
        }
 
-       /** JSON is English **/
+       /**
+        * Returns the english language, because JSON is english, and should be handled as such.
+        *
+        * @param Title $title
+        * @param Content|null $content
+        *
+        * @return Language Return of wfGetLangObj( 'en' )
+        *
+        * @see ContentHandler::getPageLanguage()
+        */
        public function getPageLanguage( Title $title, Content $content = null ) {
                return wfGetLangObj( 'en' );
        }
 
-       /** JSON is English **/
+       /**
+        * Returns the english language, because JSON is english, and should be handled as such.
+        *
+        * @param Title $title
+        * @param Content|null $content
+        *
+        * @return Language Return of wfGetLangObj( 'en' )
+        *
+        * @see ContentHandler::getPageLanguage()
+        */
        public function getPageViewLanguage( Title $title, Content $content = null ) {
                return wfGetLangObj( 'en' );
        }
index 8ab1122..00733d8 100644 (file)
@@ -352,19 +352,15 @@ class RequestContext implements IContextSource {
 
                        $skin = null;
                        wfRunHooks( 'RequestContextCreateSkin', array( $this, &$skin ) );
-                       $fallback = $this->getConfig()->get( 'FallbackSkin' );
                        $factory = SkinFactory::getDefaultInstance();
 
                        // If the hook worked try to set a skin from it
                        if ( $skin instanceof Skin ) {
                                $this->skin = $skin;
                        } elseif ( is_string( $skin ) ) {
-                               try {
-                                       $this->skin = $factory->makeSkin( $skin );
-                               } catch ( SkinException $e ) {
-                                       $this->skin = $factory->makeSkin( $fallback );
-                               }
-
+                               // Normalize the key, just in case the hook did something weird.
+                               $normalized = Skin::normalizeKey( $skin );
+                               $this->skin = $factory->makeSkin( $normalized );
                        }
 
                        // If this is still null (the hook didn't run or didn't work)
@@ -379,12 +375,13 @@ class RequestContext implements IContextSource {
                                        $userSkin = $this->getConfig()->get( 'DefaultSkin' );
                                }
 
-                               try {
-                                       $this->skin = $factory->makeSkin( $userSkin );
-                               } catch ( SkinException $e ) {
-                                       $this->skin = $factory->makeSkin( $fallback );
-                               }
+                               // Normalize the key in case the user is passing gibberish
+                               // or has old preferences (bug 69566).
+                               $normalized = Skin::normalizeKey( $userSkin );
 
+                               // Skin::normalizeKey will also validate it, so
+                               // this won't throw an exception
+                               $this->skin = $factory->makeSkin( $normalized );
                        }
 
                        // After all that set a context on whatever skin got created
index c2f5b6d..3a4bb27 100644 (file)
@@ -340,6 +340,7 @@ class DatabaseMssql extends DatabaseBase {
        }
 
        /**
+        * @param array $err
         * @return string
         */
        private function formatError( $err ) {
@@ -1068,6 +1069,7 @@ class DatabaseMssql extends DatabaseBase {
 
        /**
         * Begin a transaction, committing any previously open transaction
+        * @param string $fname
         */
        protected function doBegin( $fname = __METHOD__ ) {
                sqlsrv_begin_transaction( $this->mConn );
@@ -1076,6 +1078,7 @@ class DatabaseMssql extends DatabaseBase {
 
        /**
         * End a transaction
+        * @param string $fname
         */
        protected function doCommit( $fname = __METHOD__ ) {
                sqlsrv_commit( $this->mConn );
@@ -1085,6 +1088,7 @@ class DatabaseMssql extends DatabaseBase {
        /**
         * Rollback a transaction.
         * No-op on non-transactional databases.
+        * @param string $fname
         */
        protected function doRollback( $fname = __METHOD__ ) {
                sqlsrv_rollback( $this->mConn );
index f5fdca1..45fb3f6 100644 (file)
@@ -1154,7 +1154,7 @@ __INDEXATTR__;
                return wfTimestamp( TS_POSTGRES, $ts );
        }
 
-       /*
+       /**
         * Posted by cc[plus]php[at]c2se[dot]com on 25-Mar-2009 09:12
         * to http://www.php.net/manual/en/ref.pgsql.php
         *
@@ -1201,6 +1201,9 @@ __INDEXATTR__;
 
        /**
         * Return aggregated value function call
+        * @param array $valuedata
+        * @param string $valuename
+        * @return array
         */
        public function aggregateValue( $valuedata, $valuename = 'value' ) {
                return $valuedata;
index 3923241..7ec3b4a 100644 (file)
@@ -140,7 +140,7 @@ class ResultWrapper implements Iterator {
         * Fields can be retrieved with $row->fieldname, with fields acting like
         * member variables.
         *
-        * @return object
+        * @return stdClass
         * @throws DBUnexpectedError Thrown if the database returns an error
         */
        function fetchObject() {
@@ -177,8 +177,8 @@ class ResultWrapper implements Iterator {
                $this->db->dataSeek( $this, $row );
        }
 
-       /*********************
-        * Iterator functions
+       /*
+        * ======= Iterator functions =======
         * Note that using these in combination with the non-iterator functions
         * above may cause rows to be skipped or repeated.
         */
@@ -192,7 +192,7 @@ class ResultWrapper implements Iterator {
        }
 
        /**
-        * @return int
+        * @return stdClass|array|false
         */
        function current() {
                if ( is_null( $this->currentRow ) ) {
@@ -210,7 +210,7 @@ class ResultWrapper implements Iterator {
        }
 
        /**
-        * @return int
+        * @return stdClass
         */
        function next() {
                $this->pos++;
@@ -255,6 +255,9 @@ class FakeResultWrapper extends ResultWrapper {
                return count( $this->result );
        }
 
+       /**
+        * @return array|bool
+        */
        function fetchRow() {
                if ( $this->pos < count( $this->result ) ) {
                        $this->currentRow = $this->result[$this->pos];
@@ -276,7 +279,10 @@ class FakeResultWrapper extends ResultWrapper {
        function free() {
        }
 
-       // Callers want to be able to access fields with $this->fieldName
+       /**
+        * Callers want to be able to access fields with $this->fieldName
+        * @return false|stdClass
+        */
        function fetchObject() {
                $this->fetchRow();
                if ( $this->currentRow ) {
@@ -291,6 +297,9 @@ class FakeResultWrapper extends ResultWrapper {
                $this->currentRow = null;
        }
 
+       /**
+        * @return false|stdClass
+        */
        function next() {
                return $this->fetchObject();
        }
index 20f348a..1466605 100644 (file)
@@ -115,6 +115,7 @@ class SearchUpdate implements DeferrableUpdate {
         * Clean text for indexing. Only really suitable for indexing in databases.
         * If you're using a real search engine, you'll probably want to override
         * this behavior and do something nicer with the original wikitext.
+        * @param string $text
         */
        public static function updateText( $text ) {
                global $wgContLang;
@@ -179,6 +180,7 @@ class SearchUpdate implements DeferrableUpdate {
         * Get a string representation of a title suitable for
         * including in a search index
         *
+        * @param SearchEngine $search
         * @return string A stripped-down title string ready for the search index
         */
        private function indexTitle( SearchEngine $search ) {
index 661330d..ee918f3 100644 (file)
@@ -1140,6 +1140,8 @@ class DifferenceEngine extends ContextSource {
 
        /**
         * Use specified text instead of loading from the database
+        * @param Content $oldContent
+        * @param Content $newContent
         * @since 1.21
         */
        public function setContent( Content $oldContent, Content $newContent ) {
@@ -1153,6 +1155,7 @@ class DifferenceEngine extends ContextSource {
        /**
         * Set the language in which the diff text is written
         * (Defaults to page content language).
+        * @param Language|string $lang
         * @since 1.19
         */
        public function setTextLanguage( $lang ) {
index 58b07f5..074128f 100644 (file)
@@ -252,6 +252,7 @@ class MWException extends Exception {
        /**
         * Send a header, if we haven't already sent them. We shouldn't,
         * but sometimes we might in a weird case like Export
+        * @param string $header
         */
        private static function header( $header ) {
                if ( !headers_sent() ) {
index 2820be2..78810eb 100644 (file)
@@ -218,7 +218,7 @@ abstract class FileBackend {
        /**
         * Check if the backend medium supports a field of extra features
         *
-        * @return int Bitfield of FileBackend::ATTR_* flags
+        * @param int $bitfield Bitfield of FileBackend::ATTR_* flags
         * @return bool
         * @since 1.23
         */
index e9c8883..f40ec46 100644 (file)
@@ -173,7 +173,7 @@ class SwiftFileBackend extends FileBackendStore {
         * Sanitize and filter the custom headers from a $params array.
         * We only allow certain Content- and X-Content- headers.
         *
-        * @param array $headers
+        * @param array $params
         * @return array Sanitized value of 'headers' field in $params
         */
        protected function sanitizeHdrs( array $params ) {
index a45fb7a..25a06d2 100644 (file)
@@ -546,7 +546,7 @@ class FileRepo {
         *
         * STUB
         * @param string $hash SHA-1 hash
-        * @return array
+        * @return File[]
         */
        public function findBySha1( $hash ) {
                return array();
@@ -1014,6 +1014,7 @@ class FileRepo {
                        } elseif ( is_array( $triple[2] ) && isset( $triple[2]['headers'] ) ) {
                                $headers = $triple[2]['headers'];
                        }
+                       // @fixme: $headers might not be defined
                        $operations[] = array(
                                'op' => FileBackend::isStoragePath( $src ) ? 'copy' : 'store',
                                'src' => $src,
@@ -1447,6 +1448,7 @@ class FileRepo {
         * Delete files in the deleted directory if they are not referenced in the filearchive table
         *
         * STUB
+        * @param array $storageKeys
         */
        public function cleanupDeletedBatch( array $storageKeys ) {
                $this->assertWritableRepo();
index 96c8803..926fd0b 100644 (file)
@@ -49,7 +49,7 @@ class LocalRepo extends FileRepo {
 
        /**
         * @throws MWException
-        * @param array $row
+        * @param stdClass $row
         * @return LocalFile
         */
        function newFileFromRow( $row ) {
@@ -91,7 +91,7 @@ class LocalRepo extends FileRepo {
                        $hashPath = $this->getDeletedHashPath( $key );
                        $path = "$root/$hashPath$key";
                        $dbw->begin( __METHOD__ );
-                       // Check for usage in deleted/hidden files and pre-emptively
+                       // Check for usage in deleted/hidden files and preemptively
                        // lock the key to avoid any future use until we are finished.
                        $deleted = $this->deletedFileHasKey( $key, 'lock' );
                        $hidden = $this->hiddenFileHasKey( $key, 'lock' );
@@ -167,7 +167,7 @@ class LocalRepo extends FileRepo {
         * Checks if there is a redirect named as $title
         *
         * @param Title $title Title of file
-        * @return bool
+        * @return bool|Title
         */
        function checkRedirect( Title $title ) {
                global $wgMemc;
@@ -370,7 +370,7 @@ class LocalRepo extends FileRepo {
         * SHA-1 content hash.
         *
         * @param string $hash A sha1 hash to look for
-        * @return array
+        * @return File[]
         */
        function findBySha1( $hash ) {
                $dbr = $this->getSlaveDB();
index fce3f78..0f80e16 100644 (file)
@@ -221,7 +221,7 @@ class RepoGroup {
        /**
         * Interface for FileRepo::checkRedirect()
         * @param Title $title
-        * @return bool
+        * @return bool|Title
         */
        function checkRedirect( Title $title ) {
                if ( !$this->reposInitialised ) {
@@ -273,7 +273,7 @@ class RepoGroup {
         * Find all instances of files with this key
         *
         * @param string $hash Base 36 SHA-1 hash
-        * @return array Array of File objects
+        * @return File[]
         */
        function findBySha1( $hash ) {
                if ( !$this->reposInitialised ) {
@@ -409,6 +409,7 @@ class RepoGroup {
 
        /**
         * Create a repo class based on an info structure
+        * @param array $info
         */
        protected function newRepo( $info ) {
                $class = $info['class'];
index a61002a..0c4e42e 100644 (file)
@@ -1287,6 +1287,7 @@ abstract class File {
         * Hook into transform() to allow migration of thumbnail files
         * STUB
         * Overridden by LocalFile
+        * @param string $thumbName
         */
        function migrateThumbFile( $thumbName ) {
        }
@@ -1937,7 +1938,7 @@ abstract class File {
         * @note Use getWidth()/getHeight() instead of this method unless you have a
         *  a good reason. This method skips all caches.
         *
-        * @param string $fileName The path to the file (e.g. From getLocalPathRef() )
+        * @param string $filePath The path to the file (e.g. From getLocalPathRef() )
         * @return array The width, followed by height, with optionally more things after
         */
        function getImageSize( $filePath ) {
index 3ba47ff..07f1f09 100644 (file)
@@ -379,6 +379,7 @@ class LocalFile extends File {
 
        /**
         * Load file metadata from the DB
+        * @param int $flags
         */
        function loadFromDB( $flags = 0 ) {
                # Polymorphic function name to distinguish foreign and local fetches
@@ -931,6 +932,7 @@ class LocalFile extends File {
 
        /**
         * Delete cached transformed files for the current version only.
+        * @param array $options
         */
        function purgeThumbnails( $options = array() ) {
                global $wgUseSquid;
@@ -2371,6 +2373,7 @@ class LocalFileRestoreBatch {
 
        /**
         * Add a file by ID
+        * @param int $fa_id
         */
        function addId( $fa_id ) {
                $this->ids[] = $fa_id;
@@ -2378,6 +2381,7 @@ class LocalFileRestoreBatch {
 
        /**
         * Add a whole lot of files by ID
+        * @param int[] $ids
         */
        function addIds( $ids ) {
                $this->ids = array_merge( $this->ids, $ids );
@@ -2973,6 +2977,7 @@ class LocalFileMoveBatch {
        /**
         * Cleanup a partially moved array of triplets by deleting the target
         * files. Called if something went wrong half way.
+        * @param array $triplets
         */
        function cleanupTarget( $triplets ) {
                // Create dest pairs from the triplets
@@ -2988,6 +2993,7 @@ class LocalFileMoveBatch {
        /**
         * Cleanup a fully moved array of triplets by deleting the source files.
         * Called at the end of the move process if everything else went ok.
+        * @param array $triplets
         */
        function cleanupSource( $triplets ) {
                // Create source file names from the triplets
index 53c2e10..2d3ea5a 100644 (file)
@@ -123,6 +123,7 @@ abstract class ImageGalleryBase extends ContextSource {
         *
         * You should not call this directly, but instead use
         * ImageGalleryBase::factory().
+        * @param string $mode
         */
        function __construct( $mode = 'traditional' ) {
                global $wgGalleryOptions;
@@ -154,6 +155,7 @@ abstract class ImageGalleryBase extends ContextSource {
 
        /**
         * Set bad image flag
+        * @param bool $flag
         */
        function setHideBadImages( $flag = true ) {
                $this->mHideBadImages = $flag;
index b004a95..207efa8 100644 (file)
@@ -103,6 +103,7 @@ class PackedImageGallery extends TraditionalImageGallery {
        /**
         * Do not support per-row on packed. It really doesn't work
         * since the images have varying widths.
+        * @param int $num
         */
        public function setPerRow( $num ) {
                return;
index 4f1b530..77924ef 100644 (file)
@@ -16,6 +16,8 @@ class HTMLEditTools extends HTMLFormField {
        }
 
        /**
+        * @param string $value
+        * @return string
         * @since 1.20
         */
        public function getDiv( $value ) {
@@ -25,6 +27,8 @@ class HTMLEditTools extends HTMLFormField {
        }
 
        /**
+        * @param string $value
+        * @return string
         * @since 1.20
         */
        public function getRaw( $value ) {
index 6ea95ed..e32c0bb 100644 (file)
@@ -21,6 +21,8 @@ class HTMLHiddenField extends HTMLFormField {
        }
 
        /**
+        * @param string $value
+        * @return string
         * @since 1.20
         */
        public function getDiv( $value ) {
@@ -28,6 +30,8 @@ class HTMLHiddenField extends HTMLFormField {
        }
 
        /**
+        * @param string $value
+        * @return string
         * @since 1.20
         */
        public function getRaw( $value ) {
index cff8202..a422047 100644 (file)
@@ -23,6 +23,8 @@ class HTMLInfoField extends HTMLFormField {
        }
 
        /**
+        * @param string $value
+        * @return string
         * @since 1.20
         */
        public function getDiv( $value ) {
@@ -34,6 +36,8 @@ class HTMLInfoField extends HTMLFormField {
        }
 
        /**
+        * @param string $value
+        * @return string
         * @since 1.20
         */
        public function getRaw( $value ) {
index b25ea09..427ded4 100644 (file)
@@ -297,9 +297,9 @@ abstract class DatabaseUpdater {
         * @param string $tableName The table name
         * @param string $oldIndexName The old index name
         * @param string $newIndexName The new index name
+        * @param string $sqlPath The path to the SQL change path
         * @param bool $skipBothIndexExistWarning Whether to warn if both the old
         * and the new indexes exist. [facultative; by default, false]
-        * @param string $sqlPath The path to the SQL change path
         */
        public function renameExtensionIndex( $tableName, $oldIndexName, $newIndexName,
                $sqlPath, $skipBothIndexExistWarning = false
index 83681b6..46bb86c 100644 (file)
@@ -702,7 +702,7 @@ class MssqlInstaller extends DatabaseInstaller {
        /**
         * Try to see if a given fulltext catalog exists
         * We assume we already have the appropriate database selected
-        * @param string $schemaName Catalog name to check
+        * @param string $catalogName Catalog name to check
         * @return bool
         */
        private function catalogExists( $catalogName ) {
index 5a7d148..afa7d72 100644 (file)
        "config-localsettings-key": "Pihi hoʻopuka hou:",
        "config-localsettings-badkey": "Hewa ka pihi.",
        "config-upgrade-key-missing": "Loaʻa he hoʻonohona mai mua o MīkiaWiki mai mua.\nNo ka hoʻopuka hou ʻana o kēia hoʻonohona, e ʻoluʻolu, e kau i kēia laina lalo ma lalo o kāu <code>LocalSettings.php</code>:\n\n$1",
+       "config-localsettings-incomplete": "ʻAʻole piha pono kēia <code>LocalSettings.php</code> nei.\nʻAʻole hoʻopaʻa ʻia ka hualau $1.\nE hoʻololi iā <code>LocalSettings.php</code> i hiki ke hoʻopaʻa i ka hualau, a laila e kaomi iā \"{{int:Config-continue}}\" ke ʻoluʻolu.",
+       "config-localsettings-connection-error": "Ua loaʻa i ke kuʻia i ka hoʻokuʻi ʻana i ke hōkeo ʻikepili ma muli o ka hana ʻana o ka makemake e kākau ʻia ma <code>LocalSettings.php</code>. E ʻoluʻolu e hoʻoponopono i kēia makemake a hana hou.\n\n$1",
+       "config-session-error": "Kuʻia ka wā hoʻohana hoʻomaka: $1",
+       "config-session-expired": "Ua pau kāu ʻikepili wā hoʻohana.\nOla ka wā hoʻohana no ka manawa o $1.\nHiki iā ʻoe ke hoʻonui i kēia wā ma o ka hoʻololi ʻana o <code>session.gc_maxlifetime</code> ma php.ini.\nE hana hou i ka hana hoʻoukana.",
+       "config-no-session": "Ua nalo kāu ʻikepili wā hoʻohana!\nE hōʻoia i kāu php.ini a me ka hoʻopaʻa ʻana o <code>session.save_path</code> i ke kumu kūpono.",
        "config-your-language": "Kāu ʻōlelo:",
        "config-your-language-help": "E koho i kekahi ʻōlelo no ka hoʻohana ʻana ma loko o ka hana hoʻonohona.",
        "config-wiki-language": "ʻŌlelo Wiki:",
@@ -33,6 +38,7 @@
        "config-page-copying": "Kope",
        "config-page-upgradedoc": "Ka Hoʻopuka ʻana",
        "config-page-existingwiki": "Ka wiki nei",
+       "config-help-restart": "He ʻoiaʻiʻo kāu makemake no ka holoi pono o nā ʻikepili mālamalia a pau āu i kikokiko a hoʻomaka hou i ka hana hoʻouka?",
        "config-restart": "ʻAe, e hōʻano hou",
        "config-db-type": "ʻAno hōkeo ʻikepili:",
        "config-db-name": "Inoa hōkeo ʻikepili",
index b0bde75..0c48ffa 100644 (file)
        "config-license-gfdl": "GNU licencja wolnej dokumentacji 1.3 lub nowsza",
        "config-license-pd": "Domena publiczna",
        "config-license-cc-choose": "Wybierz własną licencję Creative Commons",
-       "config-license-help": "Wiele publicznych wiki umieszcza wszystkie dopisane treści na [http://freedomdefined.org/Definition wolnej licencji].\nTo pomaga tworzyć poczucie wspólnoty i zachęca do długoterminowego wkładu.\nNie jest to zazwyczaj konieczne w prywatnych lub firmowych wiki.\n\nJeśli chcesz móc użyć tekstu z Wikipedii i chcesz Wikipedia mogła zaakceptować tekst skopiowany z twojej wiki, należy wybrać '''Creative Commons Attribution Share Alike'''.\n\nWikipedia używała poprzednio GNU Free Documentation License.\nGFDL jest poprawną licencję, ale trudno ją zrozumieć.\nTrudno także ponowne użyć zawartości na licencji GFDL.",
+       "config-license-help": "Wiele publicznych wiki umieszcza wszystkie dopisane treści na [http://freedomdefined.org/Definition wolnej licencji].\nPomaga to tworzyć poczucie wspólnoty i zachęca do długoterminowego wkładu.\nNie jest to zazwyczaj konieczne w prywatnych lub firmowych wiki.\n\nJeśli chcesz móc użyć tekstu z Wikipedii i chcesz Wikipedia mogła zaakceptować tekst skopiowany z twojej wiki, należy wybrać <strong>{{int:config-license-cc-by-sa}}</strong>.\n\nWikipedia używała poprzednio GNU Free Documentation License.\nGFDL jest poprawną licencję, ale trudno ją zrozumieć.\nTrudno także ponowne użyć zawartości na licencji GFDL.",
        "config-email-settings": "Ustawienia e-maili",
        "config-enable-email": "Włącz wychodzące wiadomości e–mail",
        "config-enable-email-help": "Jeśli chcesz, aby działał e-mail, [http://www.php.net/manual/en/mail.configuration.php Ustawienia poczty PHP] muszą być poprawnie wprowadzone.\nJeśli nie chcesz jakichś funkcji poczty e-mail, można je wyłączyć tutaj.",
index cb6cefb..2d58010 100644 (file)
        "config-db-name-oracle": "資料庫 Schema:",
        "config-db-account-oracle-warn": "目前有三種支援 Oracle 做為後端資料庫的方案:\n\n如果您希望在安裝的過程中自動建立新的資料庫,請提供具有 SYSDBA 權限的帳號並且提供未來要給網頁存取使用的資料庫帳號及密碼。或者您可以手動建立給網頁存取使用的資料庫帳號 (請確保該帳號有建立 Schema Object 的權限),再不然您可以提供兩組不同的帳號,一組用來建立權限,而另一組用來做為網頁存取使用。\n\n本次安裝建立的帳號以及權限所需要的 Script,可以在 \"maintenance/oracle/\" 中找到。\n請注意,若您使用有限制的帳號將會預設關閉所有維護性功能。",
        "config-db-install-account": "安裝程式使用的使用者帳號",
-       "config-db-username": "資料庫使用者名稱:",
+       "config-db-username": "資料庫用戶名:",
        "config-db-password": "資料庫密碼:",
        "config-db-password-empty": "請輸入新增資料庫使用者 $1 的密碼。\n雖然您可以不設定任何密碼,但這樣做並不安全。",
        "config-db-username-empty": "您必須輸入 \"{{int:config-db-username}}\" 欄位的內容。",
index 671e812..8c982c4 100644 (file)
@@ -116,7 +116,7 @@ class MultiHttpClient {
         * This is true for the request headers and the response headers. Integer-indexed
         * method/URL entries will also be changed to use the corresponding string keys.
         *
-        * @param array $req Map of HTTP request arrays
+        * @param array $reqs Map of HTTP request arrays
         * @param array $opts
         *   - connTimeout     : connection timeout per request
         *   - reqTimeout      : post-connection timeout per request
index 053c586..dd41c38 100644 (file)
@@ -97,7 +97,7 @@ class BitmapMetadataHandler {
        /** Add misc metadata. Warning: atm if the metadata category
         * doesn't have a priority, it will be silently discarded.
         *
-        * @param array $meta Array of metadata values
+        * @param array $metaArray Array of metadata values
         * @param string $type Type. defaults to other. if two things have the same type they're merged
         */
        function addMetadata( $metaArray, $type = 'other' ) {
index d285c0c..818bb25 100644 (file)
@@ -586,7 +586,7 @@ class Exif {
                return 2; // We don't need no bloddy constants!
        }
 
-       /**#@+
+       /**
         * Validates if a tag value is of the type it should be according to the Exif spec
         *
         * @param mixed $in The input value to check
index 969bb72..13c2a91 100644 (file)
@@ -743,7 +743,7 @@ abstract class MediaHandler {
                // Do nothing
        }
 
-       /*
+       /**
         * True if the handler can rotate the media
         * @since 1.21
         * @return bool
index a0ce806..74e5e04 100644 (file)
@@ -107,6 +107,7 @@ class SvgHandler extends ImageHandler {
        /**
         * What language to render file in if none selected.
         *
+        * @param File $file
         * @return string Language code.
         */
        public function getDefaultRenderLanguage( File $file ) {
@@ -115,6 +116,8 @@ class SvgHandler extends ImageHandler {
 
        /**
         * We do not support making animated svg thumbnails
+        * @param File $file
+        * @return bool
         */
        function canAnimateThumbnail( $file ) {
                return false;
index 04099c3..aa77fa8 100644 (file)
@@ -155,7 +155,7 @@ class XCFHandler extends BitmapHandler {
         *
         * @param File $file The image object, or false if there isn't one.
         *   Warning, FSFile::getPropsFromPath might pass an (object)array() instead (!)
-        * @param string $path The filename
+        * @param string $filename The filename
         * @return string
         */
        public function getMetadata( $file, $filename ) {
@@ -218,6 +218,8 @@ class XCFHandler extends BitmapHandler {
         *
         * Image magick doesn't support indexed xcf files as of current
         * writing (as of 6.8.9-3)
+        * @param File $file
+        * @return bool
         */
        public function canRender( $file ) {
                wfSuppressWarnings();
index 79a6841..59191d7 100644 (file)
@@ -78,8 +78,8 @@ class MemcachedBagOStuff extends BagOStuff {
        }
 
        /**
-        * @param string $key
         * @param mixed $casToken
+        * @param string $key
         * @param mixed $value
         * @param int $exptime
         * @return bool
index c7d2f13..ae8cc5b 100644 (file)
@@ -342,6 +342,7 @@ class RedisBagOStuff extends BagOStuff {
 
        /**
         * Get a Redis object with a connection suitable for fetching the specified key
+        * @param string $key
         * @return array (server, RedisConnRef) or (false, false)
         */
        protected function getConnection( $key ) {
index 32996ac..5872079 100644 (file)
@@ -27,6 +27,9 @@
  * @ingroup Cache
  */
 class SqlBagOStuff extends BagOStuff {
+       /** @var LoadBalancer */
+       protected $lb;
+
        protected $serverInfos;
 
        /** @var array */
@@ -143,12 +146,14 @@ class SqlBagOStuff extends BagOStuff {
                                $db = DatabaseBase::factory( $type, $info );
                                $db->clearFlag( DBO_TRX );
                        } else {
-                               // We must keep a separate connection to MySQL in order to avoid deadlocks
-                               // However, SQLite has an opposite behavior.
-                               // @todo get this trick to work on PostgreSQL too
+                               /*
+                                * We must keep a separate connection to MySQL in order to avoid deadlocks
+                                * However, SQLite has an opposite behavior. And PostgreSQL needs to know
+                                * if we are in transaction or no
+                                */
                                if ( wfGetDB( DB_MASTER )->getType() == 'mysql' ) {
-                                       $lb = wfGetLBFactory()->newMainLB();
-                                       $db = $lb->getConnection( DB_MASTER );
+                                       $this->lb = wfGetLBFactory()->newMainLB();
+                                       $db = $this->lb->getConnection( DB_MASTER );
                                        $db->clearFlag( DBO_TRX ); // auto-commit mode
                                } else {
                                        $db = wfGetDB( DB_MASTER );
@@ -516,6 +521,7 @@ class SqlBagOStuff extends BagOStuff {
        }
 
        /**
+        * @param DatabaseBase $db
         * @param string $exptime
         * @return bool
         */
index 2a882ac..78a512c 100644 (file)
@@ -52,7 +52,7 @@ class WinCacheBagOStuff extends BagOStuff {
         * Store a value in the WinCache object cache
         *
         * @param string $key Cache key
-        * @param mixed $valueObject Value to store
+        * @param mixed $value Value to store
         * @param int $expire Expiration time
         * @return bool
         */
index 4a6e002..c54c692 100644 (file)
@@ -1551,9 +1551,9 @@ class Article implements Page {
                $user = $this->getContext()->getUser();
 
                # Check permissions
-               $permission_errors = $title->getUserPermissionsErrors( 'delete', $user );
-               if ( count( $permission_errors ) ) {
-                       throw new PermissionsError( 'delete', $permission_errors );
+               $permissionErrors = $title->getUserPermissionsErrors( 'delete', $user );
+               if ( count( $permissionErrors ) ) {
+                       throw new PermissionsError( 'delete', $permissionErrors );
                }
 
                # Read-only check...
index be5ce3f..47f64a2 100644 (file)
@@ -2314,8 +2314,8 @@ class WikiPage implements Page, IDBAccessObject {
         * @param Content $content Content submitted
         * @param User $user The relevant user
         * @param string $comment Comment submitted
-        * @param string $serialisation_format Format for storing the content in the database
         * @param bool $minor Whereas it's a minor modification
+        * @param string $serialisation_format Format for storing the content in the database
         */
        public function doQuickEditContent( Content $content, User $user, $comment = '', $minor = false,
                $serialisation_format = null
index 64febcc..2ca9d50 100644 (file)
@@ -517,6 +517,7 @@ class ParserOptions {
 
        /**
         * Extra key that should be present in the parser cache key.
+        * @param string $key
         */
        public function addExtraKey( $key ) {
                $this->mExtraKey .= '!' . $key;
index 95c0a16..75fc01f 100644 (file)
@@ -502,6 +502,7 @@ class ParserOutput extends CacheTime {
 
        /**
         * Fairly generic flag setter thingy.
+        * @param string $flag
         */
        public function setFlag( $flag ) {
                $this->mFlags[$flag] = true;
index e49afed..c0be7a1 100644 (file)
@@ -65,7 +65,7 @@ abstract class PoolCounterWork {
        /**
         * Do something with the error, like showing it to the user.
         *
-        * @param $status
+        * @param Status $status
         *
         * @return bool
         */
index 4cdb0ff..5e7e391 100644 (file)
@@ -45,9 +45,9 @@ class PoolWorkArticleView extends PoolCounterWork {
 
        /**
         * @param Page $page
+        * @param ParserOptions $parserOptions ParserOptions to use for the parse
         * @param int $revid ID of the revision being parsed.
         * @param bool $useParserCache Whether to use the parser cache.
-        * @param ParserOptions $parserOptions ParserOptions to use for the parse
         *   operation.
         * @param Content|string $content Content to parse or null to load it; may
         *   also be given as a wikitext string, for BC.
index 22d5cd4..627b4de 100644 (file)
@@ -58,7 +58,8 @@ class ProfilerSimpleUDP extends ProfilerStandard {
                                continue;
                        }
                        $pfline = sprintf( $wgUDPProfilerFormatString, $this->getProfileID(), $pfdata['count'],
-                               $pfdata['cpu'], $pfdata['cpu_sq'], $pfdata['real'], $pfdata['real_sq'], $entry );
+                               $pfdata['cpu'], $pfdata['cpu_sq'], $pfdata['real'], $pfdata['real_sq'], $entry,
+                               $pfdata['memory'] );
                        $length = strlen( $pfline );
                        /* printf("<!-- $pfline -->"); */
                        if ( $length + $plength > 1400 ) {
index 7fd86eb..cc13416 100644 (file)
@@ -339,6 +339,7 @@ class ProfilerStandard extends Profiler {
 
        /**
         * Callback to get a formatted line for the call tree
+        * @param array $entry
         * @return string
         */
        protected function getCallTreeLine( $entry ) {
@@ -514,6 +515,7 @@ class ProfilerStandard extends Profiler {
 
        /**
         * Dummy calls to wfProfileIn/wfProfileOut to calculate its overhead
+        * @param int $profileCount
         */
        protected static function calculateOverhead( $profileCount ) {
                wfProfileIn( '-overhead-total' );
index 768dd7f..0b0cd86 100644 (file)
@@ -28,7 +28,7 @@ interface RCFeedEngine {
        /**
         * Sends some text to the specified live feed.
         *
-        * @see RecentChange::cleanupForIRC
+        * @see IRCColourfulRCFeedFormatter::cleanupForIRC
         * @param array $feed The feed, as configured in an associative array
         * @param string $line The text to send
         * @return bool Success
index e30047a..198420c 100644 (file)
@@ -216,6 +216,7 @@ class ResourceLoader {
 
        /**
         * Register core modules and runs registration hooks.
+        * @param Config|null $config
         */
        public function __construct( Config $config = null ) {
                global $IP;
index 06f7146..8a223b0 100644 (file)
@@ -569,6 +569,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
        /**
         * Get the definition summary for this module.
         *
+        * @param ResourceLoaderContext $context
         * @return array
         */
        public function getDefinitionSummary( ResourceLoaderContext $context ) {
index ba37f42..45eb70f 100644 (file)
@@ -486,6 +486,7 @@ abstract class ResourceLoaderModule {
         *
         * @since 1.23
         *
+        * @param ResourceLoaderContext $context
         * @return int UNIX timestamp or 0 if no definition summary was provided
         *  by getDefinitionSummary()
         */
@@ -553,6 +554,7 @@ abstract class ResourceLoaderModule {
         *
         * @since 1.23
         *
+        * @param ResourceLoaderContext $context
         * @return array|null
         */
        public function getDefinitionSummary( ResourceLoaderContext $context ) {
index 67c42bb..78fe45c 100644 (file)
@@ -122,7 +122,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         * @param string $moduleName
         * @return array
         */
-       protected static function getImplicitDependencies( Array $registryData, $moduleName ) {
+       protected static function getImplicitDependencies( array $registryData, $moduleName ) {
                static $dependencyCache = array();
 
                // The list of implicit dependencies won't be altered, so we can
@@ -168,7 +168,7 @@ class ResourceLoaderStartUpModule extends ResourceLoaderModule {
         *  - string 'source'
         *  - string|false 'loader'
         */
-       public static function compileUnresolvedDependencies( Array &$registryData ) {
+       public static function compileUnresolvedDependencies( array &$registryData ) {
                foreach ( $registryData as $name => &$data ) {
                        if ( $data['loader'] !== false ) {
                                continue;
index d9ed91d..0472f1a 100644 (file)
@@ -184,6 +184,7 @@ abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
        /**
         * Get the definition summary for this module.
         *
+        * @param ResourceLoaderContext $context
         * @return array
         */
        public function getDefinitionSummary( ResourceLoaderContext $context ) {
index 086db3a..e92a533 100644 (file)
@@ -322,6 +322,7 @@ abstract class RevDelItem extends RevisionItemBase {
         * Returns true if the item is "current", and the operation to set the given
         * bits can't be executed for that reason
         * STUB
+        * @param int $newBits
         * @return bool
         */
        public function isHideCurrentOp( $newBits ) {
@@ -341,6 +342,7 @@ abstract class RevDelItem extends RevisionItemBase {
         * If the update fails because it did not match, the function should return
         * false. This prevents concurrency problems.
         *
+        * @param int $newBits
         * @return bool Success
         */
        abstract public function setBits( $newBits );
index dc52969..d4f8167 100644 (file)
@@ -189,7 +189,7 @@ class RevisionDeleter {
         * Suggest a target for the revision deletion
         * @since 1.22
         * @param string $typeName
-        * @param Title|null $title User-supplied target
+        * @param Title|null $target User-supplied target
         * @param array $ids
         * @return Title|null
         */
index 56bb0ac..0eb87e4 100644 (file)
@@ -120,6 +120,8 @@ class SearchEngine {
         * Transform search term in cases when parts of the query came as different
         * GET params (when supported), e.g. for prefix queries:
         * search=test&prefix=Main_Page/Archive -> test prefix:Main Page/Archive
+        * @param string $term
+        * @return string
         */
        function transformSearchTerm( $term ) {
                return $term;
@@ -152,6 +154,7 @@ class SearchEngine {
 
        /**
         * Really find the title match.
+        * @param string $searchterm
         * @return null|Title
         */
        private static function getNearMatchInternal( $searchterm ) {
index 57cdaf4..6953462 100644 (file)
@@ -447,6 +447,7 @@ class SearchHighlighter {
        /**
         * Basic wikitext removal
         * @protected
+        * @param string $text
         * @return mixed
         */
        function removeWiki( $text ) {
index 0d1663f..de701f7 100644 (file)
@@ -85,6 +85,8 @@ class SearchMssql extends SearchDatabase {
         * Does not do anything for generic search engine
         * subclasses may define this though
         *
+        * @param string $filteredTerm
+        * @param bool $fulltext
         * @return string
         */
        function queryRanking( $filteredTerm, $fulltext ) {
@@ -134,6 +136,8 @@ class SearchMssql extends SearchDatabase {
        }
 
        /** @todo document
+        * @param string $filteredText
+        * @param bool $fulltext
         * @return string
         */
        function parseQuery( $filteredText, $fulltext ) {
index 581d8bc..78eba2d 100644 (file)
@@ -303,6 +303,8 @@ class SearchMySQL extends SearchDatabase {
 
        /**
         * @since 1.18 (changed)
+        * @param string $filteredTerm
+        * @param bool $fulltext
         * @return array
         */
        function getCountQuery( $filteredTerm, $fulltext ) {
@@ -374,6 +376,7 @@ class SearchMySQL extends SearchDatabase {
        /**
         * Converts some characters for MySQL's indexing to grok it correctly,
         * and pads short words to overcome limitations.
+        * @param string $string
         * @return mixed|string
         */
        function normalizeText( $string ) {
@@ -422,6 +425,7 @@ class SearchMySQL extends SearchDatabase {
         * Armor a case-folded UTF-8 string to get through MySQL's
         * fulltext search without being mucked up by funny charset
         * settings or anything else of the sort.
+        * @param array $matches
         * @return string
         */
        protected function stripForSearchCallback( $matches ) {
index 4cfcec3..348da79 100644 (file)
@@ -125,6 +125,8 @@ class SearchOracle extends SearchDatabase {
         * Does not do anything for generic search engine
         * subclasses may define this though
         *
+        * @param string $filteredTerm
+        * @param bool $fulltext
         * @return string
         */
        function queryRanking( $filteredTerm, $fulltext ) {
@@ -172,6 +174,8 @@ class SearchOracle extends SearchDatabase {
        /**
         * Parse a user input search string, and return an SQL fragment to be used
         * as part of a WHERE clause
+        * @param string $filteredText
+        * @param bool $fulltext
         * @return string
         */
        function parseQuery( $filteredText, $fulltext ) {
index 05d5ca0..eee6930 100644 (file)
@@ -38,6 +38,8 @@ class SearchSqlite extends SearchDatabase {
         * Parse the user's query and transform it into an SQL fragment which will
         * become part of a WHERE clause
         *
+        * @param string $filteredText
+        * @param bool $fulltext
         * @return string
         */
        function parseQuery( $filteredText, $fulltext ) {
index c4de2ad..3750bad 100644 (file)
@@ -144,7 +144,7 @@ abstract class Skin extends ContextSource {
         * Factory method for loading a skin of a given type
         * @param string $key 'monobook', 'vector', etc.
         * @return Skin
-        * @deprecated Use SkinFactory instead
+        * @deprecated since 1.24; Use SkinFactory instead
         */
        static function &newFromKey( $key ) {
                wfDeprecated( __METHOD__, '1.24' );
@@ -415,7 +415,7 @@ abstract class Skin extends ContextSource {
                return "$numeric $type $name";
        }
 
-       /*
+       /**
         * Return values for <html> element
         * @return array of associative name-to-value elements for <html> element
         */
index 51aced9..0935e33 100644 (file)
@@ -34,10 +34,19 @@ class SkinFactory {
         */
        private $factoryFunctions = array();
        /**
-        * Map of name => human readable name
+        * Map of name => fallback human-readable name, used when the 'skinname-<skin>' message is not
+        * available
+        *
         * @var array
         */
        private $displayNames = array();
+       /**
+        * Map of name => class name without "Skin" prefix, for legacy skins using the autodiscovery
+        * mechanism
+        *
+        * @var array
+        */
+       private $legacySkins = array();
 
        /**
         * @var SkinFactory
@@ -53,11 +62,16 @@ class SkinFactory {
        }
 
        /**
-        * Register a new Skin factory function
-        * Will override if it's already registered
-        * @param string $name
-        * @param string $displayName
-        * @param callable $callback That takes the skin name as an argument
+        * Register a new Skin factory function.
+        *
+        * Will override if it's already registered.
+        *
+        * @param string $name Internal skin name. Should be all-lowercase (technically doesn't have
+        *     to be, but doing so would change the case of i18n message keys).
+        * @param string $displayName For backwards-compatibility with old skin loading system. This is
+        *     the text used as skin's human-readable name when the 'skinname-<skin>' message is not
+   *     available. It should be the same as the skin name provided in $wgExtensionCredits.
+        * @param callable $callback Callback that takes the skin name as an argument
         * @throws InvalidArgumentException If an invalid callback is provided
         */
        public function register( $name, $displayName, $callback ) {
@@ -72,10 +86,9 @@ class SkinFactory {
         * @return array
         */
        private function getLegacySkinNames() {
-               global $wgValidSkinNames;
                static $skinsInitialised = false;
 
-               if ( !$skinsInitialised || !count( $wgValidSkinNames ) ) {
+               if ( !$skinsInitialised || !count( $this->legacySkins ) ) {
                        # Get a list of available skins
                        # Build using the regular expression '^(.*).php$'
                        # Array keys are all lower case, array value keep the case used by filename
@@ -117,7 +130,7 @@ class SkinFactory {
                                                        "The mechanism will be removed in MediaWiki 1.25 and the skin will no longer be recognized. " .
                                                        "See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for information how to fix this."
                                                );
-                                               $wgValidSkinNames[strtolower( $aSkin )] = $aSkin;
+                                               $this->legacySkins[strtolower( $aSkin )] = $aSkin;
                                        }
                                }
                                $skinDir->close();
@@ -125,7 +138,7 @@ class SkinFactory {
                        $skinsInitialised = true;
                        wfProfileOut( __METHOD__ . '-init' );
                }
-               return $wgValidSkinNames;
+               return $this->legacySkins;
 
        }
 
@@ -143,8 +156,7 @@ class SkinFactory {
        }
 
        /**
-        * Get a legacy skin which uses $wgValidSkinNames
-        * or autoloading
+        * Get a legacy skin which uses the autodiscovery mechanism.
         *
         * @param string $name
         * @return Skin|bool false if the skin couldn't be constructed
@@ -185,7 +197,7 @@ class SkinFactory {
         */
        public function makeSkin( $name ) {
                if ( !isset( $this->factoryFunctions[$name] ) ) {
-                       // Check the legacy method of skin loading
+                       // Check the legacy autodiscovery method of skin loading
                        $legacy = $this->getLegacySkin( $name );
                        if ( $legacy ) {
                                return $legacy;
index 30ea97d..b63f7a1 100644 (file)
@@ -19,7 +19,7 @@ class SkinFallback extends SkinTemplate {
        /**
         * Add CSS via ResourceLoader
         *
-        * @param $out OutputPage
+        * @param OutputPage $out
         */
        public function setupSkinUserCss( OutputPage $out ) {
                parent::setupSkinUserCss( $out );
index 0703b0e..603ee5c 100644 (file)
@@ -40,7 +40,7 @@ class SkinFallbackTemplate extends BaseTemplate {
        private function buildHelpfulInformationMessage() {
                $defaultSkin = $this->config->get( 'DefaultSkin' );
                $installedSkins = $this->findInstalledSkins();
-               $enabledSkins = $this->config->get( 'ValidSkinNames' );
+               $enabledSkins = SkinFactory::getDefaultInstance()->getSkinNames();
                $enabledSkins = array_change_key_case( $enabledSkins, CASE_LOWER );
 
                if ( $installedSkins ) {
index 867d8ec..b6077b3 100644 (file)
@@ -271,7 +271,7 @@ class SkinTemplate extends Skin {
                wfProfileIn( __METHOD__ . '-init' );
                $this->initPage( $out );
                wfProfileOut( __METHOD__ . '-init' );
-               $tpl = $this->prepareQuickTemplate( $out );
+               $tpl = $this->prepareQuickTemplate();
                // execute template
                wfProfileIn( __METHOD__ . '-execute' );
                $res = $tpl->execute();
@@ -1375,8 +1375,9 @@ abstract class QuickTemplate {
 
        /** @var Config $config */
        protected $config;
+
        /**
-        * @var Config $config
+        * @param Config $config
         */
        function __construct( Config $config = null ) {
                $this->data = array();
index 572eacc..ce43652 100644 (file)
@@ -46,6 +46,11 @@ class ActiveUsersPager extends UsersPager {
         */
        protected $hideRights = array();
 
+       /**
+        * @var array
+        */
+       private $blockStatusByUid;
+
        /**
         * @param IContextSource $context
         * @param null $group Unused
index 867fd1b..24664ed 100644 (file)
@@ -43,6 +43,7 @@ class SpecialChangePassword extends FormSpecialPage {
 
        /**
         * Main execution point
+        * @param string|null $par
         */
        function execute( $par ) {
                $this->getOutput()->disallowUserJs();
@@ -229,6 +230,9 @@ class SpecialChangePassword extends FormSpecialPage {
        }
 
        /**
+        * @param string $oldpass
+        * @param string $newpass
+        * @param string $retype
         * @throws PasswordError When cannot set the new password because requirements not met.
         */
        protected function attemptReset( $oldpass, $newpass, $retype ) {
index 15a5b74..af8ab58 100644 (file)
@@ -163,7 +163,7 @@ class SpecialContributions extends IncludableSpecialPage {
                }
 
                if ( $feedType ) {
-                       // Maintain some level of backwards compatability
+                       // Maintain some level of backwards compatibility
                        // If people request feeds using the old parameters, redirect to API
                        $feedParams['feedformat'] = $feedType;
                        $url = wfAppendQuery( wfScript( 'api' ), $feedParams );
index 60eec39..269dff6 100644 (file)
@@ -50,6 +50,7 @@ class SpecialExpandTemplates extends SpecialPage {
 
        /**
         * Show the special page
+        * @param string|null $subpage
         */
        function execute( $subpage ) {
                global $wgParser;
index 2d72d62..2a3ab64 100644 (file)
@@ -49,6 +49,7 @@ class SpecialImport extends SpecialPage {
 
        /**
         * Execute
+        * @param string|null $par
         */
        function execute( $par ) {
                $this->setHeaders();
index 582f743..b5818ea 100644 (file)
@@ -35,6 +35,7 @@ class SpecialListGroupRights extends SpecialPage {
 
        /**
         * Show the special page
+        * @param string|null $par
         */
        public function execute( $par ) {
                global $wgImplicitGroups;
index 774fd80..2022d74 100644 (file)
@@ -55,6 +55,7 @@ class SpecialRedirect extends FormSpecialPage {
 
        /**
         * Set $mType and $mValue based on parsed value of $subpage.
+        * @param string $subpage
         */
        function setParameter( $subpage ) {
                // parse $subpage to pull out the parts
index bc1326b..6c5401a 100644 (file)
@@ -112,6 +112,7 @@ class SpecialResetTokens extends FormSpecialPage {
        /**
         * Suppress the submit button if there's nothing to do;
         * provide additional message on it otherwise.
+        * @param HTMLForm $form
         */
        protected function alterForm( HTMLForm $form ) {
                if ( $this->getTokensList() ) {
index 93df289..7eea71d 100644 (file)
@@ -622,6 +622,7 @@ class SpecialRevisionDelete extends UnlistedSpecialPage {
 
        /**
         * Report that the submit operation failed
+        * @param Status $status
         */
        protected function failure( $status ) {
                // Messages: revdelete-failure, logdelete-failure
index 5f16239..6419a57 100644 (file)
@@ -1068,6 +1068,8 @@ class SpecialSearch extends SpecialPage {
 
        /**
         * @param string $term
+        * @param int $resultsShown
+        * @param int $totalNum
         * @return string
         */
        protected function shortDialog( $term, $resultsShown, $totalNum ) {
index fe0638e..bb07c19 100644 (file)
@@ -72,6 +72,7 @@ class UnwatchedpagesPage extends QueryPage {
 
        /**
         * Add the JS
+        * @param string|null $par
         */
        public function execute( $par ) {
                parent::execute( $par );
index bd7457e..afa12a0 100644 (file)
@@ -220,7 +220,7 @@ class LoginForm extends SpecialPage {
                }
        }
 
-       /*
+       /**
         * @param string|null $subPage
         */
        public function execute( $subPage ) {
@@ -1237,6 +1237,8 @@ class LoginForm extends SpecialPage {
        }
 
        /**
+        * @param string $msg
+        * @param string $msgtype
         * @private
         */
        function mainLoginForm( $msg, $msgtype = 'error' ) {
@@ -1278,6 +1280,7 @@ class LoginForm extends SpecialPage {
                $out->addModuleStyles( array(
                        'mediawiki.ui',
                        'mediawiki.ui.button',
+                       'mediawiki.ui.checkbox',
                        'mediawiki.ui.input',
                        'mediawiki.special.userlogin.common.styles'
                ) );
@@ -1522,6 +1525,7 @@ class LoginForm extends SpecialPage {
        }
 
        /**
+        * @param string $type
         * @private
         */
        function cookieRedirectCheck( $type ) {
@@ -1537,6 +1541,7 @@ class LoginForm extends SpecialPage {
        }
 
        /**
+        * @param string $type
         * @private
         */
        function onCookieRedirectCheck( $type ) {
index 318ceb1..87ab41c 100644 (file)
@@ -50,6 +50,7 @@ class SpecialVersion extends SpecialPage {
 
        /**
         * main()
+        * @param string|null $par
         */
        public function execute( $par ) {
                global $IP, $wgExtensionCredits;
index f1e7065..01da0bd 100644 (file)
@@ -94,14 +94,15 @@ class UsercreateTemplate extends BaseTemplate {
 
                        <div class="mw-ui-vform-field">
                                <?php if ( $this->data['createemail'] ) { ?>
-                                       <label class="mw-ui-checkbox-label">
+                                       <div class="mw-ui-checkbox">
                                                <input name="wpCreateaccountMail" type="checkbox" value="1" id="wpCreateaccountMail" tabindex="2"
                                                        <?php if ( $this->data['createemailset'] ) {
                                                                echo 'checked="checked"';
                                                        } ?>
-                                               >
-                                               <?php $this->msg( 'createaccountmail' ); ?>
-                                       </label>
+                                               ><label for="wpCreateaccountMail">
+                                                       <?php $this->msg( 'createaccountmail' ); ?>
+                                               </label>
+                                       </div>
                                <?php } ?>
                        </div>
 
@@ -207,7 +208,7 @@ class UsercreateTemplate extends BaseTemplate {
                                                // If it's a checkbox, output the whole thing (assume it has a msg).
                                                if ( $inputItem['type'] == 'checkbox' ) {
                                                ?>
-                                                       <label class="mw-ui-checkbox-label">
+                                                       <div class="mw-ui-checkbox">
                                                                <input
                                                                        name="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
                                                                        id="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
@@ -216,9 +217,8 @@ class UsercreateTemplate extends BaseTemplate {
                                                                        <?php if ( !empty( $inputItem['value'] ) ) {
                                                                                echo 'checked="checked"';
                                                                        } ?>
-                                                               >
-                                                               <?php $this->msgHtml( $inputItem['msg'] ); ?>
-                                                       </label>
+                                                               ><label for="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"></label>
+                                                       </div><?php $this->msgHtml( $inputItem['msg'] ); ?>
                                                <?php
                                                } else {
                                                        // Not a checkbox.
index 7187e8c..8bba426 100644 (file)
@@ -135,14 +135,14 @@ class UserloginTemplate extends BaseTemplate {
 
                        <div class="mw-ui-vform-field">
                                <?php if ( $this->data['canremember'] ) { ?>
-                                       <label class="mw-ui-checkbox-label">
+                                       <div class="mw-ui-checkbox">
                                                <input name="wpRemember" type="checkbox" value="1" id="wpRemember" tabindex="4"
                                                        <?php if ( $this->data['remember'] ) {
                                                                echo 'checked="checked"';
                                                        } ?>
-                                               >
-                                               <?php echo $this->getMsg( 'userlogin-remembermypassword' )->numParams( $expirationDays )->escaped(); ?>
-                                       </label>
+                                               ><label for="wpRemember">
+                                                       <?php echo $this->getMsg( 'userlogin-remembermypassword' )->numParams( $expirationDays )->escaped(); ?></label>
+                                       </div>
                                <?php } ?>
                        </div>
 
index 4d74a2d..5de543e 100644 (file)
@@ -171,6 +171,7 @@ abstract class UploadBase {
                        return null;
                }
 
+               /** @var UploadBase $handler */
                $handler = new $className;
 
                $handler->initializeFromRequest( $request );
@@ -882,7 +883,7 @@ abstract class UploadBase {
        /**
         * Return the local file and initializes if necessary.
         *
-        * @return LocalFile|null
+        * @return LocalFile|UploadStashFile|null
         */
        public function getLocalFile() {
                if ( is_null( $this->mLocalFile ) ) {
@@ -1498,7 +1499,7 @@ abstract class UploadBase {
 
        /**
         * Divide the element name passed by the xml parser to the callback into URI and prifix.
-        * @param string $name
+        * @param string $element
         * @return array Containing the namespace URI and prefix
         */
        private static function splitXmlNamespace( $element ) {
@@ -1884,7 +1885,7 @@ abstract class UploadBase {
         * Get the current status of a chunked upload (used for polling).
         * The status will be read from the *current* user session.
         * @param string $statusKey
-        * @return array|bool
+        * @return Status[]|bool
         */
        public static function getSessionStatus( $statusKey ) {
                return isset( $_SESSION[self::SESSION_STATUS_KEY][$statusKey] )
index bea7128..d86de79 100644 (file)
@@ -32,6 +32,8 @@ class UploadFromChunks extends UploadFromFile {
        protected $mChunkIndex;
        protected $mFileKey;
        protected $mVirtualTempPath;
+       /** @var LocalRepo */
+       private $repo;
 
        /**
         * Setup local pointers to stash, repo and user (similar to UploadFromStash)
index 8610386..6c53249 100644 (file)
@@ -257,8 +257,8 @@ class MWCryptHKDF {
         * and the SKM (source key material) is the "data".
         *
         * @param string $hash The hashing function to use (e.g., sha256)
-        * @param string $ikm The input keying material
         * @param string $salt The salt to add to the ikm, to get the prk
+        * @param string $ikm The input keying material
         * @return string Binary string (pseudorandm key) used as input to HKDFExpand
         */
        private static function HKDFExtract( $hash, $salt, $ikm ) {
index 604d381..dffe242 100644 (file)
@@ -117,7 +117,7 @@ class UIDGenerator {
        }
 
        /**
-        * @param array $time (UIDGenerator::millitime(), clock sequence)
+        * @param array $info (UIDGenerator::millitime(), clock sequence)
         * @return string 88 bits
         */
        protected function getTimestampedID88( array $info ) {
index 99dc184..cd8df5d 100644 (file)
@@ -345,7 +345,7 @@ class Language {
        /**
         * Returns true if a language code is an IETF tag known to MediaWiki.
         *
-        * @param string $code
+        * @param string $tag
         *
         * @since 1.21
         * @return bool
@@ -3808,8 +3808,8 @@ class Language {
         * Checks that convertPlural was given an array and pads it to requested
         * amount of forms by copying the last one.
         *
-        * @param int $count How many forms should there be at least
         * @param array $forms Array of forms given to convertPlural
+        * @param int $count How many forms should there be at least
         * @return array Padded array of forms or an exception if not an array
         */
        protected function preConvertPlural( /* Array */ $forms, $count ) {
@@ -4740,6 +4740,7 @@ class Language {
 
        /**
         * Find the index number of the plural rule appropriate for the given number
+        * @param int $number
         * @return int The index number of the plural rule
         */
        public function getPluralRuleIndexNumber( $number ) {
@@ -4753,6 +4754,7 @@ class Language {
         * For example, if the language is set to Arabic, getPluralType(5) should
         * return 'few'.
         * @since 1.22
+        * @param int $number
         * @return string The name of the plural rule type, e.g. one, two, few, many
         */
        public function getPluralRuleType( $number ) {
index 8f0e7d1..2dae621 100644 (file)
@@ -9,7 +9,8 @@
                        "ZxxZxxZ",
                        "아라",
                        "RigiMahnoor",
-                       "Oldstoneage"
+                       "Oldstoneage",
+                       "Baloch Afghanistan"
                ]
        },
        "tog-underline": ":لینکانآ خط کش",
        "searchprofile-advanced-tooltip": "گردگ ته نام فضایان دل واه",
        "search-result-size": "$1 ({{PLURAL:$2|1کلمه|$2 کلمات}})",
        "search-result-category-size": "{{PLURAL:$1|یک عضو|$1 عضو}} ({{PLURAL:$2|یک جهلرده|$2 جهلرده}}، {{PLURAL:$3|یک فایل|$3 فایل}})",
-       "search-result-score": "ربط: $1%",
        "search-redirect": "(غیر مستقیم $1 )",
        "search-section": "(بخش $1 )",
        "search-file-match": "(فایلء محتواء همجندی)",
        "file-deleted-duplicate": "یک فایلی په داب ای فایل ([[:$1]]) پیسرتر حذف بوتگت. شما بایدن تاریح حذف آ فایلء دگه بچاریت",
        "uploadwarning": "هوژاری آپلود",
        "savefile": "ذخیره فایل",
-       "uploadedimage": "اپلود بوت \"[[$1]]\"",
-       "overwroteimage": "یک نوکین نسخه چه \"[[$1]]\" آپلود بیتت",
        "uploaddisabled": "آپ.د غبر فعال انت",
        "uploaddisabledtext": "آپلود فایل غیر فعال انت.",
        "php-uploaddisabledtext": "آپلود کتن فایل ته پی‌اچ‌پی فعال نهنت. تنظیم file_uploads کنترل کنیت.",
        "watchlist-details": "{{PLURAL:$1|$1 صفحه|$1 صفحات}} چارتگ بیت صفحات گپ حساب نه بیگن",
        "wlheader-enotif": "اخطار ایمیل فعالنت.",
        "wlheader-showupdated": "صفحات که عوض بوتگنت چه شمی آهری چارتن '''پررنگ''' پیش دراگ بنت.",
+       "wlnote": "جهلء {{PLURAL:$1|آهرین تغییر هست|آهرین هست'''$1''' تغییرات}} ته آهرین {{PLURAL:$2|ساعت|'''$2''' ساعات}}.",
        "wlshowlast": "پیش دار آهرین $1  ساعات $2 روچان $3",
        "watchlist-options": "گزینه یان لیست چارگ",
        "watching": "چارگ بین",
        "delete-edit-reasonlist": "اصلاح کن دلایل حذفء",
        "delete-toobig": "صفحهء یک مزنین تاریح اصلاحی هست گیشتر چه $1 {{PLURAL:$1|بازبینی|بازبینی}}.\nحذف چوشین صفحات په خاظر جلو گر چه ناگهانی اتفاق ته سایت {{SITENAME}} ممنوع بوتت.",
        "delete-warning-toobig": "ای صفحه  مزنین تاریح اصلاح هست، گیش چه  $1 {{PLURAL:$1|بازبینی|بازبینی}}.\nحذف آی شاید کار دیتابیس  {{SITENAME}} قطع کنت؛\nگون اخطار پیش روت.",
+       "delete-cantedit": "شما نه توانیت ای صپحا پاک کنیت بی خاطیریکه شما اجازه نداریت آیرا ایڈیت کنیت.",
        "rollback": "پشت ترگ اصلاحات",
        "rollback_short": "پشتررگ",
        "rollbacklink": "عقب ترگ",
index cd17741..0fb698e 100644 (file)
        "parser-template-recursion-depth-warning": "Перавышана мяжа глыбіні рэкурсіі шаблёнаў ($1)",
        "language-converter-depth-warning": "Перавышанае абмежаваньне глыбіні канвэртару варыянтаў мовы ($1)",
        "node-count-exceeded-category": "Старонкі зь перавышанай колькасьцю вузлоў",
-       "node-count-exceeded-category-desc": "Ð\9aаÑ\82Ñ\8dгоÑ\80Ñ\8bÑ\8f Ð´Ð»Ñ\8f Ñ\81Ñ\82аÑ\80онак, Ð½Ð° Ñ\8fкÑ\96Ñ\85 Ð¿ÐµÑ\80авÑ\8bÑ\88аная колькасьць вузлоў.",
+       "node-count-exceeded-category-desc": "Ð\9dа Ñ\81Ñ\82аÑ\80онÑ\86Ñ\8b Ð¿ÐµÑ\80авÑ\8bÑ\88анаÑ\8f Ð¼Ð°ÐºÑ\81Ñ\8bмалÑ\8cная колькасьць вузлоў.",
        "node-count-exceeded-warning": "Старонка перавысіла дазволеную колькасьць вузлоў",
        "expansion-depth-exceeded-category": "Старонкі зь перавышанай глыбінёй уключэньня",
        "expansion-depth-exceeded-category-desc": "Гэта катэгорыя для старонак, дзе перавышаная глыбіня раскрыцьця.",
        "delete-edit-reasonlist": "Рэдагаваць прычыны выдаленьня",
        "delete-toobig": "Гэтая старонка мае доўгую гісторыю рэдагаваньняў, болей за $1 {{PLURAL:$1|вэрсію|вэрсіі|вэрсіяў}}.\nВыдаленьне такіх старонак было забароненае, каб пазьбегнуць праблемаў у працы {{GRAMMAR:родны|{{SITENAME}}}}.",
        "delete-warning-toobig": "Гэтая старонка мае доўгую гісторыю рэдагаваньняў, больш за $1 {{PLURAL:$1|вэрсію|вэрсіі|вэрсіяў}}.\nЯе выдаленьне можа выклікаць праблемы ў працы базы зьвестак {{GRAMMAR:родны|{{SITENAME}}}}; будзьце асьцярожны.",
+       "delete-cantedit": "Вы ня можаце выдаліць гэтую старонку, таму што ня маеце правоў на яе рэдагаваньне.",
        "deleting-backlinks-warning": "'''Увага:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|іншыя старонкі]] ўключаюць або спасылаюцца на старонку, якую вы зьбіраецеся выдаліць.",
        "rollback": "Адкаціць рэдагаваньні",
        "rollback_short": "Адкат",
index 40e840a..73e5b9c 100644 (file)
        "hidetoc": "не паказваць",
        "collapsible-collapse": "Схаваць",
        "collapsible-expand": "Паказаць",
+       "confirmable-confirm": "{{GENDER:$1|Вы}} ўпэўнены?",
+       "confirmable-yes": "Так",
+       "confirmable-no": "Не",
        "thisisdeleted": "Паказаць ці аднавіць $1?",
        "viewdeleted": "Ці паказаць $1?",
        "restorelink": "$1 {{PLURAL:$1|сцёртая праўка|сцёртыя праўкі|сцёртых правак}}",
        "delete-edit-reasonlist": "Правіць прычыны сцірання",
        "delete-toobig": "Старонка мае вялікую гісторыю правак, больш за $1 {{PLURAL:$1|версію|версій}}. Сціранне такіх старонак было абмежавана, каб пазбегчы ўтварэння выпадковых перашкод працы {{SITENAME}}.",
        "delete-warning-toobig": "Старонка мае вялікую гісторыю правак, больш за $1 {{PLURAL:$1|версію|версій}}. Сціранне такіх старонак можа перашкодзіць працы базы даных {{SITENAME}}; будзьце асцярожнымі.",
+       "delete-cantedit": "Вы не можаце сцерці гэту старонку, таму што не маеце дазволу правіць яе.",
        "deleting-backlinks-warning": "'''Увага:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Іншыя старонкі]] спасылаюцца на ці ўключаюць старонку, якую вы збіраецеся сцерці.",
        "rollback": "Адкаціць праўкі",
        "rollback_short": "Адкат",
        "autoblockid": "Аўтаблакіроўка #$1",
        "block": "Заблакаваць удзельніка",
        "unblock": "Разблакаваць удзельніка",
-       "blockip": "Заблакаваць удзельніка",
+       "blockip": "Заблакаваць {{GENDER:$1|удзельніка|удзельніцу}}",
        "blockip-legend": "Заблакаваць удзельніка",
        "blockiptext": "Гэты фармуляр дазваляе заблакаваць магчымасць запісу для пэўнага адрасу IP ці імя ўдзельніка.\nГэта трэба рабіць толькі дзеля засцерагання ад вандалізму і ў адпаведнасці з [[{{MediaWiki:Policy-url}}|правіламі]].\nНіжэй трэба ўпісаць канкрэтную прычыну (напрыклад, пералічваючы канкрэтныя старонкі, якія былі вандалізаваныя).",
        "ipaddressorusername": "IP-адрас ці імя ўдзельніка:",
        "ipb-unblock-addr": "Зняць блок з $1",
        "ipb-unblock": "Зняць блок з імя ўдзельніка або адрасу IP",
        "ipb-blocklist": "Паказаць наяўныя блокі",
-       "ipb-blocklist-contribs": "Уклад $1",
+       "ipb-blocklist-contribs": "Уклад {{GENDER:$1|$1}}",
        "unblockip": "Зняць блок з удзельніка",
        "unblockiptext": "У форме, што ніжэй, можна вярнуць дазвол на запіс для раней заблакаванага адрасу IP або ўдзельніка.",
        "ipusubmit": "Зняць гэты блок",
        "log-name-pagelang": "Журнал змянення мовы",
        "log-description-pagelang": "Гэта журнал змяненняў у мовах старонкі.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|змяніў|змяніла}} мову старонкі $3 з $4 на $5.",
+       "default-skin-not-found": "Упс! Прадвызначаная вокладка для вашай вікі (<code>$wgDefaultSkin</code>), <code>$1</code>, недаступна.\n\nВыглядае на тое, што ваша інсталяцыя ўключае наступныя вокладкі. Гл. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя: Устаноўка вокладак] дзеля інфармацыі па ўключэнні і выбару прадвызначанай вокладкі.\n\n$2\n\n; Калі вы толькі што ўстанавілі MediaWiki:\n: Магчыма, вы ўстанавілі з git, ці наўпрост з зыходнага коду, выкарыстаўшы іншы метад. Гэта нармальна. Паспрабуйце ўстанавіць некалькі вокладак з [https://www.mediawiki.org/wiki/Category:All_skins каталога вокладак mediawiki.org], такім чынам:\n:* Узяўшы [https://www.mediawiki.org/wiki/Download tarball-інсталятар], які ўтрымлівае некалькі вокладак і прыставак. Вы можаце скапіяваць і ўставіць каталог <code>skins/</code> з яго.\n:* Зрабіўшы клон  аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталог <code>skins/</code> вашай інсталяцыі MediaWiki.\n: Калі вы распрацоўшчык MediaWiki, гэта не павінна ўплываць на ваша git-сховішча.\n\n; Калі вы толькі што абнавілі MediaWiki:\n: MediaWiki 1.24 і навейшыя больш не падключаюць вокладкі аўтаматычна (гл. [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Інструкцыя: Аўтавызначэнне вокладак]). Вы можаце ўставіць наступныя радкі ў <code>LocalSettings.php</code>, каб падключыць усе ўстаноўленыя вокладкі:\n\n<pre>$3</pre>\n\n; Калі вы толькі што змянілі <code>LocalSettings.php</code>:\n: Пераправерце назвы вокладак на прадмет памылак.",
+       "default-skin-not-found-no-skins": "Упс! Прадвызначаная вокладка для вашай вікі (<code>$wgDefaultSkin</code>), <code>$1</code>, недаступна.\n\nВы не ўстанавілі вокладкі.\n\n; Калі вы толькі што ўстанавілі ці абнавілі MediaWiki:\n: Магчыма, вы ўстанавілі з git, ці наўпрост з зыходнага коду, выкарыстаўшы іншы метад. Гэта нармальна. MediaWiki 1.24 і навейшыя не ўключаюць вокладкі ў асноўнае сховішча. Паспрабуйце ўстанавіць некалькі вокладак з [https://www.mediawiki.org/wiki/Category:All_skins каталога вокладак mediawiki.org], такім чынам:\n:* Узяўшы [https://www.mediawiki.org/wiki/Download tarball-інсталятар], які ўтрымлівае некалькі вокладак і прыставак. Вы можаце скапіяваць і ўставіць каталог <code>skins/</code> адтуль.\n:* Зрабіўшы клон аднаго з сховішчаў <code>mediawiki/skins/*</code> праз git у каталог <code>skins/</code> вашай інсталяцыі MediaWiki.\n: Калі вы распрацоўшчык MediaWiki, гэта не павінна адбіцца на вашым git-сховішчы. Гл. [https://www.mediawiki.org/wiki/Manual:Skin_configuration Інструкцыя: Настройка вокладак] дзеля інфармацыі па ўключэнні вокладак і выбары прадвызначэння.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (уключана)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''выключана''')"
 }
index c993c30..425390c 100644 (file)
        "pool-timeout": "সময় উত্তির্ণ লক-এর জন্য অপেক্ষারত",
        "pool-queuefull": "পুলের লাইন পূর্ণ",
        "pool-errorunknown": "অজানা ত্রুটি",
+       "pool-servererror": "পুল কাউন্টার সার্ভিস নিষ্ক্রিয় ($1)।",
        "aboutsite": "{{SITENAME}} বৃত্তান্ত",
        "aboutpage": "Project:বৃত্তান্ত",
        "copyright": "বিষয়বস্তু $1-এর আওতায় প্রকাশিত যদি না অন্য কিছু নির্ধারিত থাকে।",
        "invalidtitle-knownnamespace": "অবৈধ শিরোনাম, যেখানে নামস্থান \"$2\" এবং লেখা হয়েছে \"$3\"",
        "invalidtitle-unknownnamespace": "অবৈধ শিরোনাম, যেখানে ব্যবহৃত হয়েছে অপরিচিত নামস্থান সংখ্যা $1 এবং লেখা হয়েছে \"$2\"",
        "exception-nologin": "লগইন করা হয়নি",
-       "exception-nologin-text": "এই কাজটি করার জন্য উইকিতে [[Special:Userlogin|লগইন]] করা প্রয়োজন।",
+       "exception-nologin-text": "এই কাজ করা বা পাতাটি দেখার জন্য অনুগ্রহ করে প্রবেশ করুন।",
        "exception-nologin-text-manual": "অনুগ্রহ করে এই পাতা দেখতে অথবা পরিবর্তন করতে $1 করুন।",
        "virus-badscanner": "ভুল কনফিগারেশন: অজ্ঞাত ভাইরাস স্কেনার: ''$1''",
        "virus-scanfailed": "স্ক্যান করা যাচ্ছে না (কোড $1)",
        "preview": "প্রাকদর্শন",
        "showpreview": "প্রাকদর্শন",
        "showdiff": "পরিবর্তনসমূহ",
+       "blankarticle": "<strong>সতর্ক বার্তা:</strong> আপনি একটি খালি পাতা তৈরী করতে যাচ্ছেন।\nআপনি যদি পুনরায় \"{{int:savearticle}}\" বাটন ক্লিক করেন তাহলে, পাতাটি তৈরী হবে যেখানে কোনো তথ্য লেখা নেই।",
        "anoneditwarning": "আপনি লগ ইন করেননি। এই পাতার সম্পাদনার ইতিহাসে আপনার আইপি সংখ্যা সংরক্ষিত হবে।",
        "anonpreviewwarning": "আপনি লগ ইন করেননি। এই পাতার সম্পাদনার ইতিহাসে আপনার আইপি সংখ্যা সংরক্ষিত হবে।",
        "missingsummary": "'''খেয়াল করুন''':  আপনি কিন্তু সম্পাদনার সারাংশ দেননি। আবার যদি \"সংরক্ষণ\" বোতামে ক্লিক করেন, তাহলে ঐ সারাংশ বাক্যটি ছাড়াই আপনার সম্পাদনা সংরক্ষিত হবে।",
        "parser-template-recursion-depth-warning": "টেমপ্লেট পুনরাবৃত্তি (রিকার্শন) ডেপথ্‌ সীমা অতক্রম করেছে ($1)",
        "language-converter-depth-warning": "ভাষা পরিবর্তন ডেপথ্‌ সীমা অতক্রম করেছে ($1)",
        "node-count-exceeded-category": "যে সকল পাতার নোড কাউন্ট সীমানা পার হয়েছে",
+       "node-count-exceeded-category-desc": "পাতার সর্বোচ্চ নোড কাউন্ট সীমানা অতিক্রম করেছে।",
        "node-count-exceeded-warning": "পাতাটি নোড কাউন্ট সীমানা পার করেছে",
        "expansion-depth-exceeded-category": "যে সকল পাতার এক্সেপশন সীমানা অতিক্রম করেছে",
+       "expansion-depth-exceeded-category-desc": "পাতাটি সর্বোচ্চ এক্সপশন সীমানা অতিক্রম করেছে।",
        "expansion-depth-exceeded-warning": "পাতাটি এক্সেপশন সীমানা অতিক্রম করেছে",
        "parser-unstrip-loop-warning": "ত্রুটিপূর্ণ লুপ খুঁজে পাওয়া গিয়েছে",
        "parser-unstrip-recursion-limit": "লুপ রিকারশন সীমানা অতিক্রম করেছে ($1)",
        "rev-deleted-event": "(লগ অ্যাকশন সরানো হয়েছে)",
        "rev-deleted-user-contribs": "ব্যবহারকারীর নাম অথবা আইপি ঠিকানা অপসারিত হয়েছে - অবদান থেকে সম্পাদনা আড়াল করা হয়েছে",
        "rev-deleted-text-permission": "পাতার এই সংস্করণটি '''অপসারিত''' হয়েছে।\nবিস্তারিত কারণ এর [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অপসারণ লগে] পাওয়া যেতে পারে।",
+       "rev-suppressed-text-permission": "পাতার এই সংশোধনটি <strong>গোপন</strong> করা হয়েছে।\nআপনি এটি দেখতে পারেন; এ সংক্রাস্ত বিস্তারিত বিবরণ[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} গোপনকার্যের লগে] থাকতে পারে।",
        "rev-deleted-text-unhide": "পাতার এই সংস্করণটি '''অপসারিত''' হয়েছে।\nবিস্তারিত কারণ এর [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অপসারণ লগে] পাওয়া যেতে পারে।\nআপনি ইচ্ছা পোষণ করলে [$1 এই সংস্করণটি দেখতে পারেন]।",
        "rev-suppressed-text-unhide": "পাতার এই সংস্করণটি '''অপসারিত''' হয়েছে।\nবিস্তারিত কারণ এর [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} অপসারণ লগে] পাওয়া যেতে পারে।\nআপনি ইচ্ছা পোষণ করলে [$1 এই সংস্করণটি দেখতে পারেন]।",
        "rev-deleted-text-view": "পাতার এই সংশোধনটি অপসারণ করা হয়েছে।\nআপনি এটি দেখতে পারেন; এ সংক্রাস্ত বিস্তারিত বিবরণ [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} অবলুপ্তি লগে] থাকতে পারে।",
        "powersearch-togglelabel": "পরীক্ষা:",
        "powersearch-toggleall": "সকল",
        "powersearch-togglenone": "কিছু নয়",
+       "powersearch-remember": "ভবিষ্যত অনুসন্ধানগুলির জন্য নির্বাচন মনে রাখুন",
        "search-external": "বহিঃস্থ অনুসন্ধান",
        "searchdisabled": "{{SITENAME}} অনুসন্ধান এখন নিষ্ক্রিয় আছে। আপনি গুগলের মাধ্যমে অনুসন্ধান চালাতে পারেন। লক্ষ্য করুন যে {{SITENAME}}-এর বিষয়বস্তুর উপর গুগলের ইন্ডেক্সগুলি হালনাগাদ না-ও করা থাকতে পারে।",
        "search-error": "অনুসন্ধানের সময় একটি ত্রুটি হয়েছে: $1",
        "preferences": "আমার পছন্দ",
        "mypreferences": "পছন্দসমূহ",
        "prefs-edits": "সম্পাদনা সংখ্যা:",
-       "prefsnologintext2": "বà§\8dযবহারà¦\95ারà§\80 à¦ªà¦\9bনà§\8dদসমà§\82হ à¦¨à¦¿à¦°à§\8dধারনà§\87র à¦\9cনà§\8dয $1 করুন।",
+       "prefsnologintext2": "à¦\86পনার à¦ªà¦\9bনà§\8dদসমà§\82হ à¦ªà¦°à¦¿à¦¬à¦°à§\8dতন à¦\95রতà§\87 à¦ªà§\8dরবà§\87শ করুন।",
        "prefs-skin": "আবরণ (Skin)",
        "skin-preview": "প্রাকদর্শন",
        "datedefault": "কোন পছন্দ নেই",
        "recentchanges-legend-heading": "'''ব্যাখ্যামূলক বর্ণনা:'''",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (আরও দেখুন [[Special:NewPages|নতুন পাতার তালিকা]])",
        "recentchanges-legend-plusminus": "(''±১২৩'')",
-       "rcnotefrom": "<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)",
+       "rcnotefrom": "<strong>$2</strong>টা থেকে সংঘটিত পরিবর্তনগুলি (সর্বোচ্চ <strong>$1টি</strong> দেখানো হয়েছে)",
        "rclistfrom": "$2, $3 তারিখের পর সংঘটিত নতুন পরিবর্তনগুলো দেখাও",
        "rcshowhideminor": "অনুল্লেখ্য পরিবর্তনগুলো $1",
        "rcshowhideminor-show": "দেখাও",
        "license": "লাইসেন্সকরণ:",
        "license-header": "লাইসেন্স প্রদান",
        "nolicense": "কিছুই নির্বাচন করা হয়নি",
+       "licenses-edit": "লাইসেন্স অপশন সম্পাদনা করুন",
        "license-nopreview": "(প্রাকদর্শন লভ্য নয়)",
        "upload_source_url": " (একটি বৈধ, উন্মুক্ত URL)",
        "upload_source_file": " (আপনার কম্পিউটারের একটি ফাইল)",
        "wantedtemplates": "আবশ্যিক টেম্পলেটগুলো",
        "mostlinked": "যেসব পাতার প্রতি সবচেয়ে বেশি সংযোগ আছে",
        "mostlinkedcategories": "যেসব বিষয়শ্রেণীর প্রতি সবচেয়ে বেশি সংযোগ আছে",
-       "mostlinkedtemplates": "যà§\87সব à¦\9fà§\87মপà§\8dলà§\87à¦\9fà§\87 à¦¸à¦¬à¦\9aà§\87য়à§\87 à¦¬à§\87শি à¦¸à¦\82যà§\8bà¦\97 à¦\86à¦\9bà§\87",
+       "mostlinkedtemplates": "সবà¦\9aà§\87য়à§\87 à¦¬à§\87শি à¦\85নà§\8dতরà§\8dভà§\81à¦\95à§\8dত à¦ªà¦¾à¦¤à¦¾",
        "mostcategories": "সবচেয়ে বেশী বিষয়শ্রেণী-সমৃদ্ধ নিবন্ধসমূহ",
        "mostimages": "যেসব ফাইলের দিকে সবচেয়ে বেশি সংযোগ আছে",
        "mostinterwikis": "সবচেয়ে বেশী ইন্টারউইকি লিংক-সমৃদ্ধ নিবন্ধসমূহ",
        "watchlist-details": "আপনার নজরতালিকাতে {{PLURAL:$1|$1টি পাতা}} আছে (আলাপ পাতাগুলি গণনায় না ধরে)।",
        "wlheader-enotif": "ইমেল বিজ্ঞপ্তি সক্রিয় করা আছে।",
        "wlheader-showupdated": "আপনার শেষ আগমনের পর থেকে যেসব পাতায় পরিবর্তন হয়েছে সেগুলি '''গাঢ়''' করে দেখানো হয়েছে।",
-       "wlnote": "নিচে $3, $4 তারিখ থেকে বিগত {{PLURAL:$2|১ ঘন্টায়|'''$2''' ঘন্টায়}} সংঘটিত {{PLURAL:$1|শেষ ১টি পরিবর্তন|শেষ '''$1'''টি পরিবর্তন}} দেখানো হল।",
+       "wlnote": "নিচে $3, $4 তারিখ থেকে বিগত {{PLURAL:$2|১ ঘন্টায়|<strong>$2</strong> ঘন্টায়}} সংঘটিত {{PLURAL:$1|শেষ ১টি পরিবর্তন|শেষ <strong>$1টি</strong> পরিবর্তন}} দেখানো হল।",
        "wlshowlast": "দেখাও সর্বশেষ  $1 ঘণ্টা $2 দিন $3",
        "watchlist-options": "নজর তালিকা পছন্দসমূহ",
        "watching": "নজর রাখা হচ্ছে...",
        "autoblockid": "স্বয়ংক্রিয় বাধা #$1",
        "block": "ব্যবহারকারীকে বাধা দাও",
        "unblock": "ব্যবহারকারীর উপর থেকে বাধা অপসারণ",
-       "blockip": "ব্যবহারকারীকে বাধা দাও",
+       "blockip": "{{GENDER:$1|ব্যবহারকারীকে}} বাধা দাও",
        "blockip-legend": "ব্যবহারকারীকে বাধা দেওয়া হোক",
        "blockiptext": "কোন নির্দিষ্ট আইপি ঠিকানা বা ব্যবহারকারীর লেখার অধিকারে বাধা দিতে নিচের ফর্মটি ব্যবহার করুন।\nএটি কেবলমাত্র ধ্বংসপ্রবণতা প্রতিরোধে ও [[{{MediaWiki:Policy-url}}|নীতিমালা]] মেনে সম্পাদন করা উচিত।\nনিচে একটি নির্দিষ্ট কারণ দিন (উদাহরণস্বরূপ, যেসব পাতার ধ্বংসসাধন করা হয়েছে, সেগুলি উল্লেখ করতে পারেন)।",
        "ipaddressorusername": "আইপি ঠিকানা বা ব্যবহারকারীর নাম:",
        "ipb-unblock-addr": "$1-এর উপর থেকে বাধা তুলে নেওয়া হোক",
        "ipb-unblock": "ব্যবহারকারী বা আইপি ঠিকানার উপর থেকে বাধা তুলে নেওয়া হোক",
        "ipb-blocklist": "বিদ্যমান বাধাগুলি দেখুন",
-       "ipb-blocklist-contribs": "$1 এর অবদানসমূহ",
+       "ipb-blocklist-contribs": "{{GENDER:$1|$1}}-এর অবদানসমূহ",
        "unblockip": "ব্যবহারকারীর উপর থেকে বাধা তুলে নেওয়া হোক",
        "unblockiptext": "নিচের ফর্মটি ব্যবহার করে পূর্বে বাধা দেওয়া কোন আইপি ঠিকানা বা ব্যবহারকারীর সাইটে লেখার অধিকার পুনঃপ্রতিষ্ঠা করুন।",
        "ipusubmit": "বাধা তুলে নেওয়া হোক",
        "logentry-rights-rights": "$1 ব্যবহারকারী, $3 এর দলগত সদস্যপদ $4 থেকে $5 এ {{GENDER:$2|পরিবর্তন}} করেছেন",
        "logentry-rights-rights-legacy": "$1 দলের সদস্যপদ পরিবর্তন করেছেন {{GENDER:$2|changed}} এর জন্য $3",
        "logentry-rights-autopromote": "$1 সয়ংক্রিয়ভাবে $4 থেকে $5 এ {{GENDER:$2|উন্নীত}} হয়েছে",
+       "logentry-upload-upload": "$1 $3 {{GENDER:$2|আপলোড করেছেন}}",
+       "logentry-upload-overwrite": "$1 $3-এর একটি নতুন সংস্করণ {{GENDER:$2|আপলোড করেছেন}}",
+       "logentry-upload-revert": "$1 $3 {{GENDER:$2|আপলোড করেছেন}}",
        "rightsnone": "(কিছু নাই)",
        "feedback-bugornote": "কারিগরী ত্রুটির বিস্তারিত বর্ণনা জানতে [$1 বাগ রিপোর্ট করুন]।\nঅথবা নিচের এই সরল ফর্মটি ব্যবহার করতে পারেন। \"[$3 $2]\" পাতায় আপনার ব্যবহারকারী নাম সহ মন্তব্যটি প্রকাশিত হবে।",
        "feedback-subject": "বিষয়:",
index 5b5c7a0..c1145a4 100644 (file)
        "hidden-category-category": "Rummadoù kuzhet",
        "category-subcat-count": "{{PLURAL:$2|N'eus er rummad-mañ nemet an isrummad da-heul.|{{PLURAL:$1|isrummad|$1 isrummad}} zo d'ar rummad-mañ diwar un hollad a $2.}}",
        "category-subcat-count-limited": "Er rummad-mañ e kaver an {{PLURAL:$1|isrummad-se|$1 isrummadoù-se}}.",
-       "category-article-count": "{{PLURAL:$2|N'eus er rummad-mañ nemet ar bajenn da-heul.|Emañ ar {{PLURAL:$1|bajenn da-heul|$1 pajenn da-heul}} er rummad-mañ, diwar un hollad a $2.}}",
-       "category-article-count-limited": "{{PLURAL:$1|Emañ ar bajenn|Emañ an $1 pajenn}} da-heul er rummad-mañ.",
+       "category-article-count": "{{PLURAL:$2|N'eus er rummad-mañ nemet ar bajenn da-heul.|Emañ {{PLURAL:$1|ar bajenn da-heul|an/ar $1 pajenn da-heul}} er rummad-mañ, diwar un hollad a $2.}}",
+       "category-article-count-limited": "{{PLURAL:$1|Emañ ar bajenn|Emañ an/ar $1 pajenn}} da-heul er rummad-mañ.",
        "category-file-count": "{{PLURAL:$2|N'eus er rummad-mañ nemet ar restr da-heul.|Emañ ar {{PLURAL:$1|restr|$1 restr}} da-heul er rummad-mañ, diwar un hollad a $2.}}",
        "category-file-count-limited": "{{PLURAL:$1|Emañ ar restr|Emañ an $1 restr}} da-heul er rummad-mañ.",
        "listingcontinuesabbrev": "(war-lerc'h)",
        "otherlanguages": "Yezhoù all",
        "redirectedfrom": "(Adkaset eus $1)",
        "redirectpagesub": "Pajenn adkas",
-       "lastmodifiedat": "Kemmoù diwezhañ degaset d'ar bajenn-mañ, d'an $1 da $2.",
+       "lastmodifiedat": "Kemmoù diwezhañ degaset d'ar bajenn-mañ, d'an/ar $1 da $2.",
        "viewcount": "Sellet ez eus bet {{PLURAL:$1|$1 wezh|$1 gwezh}} ouzh ar bajenn-mañ.",
        "protectedpage": "Pajenn warezet",
        "jumpto": "Mont da :",
index 0c50c2c..491303c 100644 (file)
                        "Koavf",
                        "Themasterriot",
                        "AVIADOR",
-                       "F3RaN"
+                       "F3RaN",
+                       "Amitie 10g"
                ]
        },
        "tog-underline": "Subrayar los enlaces:",
        "editfont-monospace": "Tipo de letra monoespaciado",
        "editfont-sansserif": "Tipo de letra de palo seco",
        "editfont-serif": "Tipo de letra con serifas",
-       "sunday": "domingo",
-       "monday": "lunes",
-       "tuesday": "martes",
-       "wednesday": "miércoles",
-       "thursday": "jueves",
-       "friday": "viernes",
-       "saturday": "sábado",
+       "sunday": "Domingo",
+       "monday": "Lunes",
+       "tuesday": "Martes",
+       "wednesday": "Miércoles",
+       "thursday": "Jueves",
+       "friday": "Viernes",
+       "saturday": "Sábado",
        "sun": "dom",
        "mon": "lun",
        "tue": "mar",
        "thu": "jue",
        "fri": "vie",
        "sat": "sáb",
-       "january": "enero",
-       "february": "febrero",
-       "march": "marzo",
-       "april": "abril",
-       "may_long": "mayo",
-       "june": "junio",
-       "july": "julio",
-       "august": "agosto",
-       "september": "septiembre",
-       "october": "octubre",
-       "november": "noviembre",
-       "december": "diciembre",
-       "january-gen": "enero",
-       "february-gen": "febrero",
-       "march-gen": "marzo",
-       "april-gen": "abril",
-       "may-gen": "mayo",
-       "june-gen": "junio",
-       "july-gen": "julio",
-       "august-gen": "agosto",
-       "september-gen": "septiembre",
-       "october-gen": "octubre",
-       "november-gen": "noviembre",
-       "december-gen": "diciembre",
+       "january": "Enero",
+       "february": "Febrero",
+       "march": "Marzo",
+       "april": "Abril",
+       "may_long": "Mayo",
+       "june": "Junio",
+       "july": "Julio",
+       "august": "Agosto",
+       "september": "Septiembre",
+       "october": "Octubre",
+       "november": "Noviembre",
+       "december": "Diciembre",
+       "january-gen": "Enero",
+       "february-gen": "Febrero",
+       "march-gen": "Marzo",
+       "april-gen": "Abril",
+       "may-gen": "Mayo",
+       "june-gen": "Junio",
+       "july-gen": "Julio",
+       "august-gen": "Agosto",
+       "september-gen": "Septiembre",
+       "october-gen": "Octubre",
+       "november-gen": "Noviembre",
+       "december-gen": "Diciembre",
        "jan": "ene",
        "feb": "feb",
        "mar": "mar",
        "oct": "oct",
        "nov": "nov",
        "dec": "dic",
-       "january-date": "$1 de enero",
-       "february-date": "$1 de febrero",
-       "march-date": "$1 de marzo",
-       "april-date": "$1 de abril",
-       "may-date": "$1 de mayo",
-       "june-date": "$1 de junio",
-       "july-date": "$1 de julio",
-       "august-date": "$1 de agosto",
-       "september-date": "$1 de septiembre",
-       "october-date": "$1 de octubre",
-       "november-date": "$1 de noviembre",
-       "december-date": "$1 de diciembre",
+       "january-date": "$1 de Enero",
+       "february-date": "$1 de Febrero",
+       "march-date": "$1 de Marzo",
+       "april-date": "$1 de Abril",
+       "may-date": "$1 de Mayo",
+       "june-date": "$1 de Junio",
+       "july-date": "$1 de Julio",
+       "august-date": "$1 de Agosto",
+       "september-date": "$1 de Septiembre",
+       "october-date": "$1 de Octubre",
+       "november-date": "$1 de Noviembre",
+       "december-date": "$1 de Diciembre",
        "pagecategories": "{{PLURAL:$1|Categoría|Categorías}}",
        "category_header": "Páginas en la categoría «$1»",
        "subcategories": "Subcategorías",
        "delete-edit-reasonlist": "Editar razones de borrado",
        "delete-toobig": "Esta página tiene un historial muy grande, con más de $1 {{PLURAL:$1|revisión|revisiones}}. Borrar este tipo de páginas ha sido restringido para prevenir posibles problemas en {{SITENAME}}.",
        "delete-warning-toobig": "Esta página tiene un historial de más de $1 {{PLURAL:$1|revisión|revisiones}}. Eliminarla puede perturbar las operaciones de la base de datos de {{SITENAME}}. Ten cuidado al borrar.",
+       "delete-cantedit": "Usted no se puede borrar esta página porque usted no tiene permiso para editar.",
        "deleting-backlinks-warning": "'''Advertencia:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Otras páginas]] enlazan o transcluyen la página que vas a eliminar.",
        "rollback": "Revertir ediciones",
        "rollback_short": "Revertir",
        "log-name-pagelang": "Registro de cambios en idiomas",
        "log-description-pagelang": "Este es un registro de los cambios en los idiomas de las páginas.",
        "logentry-pagelang-pagelang": "$1 {{GENDER:$2|cambió}} el idioma de la página «$3» del $4 al $5.",
+       "default-skin-not-found": "¡Oops! La apariencia por defecto de la wiki (<code>$wgDefaultSkin</code>), <code>$1</code>, no está disponible.\n\nLa instalación parece poseer las siguientes opciones de apariencia. Por favor revise [https://www.mediawiki.org/wiki/Manual:Skin_configuration Manual: Skin configuration] para mayor información sobre cómo configurarla y seleccionar la apariencia por defecto.\n\n$2\n\n; Si acaba de instalar MediaWiki:\n: Probablemente la haya instalado desde git, o directamente desde el código fuente usando algún otro método. Esto es lo esperado. Intente instalar algunos sets de apariencia desde [https://www.mediawiki.org/wiki/Category:All_skins mediawiki.org's skin directory]:\n:* Descargando [https://www.mediawiki.org/wiki/Download el instalador tarball], el cual contiene varios sets de apariencia y extensiones. Puede copiar y pegar el directorio <code>skins/</code> desde ahi.\n:* Clonando uno de los repositorios en <code>mediawiki/skins/*</code> via git dentro del directorio <code>skins/</code> de su instaación de MediaWiki.\n: Haciendo esto no debería interferir con su repositorio git si usted es un desarrollador de MediaWiki.\n\n; Si acaba de actualizar MediaWiki:\n: MediaWiki 1.24 y versiones posteriores ya no tiene habilitada la actualización de apariencia (revise [https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery Manual: Skin autodiscovery]). Puede pegar las siguientes lineas <code>LocalSettings.php</code> para habilitar todos los sets de apariencia que haya configurado:\n\n<pre>$3</pre>\n\n; Si acaba de modificar <code>LocalSettings.php</code>:\n: Compruebe detenidamente posibles errores tipográficos en los nombres de los sets de apariencias.",
        "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (activado)",
        "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''desactivado''')"
 }
index b9e71e1..c318f3e 100644 (file)
        "protectedtitles": "Suojatut sivunimet",
        "protectedtitles-summary": "Tällä sivulla on lueteltu ne sivut, jotka on tällä hetkellä suojattu uudelleenluonnilta. Nähdäksesi luettelon olemassaolevista suojatuista sivuista katso [[{{#special:ProtectedPages}}|{{int:protectedpages}}]].",
        "protectedtitlesempty": "Ei suojattuja sivunimiä näillä hakuehdoilla.",
-       "listusers": "Käyttäjälista",
+       "listusers": "Käyttäjien luettelo",
        "listusers-editsonly": "Näytä vain käyttäjät, joilla on muokkauksia",
        "listusers-creationsort": "Lajittele tunnuksen luontipäivämäärän mukaan",
        "listusers-desc": "Lajittele alenevassa järjestyksessä",
index bfba9bb..b5506ae 100644 (file)
        "talkpagelinktext": "Walaʻau",
        "specialpage": "‘Ao‘ao kūikawā",
        "personaltools": "Hāmeʻa ponoʻī",
-       "postcomment": "Māhele hou",
        "articlepage": "Nānā i ka ʻaoʻao mealoko",
        "talk": "walaʻau",
        "views": "Nānaina",
        "hidetoc": "hoʻohūnā",
        "collapsible-collapse": "Hoʻoliʻi",
        "collapsible-expand": "Hoʻākea",
+       "confirmable-confirm": "He ʻoiaʻiʻo nō?",
+       "confirmable-yes": "ʻAe",
+       "confirmable-no": "ʻAʻole",
        "thisisdeleted": "Nānā ai‘ole hō‘āla iā $1?",
        "viewdeleted": "Nānā iā $1?",
        "restorelink": "{{PLURAL:$1|kekahi loli holoi|$1 mau loli holoi}}",
        "cascadeprotected": "Ho‘omalu ‘ia kēia ‘ao‘ao mai e ho‘opololei ana, no ka mea, hoʻokomo pū ‘ia ‘oia ma aia {{PLURAL:$1|‘ao‘ao|nā ‘ao‘ao}} i lalo, ho‘omalu ‘ia me ka \"e wailele ana\" koho:\n$2",
        "ns-specialprotected": "‘A‘ole hiki ke ho‘ololi i nā ‘ao‘ao kūikawā",
        "exception-nologin": "ʻE‘e ʻole",
+       "exception-nologin-text": "E ʻoluʻolu e ʻeʻe no ke komo ʻana i kēia ʻaoʻao a i ʻole ka ʻae no kēia hana.",
+       "exception-nologin-text-manual": "E ʻoluʻolu, e $1 no ke komo ʻana i kēia ʻaoʻao a i ʻole ka ʻae no kēia hana.",
        "welcomeuser": "Welina mai e $1!",
        "yourname": "Inoa mea ho'ohana:",
        "userlogin-yourname": "Inoa mea hoʻohana",
        "userlogin-remembermypassword": "Hoʻomanaʻo iaʻu",
        "login": "ʻEʻe",
        "nav-login-createaccount": "ʻEʻe / Kāinoa",
-       "loginprompt": "Pono ʻoe e hoʻā i nā makana no ka ʻeʻe ʻana iā {{SITENAME}}.",
        "userlogin": "ʻEʻe / Kāinoa",
        "userloginnocreate": "ʻEʻe",
        "logout": "Haʻalele",
        "pt-createaccount": "Kāinoa",
        "pt-userlogout": "Haʻalele",
        "changepassword": "E hoʻololi i ka ʻōlelo hūnā",
+       "resetpass_header": "Hoʻololi i ka ʻōlelo hūnā moʻokāki",
        "oldpassword": "ʻŌlelo hūnā kahiko:",
        "newpassword": "ʻŌlelo hūnā hou:",
        "retypenew": "E kikokiko hou i ka ʻōlelo hūnā hou:",
        "resetpass_submit": "Kau i ka ʻōlelo hūnā a ʻeʻe",
        "changepassword-success": "Ua hoʻololi ‘ia kāu hua‘ōlelo huna!",
+       "changepassword-throttled": "Nui ʻino ka hana ʻeʻe ʻana.\nE kali no $1 ma mua o ka hana hou ʻana ke ʻoluʻolu.",
+       "resetpass_forbidden": "ʻAʻole hiki ke hoʻololi i nā ʻōlelo hūnā",
+       "resetpass-no-info": "Pono ʻoe e ʻeʻe no ke komo pono ʻana o kēia ʻaoʻao.",
        "resetpass-submit-loggedin": "Hoʻololi i ka ʻōlelo hūnā",
        "resetpass-submit-cancel": "Hoʻōki",
        "resetpass-temp-password": "ʻŌlelo hūnā kūikawā:",
+       "resetpass-expired": "Ua pau kāu ʻōlelo hūnā. E ʻoluʻolu, e loaʻa kahi ʻōlelo hūnā hou no ka ʻeʻe ʻana.",
        "passwordreset": "Kāinoa hou i ka ʻōlelo hūnā",
        "passwordreset-legend": "Kāinoa hou i ka ʻōlelo hūnā",
        "passwordreset-username": "Inoa mea ho'ohana:",
        "passwordreset-email": "Wahinoho lekauila:",
+       "changeemail": "Hoʻololi i ka wahinoho lekauila",
+       "changeemail-header": "Hoʻololi i ka wahinoho lekauila moʻokāki",
        "changeemail-oldemail": "Wahinoho lekauila hananei:",
        "changeemail-newemail": "Wahinoho lekauila hou:",
        "changeemail-none": "(ʻaʻohe)",
        "showpreview": "E hō'ike i ka nāmua",
        "showdiff": "E hō'ike i nā loli",
        "anoneditwarning": "<strong>E akahele:</strong> ʻAʻole ʻoe ʻeʻe nei.\nE hoʻopaʻa ʻia ana kāu IP ma ko kēia ʻaoʻao mōʻaukala hoʻololi.",
+       "missingcommenttext": "E kikokiko i kekahi kaumanaʻo i lalo, ke ʻoluʻolu.",
        "summary-preview": "Nāmua hōʻuluʻulu manaʻo:",
        "blockedtitle": "Ua pale ‘ia ka mea ho‘ohana",
        "blockednoreason": "‘a‘ohe kumu",
+       "whitelistedittext": "E ʻoluʻolu, e $1 no ka hoʻololi ʻaoʻao ʻana.",
        "loginreqtitle": "Noi i ka ʻeʻe ʻana",
        "loginreqlink": "ʻeʻe",
        "accmailtitle": "Ua ho‘ouna ‘ia ka ‘ōlelo hūnā",
        "anontalkpagetext": "----\n<em>ʻO kēia ka ʻaoʻao kūkākūkā no kekahi mea ho‘ohana me ka inoa ʻole.</em>\nNo laila, pono mākou e ho‘ohana i ka IP no ka hōʻoia ʻana iā ia a hiki i kekahi mau mea hoʻohana ke hoʻokaʻana i kēia  IP.\nInā he mea ho‘ohana inoa ʻole ʻoe a loaʻa kekahi mau manaʻo nāuʻole, e ʻoluʻolu [[Special:UserLogin/signup|e kāinoa]] a i ʻole [[Special:UserLogin|e ʻeʻe]].''",
        "noarticletext": "ʻAʻohe kikokikona a kēia ʻaoʻao.\nHiki iā ʻoe ke [[Special:Search/{{PAGENAME}}|huli no kēia inoa ʻaoʻao]] i nā ʻaoʻao ʻē aʻe, <span class=\"plainlinks\">[{{fullurl:SpecialLog|page={{FULLPAGENAMEE}}}} huli i nā moʻolelo pili], a i ʻole [{{fullurl:{{FULLPAGENAME}}|action=edit}} hoʻololi i kēia ʻaoʻao]</span>.",
        "noarticletext-nopermission": "ʻAʻohe kikokikona a kēia ʻaoʻao.\nHiki iā ʻoe ke [[Special:Search/{{PAGENAME}}|huli no kēia inoa ʻaoʻao]] i nā ʻaoʻao ʻē aʻe aiʻole <span class=\"plainlinks\">[{{fullurl:SpecialLog|page={{FULLPAGENAMEE}}}} huli i nā moʻolelo pili]</span>, akā hiki ʻole iā ʻoe ke hoʻololi i kēia ʻaoʻao.",
+       "userpage-userdoesnotexist-view": "ʻAʻole kāinoa ʻia ka moʻokāki mea hoʻohana ʻo \"$1\".",
        "updated": "(Hoʻopuka hou ʻia)",
        "note": "<strong>E noka:</strong>",
        "previewnote": "<strong>ʻO kēia ka nāmua wale nō.</strong>\n‘A‘ole mālama ‘ia nā ho‘ololi!",
        "protectedpagewarning": "<strong>E akahele:  Ua hoʻomalu ‘ia kēia ‘ao‘ao, pēlā, hiki i nā \"kahu\" ke ho‘ololi wale nō.</strong>\nAia nā loli hanalohi i lalo no ka ʻikena:",
        "templatesused": "{{PLURAL:$1|anakuhi|mau anakuhi}} e hana ʻia ma kēia ʻaoʻao:",
        "templatesusedpreview": "Hoʻohana ʻia kēia {{PLURAL:$1|anakuhi|mau anakuhi}} i kēia nāmua:",
+       "templatesusedsection": "{{PLURAL:$1|Ka anakuhi|Nā anakuhi}} e hana ʻia i kēia mahele:",
        "template-protected": "(ho‘omalu ‘ia)",
        "template-semiprotected": "(hapa-ho‘omalu ‘ia)",
        "hiddencategories": "ʻO kēia ʻaoʻao he lālā o {{PLURAL:$1|1 mahele hūnā|$1 mau māhele hūnā}}:",
        "recreate-moveddeleted-warn": "<strong>E akahele: Ke haku nei ʻoe i kekahi ʻaoʻao i holoi ʻia.</strong>\n\nPono ʻoe e noʻonoʻo e pili ana ka pono o ka hoʻomau ʻana o ka hoʻololi ʻana o kēia ʻaoʻao.\nAia ka moʻolelo holoi a hoʻoneʻe no kēia ʻaoʻao ma ʻaneʻi:",
        "moveddeleted-notice": "Ua holoi ʻia kēia ʻaoʻao.\nHoʻolako ʻia ka moʻolelo holoi a hoʻoneʻe no kēia ʻaoʻao i lalo no ke kūmole.",
        "log-fulllog": "Nānā i ka moʻolelo piha",
+       "postedit-confirmation-created": "Ua haku ʻia ka ʻaoʻao.",
        "postedit-confirmation-saved": "Ua mālama ʻia kāu hoʻololi",
        "defaultmessagetext": "Kikokikona pūlono pa‘amau",
        "content-model-wikitext": "kikokikonawiki",
        "content-model-javascript": "IawaSikulipa",
+       "content-model-css": "CSS",
        "post-expand-template-inclusion-warning": "<strong>E akahele:</strong> Hoʻokela ʻia ka palena nui o ke anakuhi.\nHoʻohui ʻole i kekahi mau anakuhi.",
        "post-expand-template-inclusion-category": "Nā ʻaoʻao me nā anakuhi e hoʻokela i ka palenanui",
        "post-expand-template-argument-warning": "<strong>E akahele:</strong> Aia ma kēia ʻaoʻao i kekahi a ʻoi pilikia anakuhi e loaʻa i kekahi nui hoʻonui nunui loa.\nUa waiho ʻia kēia mau pilikia.",
        "history-feed-title": "Mōʻaukala kāmua",
        "history-feed-description": "Mōʻaukala kāmua no kēia ʻaoʻao ma ka wiki",
        "history-feed-item-nocomment": "$1 ma $3 ma ka hola $4",
+       "rev-deleted-comment": "wehe ʻia ka hōʻuluʻulu manaʻo hoʻololi)",
+       "rev-deleted-user": "(wehe ʻia ka inoa mea hoʻohana)",
        "rev-delundel": "hoʻololi ka nānā ʻana",
        "rev-showdeleted": "hōʻike",
        "revisiondelete": "Holoi/holoi ʻole i nā kāmua",
        "revdelete-reasonotherlist": "Nā kumu ʻē aʻe",
        "revdelete-edit-reasonlist": "Hoʻololi i nā kumu holoi",
        "revdelete-offender": "Mea kākau kāmua:",
+       "mergehistory": "Hoʻokuʻi pū i nā mōʻaukala ʻaoʻao",
        "mergehistory-from": "ʻAoʻao kūmole:",
        "mergehistory-into": "ʻAoʻao helewahi:",
        "mergehistory-reason": "Kumu:",
+       "mergelog": "Moʻolelo hoʻokuʻi pū",
        "revertmerge": "Hoʻokuʻipū ʻole",
        "history-title": "Mōʻaukala kāmua o \"$1\"",
        "lineno": "Laina $1:",
        "search-external": "Huli kūwaho",
        "preferences": "Kaʻu makemake",
        "mypreferences": "Ka‘u makemake",
+       "prefs-edits": "Helu o nā hoʻololi:",
+       "prefsnologintext2": "E ʻeʻe no ka hoʻololi ʻana o kāu makemake, ke ʻoluʻolu.",
        "prefs-skin": "ʻIli",
        "skin-preview": "Nāmua",
        "datedefault": "ʻAʻohe makemake",
        "prefs-namespaces": "Lewainoa",
        "default": "paʻamau",
        "prefs-files": "Waihona",
+       "prefs-emailconfirm-label": "Hōʻoia lekauila:",
        "youremail": "Lekauila:",
        "username": "{{GENDER:$1|Inoa mea hoʻohana}}:",
        "prefs-memberingroups": "{{GENDER:$2|He lālā}} o {{PLURAL:$1|hui|mau hui}}:",
        "prefs-diffs": "ʻOkoʻa",
        "prefs-help-prefershttps": "E hana ana kēia makemake i ka ʻeʻe hou ana.",
        "userrights": "Ho‘oponopono ‘ana o nā kuleana",
+       "userrights-user-editname": "E kikokiko i kekahi inoa mea hoʻohana:",
+       "editusergroup": "Hoʻololi i nā hui mea hoʻohana",
+       "userrights-editusergroup": "Hoʻololi i nā hui mea hoʻohana",
+       "saveusergroups": "Mālama i nā hui mea hoʻohana",
        "userrights-groupsmember": "He lālā o:",
        "userrights-reason": "Kumu:",
        "group": "Hui:",
        "right-bigdelete": "Holoi i nā ʻaoʻao me he mōʻaukala nui",
        "right-browsearchive": "Huli i nā ʻaoʻao holoi",
        "right-undelete": "Holoi ʻole i kekahi ʻaoʻao",
+       "right-suppressionlog": "Nānā i nā moʻolelo pilikino",
        "right-block": "Pale i nā mea hoʻohana ʻē aʻe mai ka hoʻololi ʻana",
        "right-blockemail": "Pale i nā mea hoʻohana ʻē aʻe mai ka lekauila ʻana",
        "right-hideuser": "Pale i ka inoa mea hoʻohana, no laila ʻaʻole hōʻike i ka lehulehu",
        "action-createpage": "haku ʻaoʻao",
        "action-createtalk": "haku ʻaoʻao kūkākūkā",
        "action-createaccount": "kāinoa i kēia moʻokāki mea hoʻohana",
+       "action-move": "hoʻoneʻe i kēia ʻaoʻao",
+       "action-move-subpages": "hoʻoneʻe i kēia ʻaoʻao a me nā ʻaoʻao kūloko hoʻi.",
+       "action-movefile": "hoʻoneʻe i kēia waihona",
+       "action-upload": "hoʻouka i kēia waihona",
+       "action-delete": "holoi i kēia ʻaoʻao",
+       "action-sendemail": "lekauila",
        "nchanges": "$1 {{PLURAL:$1|loli|mau loli}}",
        "enhancedrc-since-last-visit": "$1 {{PLURAL:$1|mai kāu kipana aku nei}}",
        "enhancedrc-history": "mōʻaukala",
        "filesource": "Kumu:",
        "uploadwarning": "Akahele hoʻouka",
        "savefile": "Waihona mālama",
-       "uploadedimage": "ua hoʻouka iā \"[[$1]]\"",
        "upload-source": "Waihona kūmole",
        "sourcefilename": "Inoa waihona kūmole:",
        "sourceurl": "URL kūmole:",
index 8a9154f..dcccfad 100644 (file)
@@ -72,6 +72,7 @@
        "tog-watchdefault": "मेरे द्वारा सम्पादित पृष्ठों और फ़ाइलों को मेरी ध्यानसूची में जोड़ें",
        "tog-watchmoves": "मेरे द्वारा स्थानांतरित पृष्ठों एवं फ़ाइलों को मेरी ध्यानसूची में जोड़ें",
        "tog-watchdeletion": "मेरे द्वारा हटाए गए पृष्ठों एवं फ़ाइलों को मेरी ध्यानसूची में जोड़ें",
+       "tog-watchrollback": "मेरे द्वारा प्रत्यापन्न (रोलबैक) किये हुये पृष्ठों को मेरी ध्यानसूची में जोड़ें।",
        "tog-minordefault": "मेरे सभी सम्पादन छोटे बदलाव हैं",
        "tog-previewontop": "सम्पादन बक्से के ऊपर झलक दिखाएँ",
        "tog-previewonfirst": "प्रथम सम्पादन के बाद झलक दिखाएँ",
index 3677994..a15861f 100644 (file)
        "talkpagelinktext": "diskusija",
        "specialpage": "Specialna strona",
        "personaltools": "Wosobinske nastroje",
-       "postcomment": "Nowy wotrězk",
        "articlepage": "Nastawk",
        "talk": "diskusija",
        "views": "Zwobraznjenja",
        "hidetoc": "schować",
        "collapsible-collapse": "Schować",
        "collapsible-expand": "Pokazać",
+       "confirmable-confirm": "Sy {{GENDER:$1|sej}} wěsty?",
+       "confirmable-yes": "Haj",
+       "confirmable-no": "Ně",
        "thisisdeleted": "$1 pokazać abo wobnowić?",
        "viewdeleted": "$1 pokazać?",
        "restorelink": "{{PLURAL:$1|1 wušmórnjenu wersiju|$1 wušmórnjenej wersiji|$1 wušmórnjene wersije|$1 wušmórnjenych wersijow}}",
        "invalidtitle-knownnamespace": "Njepłaćiwy titul z mjenowym rumom \"$2\" a tekstom \"$3\"",
        "invalidtitle-unknownnamespace": "Njepłaćiwy titul z njeznatym mjenowym rumom $1 a tekstom \"$2\"",
        "exception-nologin": "Njejsy přizjewjeny",
-       "exception-nologin-text": "Prošu [[Special:Userlogin|přizjew so]], zo by přistup na tutu stronu abo akciju měł.",
+       "exception-nologin-text": "Prošu přizjew so, zo by přistup na tutu stronu abo akciju měł.",
        "exception-nologin-text-manual": "Zo by přistup na tutu stronu abo akciju měł, dyrbiš so $1.",
        "virus-badscanner": "Špatna konfiguracija: Njeznaty wirusowy skener: ''$1''",
        "virus-scanfailed": "Skenowanje njeporadźiło (kode $1)",
        "externaldberror": "Běše pak eksterny zmylk awtentifikacije datoweje banki, pak njesměš swoje eksterne konto aktualizować.",
        "login": "Přizjewić",
        "nav-login-createaccount": "Konto wutworić abo so přizjewić",
-       "loginprompt": "Za přizjewjenje do {{GRAMMAR:genitiw|{{SITENAME}}}} dyrbja placki zmóžnjene być.",
        "userlogin": "Załožće konto abo přizjewće so",
        "userloginnocreate": "Přizjewić",
        "logout": "wotzjewić",
        "searchprofile-advanced-tooltip": "W swójskich mjenowych rumach pytać",
        "search-result-size": "$1 ({{PLURAL:$2|1 słowo|$2 słowje|$2 słowa|$2 słowow}})",
        "search-result-category-size": "{{PLURAL:$1|1 čłon|$1 čłonaj|$1 čłonojo|$1 čłonow}} ({{PLURAL:$2|1 podkategorija|$2 podkategoriji|$2 podkategorije|$2 podkategorijow}}, {{PLURAL:$3|1 dataja|$3 dataji|$3 dataje|$3 datajow}})",
-       "search-result-score": "Relewanca: $1 %",
        "search-redirect": "(Daleposrědkowanje $1)",
        "search-section": "(wotrězk $1)",
        "search-file-match": "(wotpowěduje datajowemu wobsahej)",
        "right-browsearchive": "Zhašane strony pytać",
        "right-undelete": "Strony wobnowić",
        "right-suppressrevision": "Wersije, kotrež su před administratorami schowane, přepruwować a wobnowić",
+       "right-viewsuppressed": "Před wužiwarjemi schowane wersije sej wobhladać",
        "right-suppressionlog": "Priwatne protokole wobhladać",
        "right-block": "Druhich wužiwarjow při wobdźěłowanju haćić",
        "right-blockemail": "Wužiwarja při słanju e-mejlow haćić",
        "uploadwarning": "Warnowanje",
        "uploadwarning-text": "Prošu změń slědowace datajowe wopisanje a spytaj hišće raz.",
        "savefile": "Dataju składować",
-       "uploadedimage": "je dataju „[[$1]]” nahrał",
-       "overwroteimage": "je nowu wersiju dataje „[[$1]]“ nahrał",
        "uploaddisabled": "Wodaj, nahraće je znjemóžnjene.",
        "copyuploaddisabled": "Nahraće přez URL znjemóžnjene.",
        "uploaddisabledtext": "Nahraće datajow je znjemóžnjene.",
        "license": "Licenca:",
        "license-header": "Licencowanje",
        "nolicense": "žadyn wuběr",
+       "licenses-edit": "Licencne nastajenja wobdźěłać",
        "license-nopreview": "(žadyn přehlad k dispoziciji)",
-       "upload_source_url": " (płaćiwy, zjawnje docpějomny URL)",
-       "upload_source_file": " (dataja na twojim ličaku)",
+       "upload_source_url": " (twoja wubrana dataja z płaćiweho, zjawnje přistupneho URL)",
+       "upload_source_file": " (twoja wubrana dataja z twojeho ličaka)",
+       "listfiles-delete": "zhašeć",
        "listfiles-summary": "Tuta specialna strona pokazuje wšě nahrate dataje.",
        "listfiles_search_for": "Za mjenom wobraza pytać:",
        "imgfile": "dataja",
        "wantedfiles": "Požadane dataje",
        "wantedfiletext-cat": "Slědowace dataje so wužiwaja, ale njeeksistuju. Dataje z cuzych repozitorijow hodźa so nalistować, byrnjež eksistowali. Tajke wopačne pozitiwy su <del>přešmórnjene</del>. Nimo toho so strony w [[:$1]] nalistuja, kotrež dataje zasadźuja, kotrež njeeksistuja.",
        "wantedfiletext-nocat": "Slědowace dataje so wužiwaja, ale njeeksistuja. Dataje z cuzych repozitorijow hodźa so nalistować, byrnjež eksistowali. Tajke wopačne pozitiwy su <del>přešmórnjene</del>.",
+       "wantedfiletext-nocat-noforeign": "Slědowace dataje so wužiwaja, ale njeeksistuja.",
        "wantedtemplates": "Falowace předłohi",
        "mostlinked": "Z najwjace stronami zwjazane strony",
        "mostlinkedcategories": "Z najwjace stronami zwjazane kategorije",
        "watchlist-details": "{{PLURAL:$1|$1 wobkedźbowana strona|$1 wobkedźbowanej stronje|$1 wobkedźbowane strony|$1 wobkedźbowanych stronow}}, bjeztoho zo so diskusijne strony dźělene liča.",
        "wlheader-enotif": "E-mejlowa zdźělenska słužba je zmóžnjena.",
        "wlheader-showupdated": "Strony, kotrež su so po twojim poslednim wopyće změnili, so '''tučne''' pokazuja.",
-       "wlnote2": "Slěduja změny {{PLURAL:$1|zańdźeneje hodźiny|zańdźeneju <strong>$1</strong> hodźinow|zańdźenych <strong>$1</strong> hodźin}} Staw: $2, $3.",
+       "wlnote": "Deleka {{PLURAL:$1|je poslednja změna|stej poslednjej '''$1''' změnje|su poslednje '''$1''' změny|je poslednich '''$1''' změnow}} za {{PLURAL:$2|poslednju hodźinu|poslednje '''$2''' hodźinje|poslednje '''$2''' hodźiny|poslednje '''$2''' hodźin}}, staw : $3, $4.",
        "wlshowlast": "Poslednje $1 hodź. - $2 dnjow - $3 pokazać",
        "watchlist-options": "Opcije wobkedźbowankow",
        "watching": "Wobkedźbuju…",
        "delete-edit-reasonlist": "Přičiny za wušmórnjenje wobdźěłać",
        "delete-toobig": "Tuta strona ma z wjace hač $1 {{PLURAL:$1|wersiju|wersijomaj|wersijemi|wersijemi}} wulke wobdźěłanske stawizny. Wušmórnjenje tajkich stronow bu wobmjezowane, zo by připadne přetorhnjenje {{SITENAME}} wobešło.",
        "delete-warning-toobig": "Tuta strona ma z wjace hač $1 {{PLURAL:$1|wersiju|wersijomaj|wersijemi|wersijemi}} wulke wobdźěłanske stawizny. Wušmórnjenje móže operacije datoweje banki {{SITENAME}} přetorhnyć; pokročuj z kedźbliwosću.",
+       "delete-cantedit": "Njemóžeš tutu stronu zhašeć, dokelž nimaš prawo ju wobdźěłować.",
        "deleting-backlinks-warning": "'''Warnowanje:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Druhe strony]] wotkazuja k stronje abo strona je druhdźe zapřijata, kotruž chceš zhašeć.",
        "rollback": "Změny cofnyć",
        "rollback_short": "Cofnyć",
        "autoblockid": "#$1 awtomatisce blokować",
        "block": "Wužiwarja blokować",
        "unblock": "Blokowanje wužiwarja zběhnyć",
-       "blockip": "Wužiwarja zablokować",
+       "blockip": "{{GENDER:$1|Wužiwarja|Wužiwarku}} blokować",
        "blockip-legend": "Wužiwarja blokować",
        "blockiptext": "Wužij slědowacy formular deleka, zo by pisanski přistup za podatu IP-adresu abo wužiwarske mjeno blokował. To měło so jenož stać, zo by wandalizmej zadźěwało a woptpowědujo [[{{MediaWiki:Policy-url}}|zasadam]]. Zapodaj deleka přičinu (na př. citujo wosebite strony, kotrež běchu z woporom wandalizma).",
        "ipaddressorusername": "IP-adresa abo wužiwarske mjeno",
        "ipb-unblock-addr": "zablokowanje wužiwarja „$1“ zběhnyć",
        "ipb-unblock": "zablokowanje wužiwarja abo IP-adresy zběhnyć",
        "ipb-blocklist": "tuchwilne blokowanja zwobraznić",
-       "ipb-blocklist-contribs": "Přinoški za $1",
+       "ipb-blocklist-contribs": "Přinoški za {{GENDER:$1|$1}}",
        "unblockip": "Zablokowanje zběhnyć",
        "unblockiptext": "Wužij formular deleka, zo by blokowanje IP-adresy abo wužiwarskeho mjena zběhnył.",
        "ipusubmit": "Tute blokěrowanje skónčić",
        "autosumm-replace": "Strona bu z hinašim tekstom přepisana: '$1'",
        "autoredircomment": "posrědkuju k stronje „[[$1]]”",
        "autosumm-new": "Wutwori stronu z '$1'",
+       "autosumm-newblank": "Prózdna strona wutworjena",
        "size-kilobytes": "$1 kB",
        "lag-warn-normal": "Změny {{PLURAL:$1|zašłeje $1 sekundy|zašłeju $1 sekundow|zašłych $1 sekundow|zašłych $1 sekundow}} so w tutej lisćinje hišće njezwobraznjeja.",
        "lag-warn-high": "Wućeženja datoweje banki dla so změny {{PLURAL:$1|zašłeje $1 sekundy|zašłeje $1 sekundow|zašłych $1 sekundow|zašłych $1 sekundow}} w tutej lisćinje hišće njepokazuja.",
        "duplicate-defaultsort": "Warnowanje: Standardny sortěrowonski kluč (DEFAULTSORTKEY) \"$2\" přepisa prjedawšu sortěrowanski kluč \"$1\".",
        "version": "Wersija",
        "version-extensions": "Instalowane rozšěrjenja",
-       "version-skins": "Šaty",
+       "version-skins": "Instalowane drasty",
        "version-specialpages": "Specialne strony",
        "version-parserhooks": "Parserowe hoki",
        "version-variables": "Wariable",
        "version-hook-name": "Mjeno hoki",
        "version-hook-subscribedby": "Abonowany wot",
        "version-version": "(Wersija $1)",
+       "version-no-ext-name": "[žane mjeno]",
        "version-license": "Licenca MediaWiki",
        "version-ext-license": "Licenca",
        "version-ext-colheader-name": "Rozšěrjenje",
+       "version-skin-colheader-name": "Drasta",
        "version-ext-colheader-version": "Wersija",
        "version-ext-colheader-license": "Licenca",
        "version-ext-colheader-description": "Wopisanje",
        "logentry-rights-rights": "$1 je skupinske čłonstwo za $3 z $4 do $5 {{GENDER:$2|změnił|změniła}}",
        "logentry-rights-rights-legacy": "$1 je skupinske čłonstwo za $3 {{GENDER:$2|změnił|změniła}}",
        "logentry-rights-autopromote": "$1 je so awtomatisce wot $4 do $5 {{GENDER:$2|přirjadował|přirjadowała}}",
+       "logentry-upload-upload": "$1 je $3 {{GENDER:$2|nahrał|nahrała}}",
+       "logentry-upload-overwrite": "$1 je nowu wersiju $3 {{GENDER:$2|nahrał|nahrała}}",
+       "logentry-upload-revert": "$1 je $3 {{GENDER:$2|nahrał|nahrała}}",
        "rightsnone": "(ničo)",
        "feedback-bugornote": "Jeli sy zwólniwy, techniski problem nadrobnje wopisać, [$1 zdźěl prošu zmylk].\nHewak móžeš slědowacy jednory formular wužiwać. Twój komentar přida so stronje \"[$3 $2]\", z twojim wužiwarskim mjenom a z wobhladowakom, kotryž wužiwaš.",
        "feedback-subject": "Tema:",
        "expand_templates_remove_nowiki": "Taflički <nowiki> we wuslědku potłóčić",
        "expand_templates_generate_xml": "Analyzowy štom XML pokazać",
        "expand_templates_generate_rawhtml": "Hruby HTML pokazać",
-       "expand_templates_preview": "Přehlad"
+       "expand_templates_preview": "Přehlad",
+       "pagelanguage": "Selektor rěče strony",
+       "pagelang-name": "Strona",
+       "pagelang-language": "Rěč",
+       "pagelang-use-default": "Standardnu rěč wužiwać",
+       "pagelang-select-lang": "Rěč wubrać",
+       "right-pagelang": "Rěč strony změnić",
+       "action-pagelang": "rěč strony změnić",
+       "log-name-pagelang": "Protokol změnow rěče",
+       "log-description-pagelang": "To je protokol změnow na rěčach stronow.",
+       "logentry-pagelang-pagelang": "$1 je rěč strony za $3 wot $4 do $5 {{GENDER:$2|změnił|změniła}}.",
+       "default-skin-not-found-row-enabled": "* <code>$1</code> / $2 (zmóžnjeny)",
+       "default-skin-not-found-row-disabled": "* <code>$1</code> / $2 ('''znjemóžnjeny''')"
 }
index 59fd0fc..91b5254 100644 (file)
        "movepagetalktext": "La corrispondente pagina di discussione, se esiste, sarà spostata automaticamente insieme alla pagina principale, '''tranne che nei seguenti casi''':\n* lo spostamento della pagina è tra namespace diversi;\n* in corrispondenza del nuovo titolo esiste già una pagina di discussione (non vuota);\n* la casella qui sotto è stata deselezionata.\n\nIn questi casi, se lo si ritiene opportuno, occorre spostare o aggiungere manualmente le informazioni contenute nella pagina di discussione.",
        "movearticle": "Sposta la pagina:",
        "moveuserpage-warning": "'''Attenzione:''' Si sta per spostare una pagina utente. Nota che verrà spostata solamente la pagina. L'utente ''non'' sarà rinominato.",
-       "movecategorypage-warning": "<strong>Attenzione:</strong> stai per spostare una categoria. Solo la pagina verrà spostata, ma tutte le pagine nella vecchia categoria <em>non</em> saranno inserite nella nuova.",
+       "movecategorypage-warning": "<strong>Attenzione:</strong> si sta per spostare una categoria. Solo questa pagina verrà spostata: tutte le pagine nella vecchia categoria <em>non</em> saranno inserite nella nuova.",
        "movenologintext": "Lo spostamento delle pagine è consentito solo agli utenti registrati che hanno eseguito l'[[Special:UserLogin|accesso]] al sito.",
        "movenotallowed": "Non si dispone dei permessi necessari per spostare le pagine.",
        "movenotallowedfile": "Non si dispone dei permessi necessari per spostare i file.",
index 34bda5e..2894e7f 100644 (file)
        "mergehistory-go": "Weis déi Versiounen, déi zesummegeluecht kënne ginn",
        "mergehistory-submit": "Versioune verschmelzen",
        "mergehistory-empty": "Et kënne keng Versioune zesummegeluecht ginn.",
-       "mergehistory-success": "{{PLURAL:$3|1 Versioun gouf|$3 Versioune goufe}} vun [[:$1]] op [[:$2]] zesummegeluecht.",
+       "mergehistory-success": "{{PLURAL:$3|1 Versioun gouf|$3 Versioune goufe}} vu(n) [[:$1]] op [[:$2]] zesummegeluecht.",
        "mergehistory-fail": "Versiounszesummeleeung war net méiglech, kuckt w.e.g. d'Säiten an d'Zäit-Parameter no.",
        "mergehistory-no-source": "Originalsäit \"$1\" gëtt et net.",
        "mergehistory-no-destination": "Zilsäit \"$1\" gëtt et net.",
index 597ee3d..025263c 100644 (file)
        "previewconflict": "ورگشت پیش سیل د نیسسه د راساگه وارو ویرایشت چی شکل دیار بیین بوئه ار شما وه نه سی اماییه کردن انتخاو بکیت.",
        "session_fail_preview": "<strong>د بدبختی ما سی یه که رسینه یا جلسه مونه د دس دئیمه نمی تونیم کار پردازشت ویرایشت شمانه انجوم بیئمو.</strong>\nلطفن هنی تلاش بکیت.\nار هنی کار وه دروس کار نکرد،[[Special:UserLogout|اومائن وه در]] نه ازمایشت بکیت و د نو بیایت وامین.",
        "session_fail_preview_html": "<strong>د بدبختی ما سی یه که رسینه یا جلسه مونه د دس دئیمه نمی تونیم کار پردازشت ویرایشت شمانه انجوم بیئمو.</strong>\nلطفن هنی تلاش بکیت.\n\n<em>سی یه که {{نوم دیارگه}} یه گل ردیف اچ تی ام ال کنشتگر بیه داره، پیش سیل سی یه که د دس حمله یا جاوا اسکریپ د امون با قام کرده بیه..</em>\n\n<strong>ار وه گات قانونی تلاش سی ویرایشته،لطفا د نو تلاش بکیت.</strong>\nار هنی کار وه دروس کار نکرد،[[Special:UserLogout|اومائن وه در]] نه ازمایشت بکیت و د نو بیایت وامین.",
+       "token_suffix_mismatch": "<strong>ویرایشتیا شما سی یه که دووارته نئر شما نیسسه یا نقطه نیائن نه د رازینه امنیتی ویرایشت د یک تیچسه.</strong>\nویرایشت سی یه که د خراو بیئن نیسسه بلگه نهاگری با رد بیه.\nای رخ ون د گاتیایی پیش میا که شما د یه گل رسینه جا پروکسی استفاده می کیت.",
+       "edit_form_incomplete": "<strong>پاره ای د ویرایشتا وه رسینه جا نمی رسن، هنی وارسی بکیت سی یه که بوینیت ویرایشتیا شما خوئه و هنی تلاش بکیت .</strong>",
        "editing": "د حالت ويرايشت$1",
        "creating": "راس كردن $1",
        "editingsection": "د حال ویرایشت$1(بشخ)",
        "explainconflict": "داوسه که شما شرو د ویرایشت ای بلگه کردیته، یه نفر هنی ای بلگه نه آلشت دئه.\nراساگه روئی متن بلگه متن نه چی یه که وجود داشتوه د ور میئره.\nآلشتیا شما د متن هاری نشو دئه هئ.\nشما با آلشتیاتونه د متن که هئش یکی بکید.\nفقط متنی که ها د رو د وختی که شما\"{{رقم:ذخیره گوتار}}\" نه گزارشت می کید اماییه بوئه",
        "yourtext": "متن شما",
        "storedversion": "دوواره دیئن انبار بیه.",
+       "nonunicodebrowser": "<strong>زئنار:دووارته نئر شما وا نیسسه یا یونیکد سازگاری ناره.</strong>\nیه گل راحل وه کار گرته بیه سی یه که شما بلگه یا نه وا امنیت ویرایشت بکیت:\nنیسه یا غیر-ASCII  د پایه رازینه یا 16 تایی دتو نشو دئه بوئه.",
        "editingold": "<strong>زئنار:شما داریت یه گل وانئری نا به هنگوم بیه نه سی ای بلگه ویرایشت می کید</strong>\nار شما ونه اماییه بکیت،هر آلشتی که د اول سی ای وانئری انجوم بیه گم بوئه.",
        "yourdiff": "فرخيا",
+       "longpageerror": "<strong>خطا:نیسسه شما  {{جمی:$1|یه کلوبایت|$1 کلوبایت}}  درازی نه دئه، که ونو د بیشرونه انازه{{جمی:$2|یه کلوبایت|$2 کلوبایت}} گپترن.</strong>\nنبوئه وه اماییه با.",
+       "readonlywarning": "<strong>زئنار:رسینه گا سی واداشت قلف بیه، سی یه نه که شما ایسه نمی تونیت ویرایشتیاتونه اماییه بکیت.</strong>\nشات شما بحایت که نیسسه خوتونه د جانیا نیسسه ای وردار بدیس بکیت و ونه سی نهاتر اماییه بکیت.\n\nدیوونداری که ونه قلف کرده چنی گوته:$1",
+       "protectedpagewarning": "<strong>زئنار:ای بلگه سی یه پر و پیم بیه که کاریاریایی که دسرسی دیوونداری دارن فقط بتونن دش ویرایشت بکن.</strong>\nآخرین سیائه سی سرچشمه یا د هار اماییه کاری بیه:",
        "templatesused": "{{جمی:$1|چوئه|چوئه یا}}د ای بلگه استفاده بیه:",
        "templatesusedpreview": "{{جمی:$1|چوئه|چوئه یا}}استفاده بیه د ای پیش سیل:",
        "templatesusedsection": "{{جمی:$1|چوئه|چوئه یا}} استفاده بیه د ای بخش:",
index 91574c5..8763b41 100644 (file)
@@ -12,7 +12,8 @@
                        "Xiaomingyan",
                        "Yanteng3",
                        "아라",
-                       "LNDDYL"
+                       "LNDDYL",
+                       "Jason924tw"
                ]
        },
        "tog-underline": "鏈墊線:",
        "history_short": "誌",
        "updatedmarker": "新也",
        "printableversion": "印本",
-       "permalink": "æ\81\86é\8f\88",
+       "permalink": "æ\81\86é\80\9a",
        "print": "印",
        "view": "察",
        "edit": "纂",
        "copyright": "文奉$1行。",
        "copyrightpage": "{{ns:project}}:版權",
        "currentevents": "世事",
-       "currentevents-url": "Project:世事",
+       "currentevents-url": "Wikipedia:世事",
        "disclaimers": "免責宣",
        "disclaimerpage": "Project:免責宣",
        "edithelp": "助纂塾",
        "shown-title": "每頁示 $1",
        "viewprevnext": "見($1 {{int:pipe-separator}} $2)($3)",
        "searchmenu-exists": "'''在此wiki中有頁為\"[[:$1]]\"。'''",
-       "searchmenu-new": "'''在此wiki上建頁\"[[:$1]]\"!'''",
+       "searchmenu-new": "'''在此共筆上建頁\"[[:$1]]\"!'''",
        "searchprofile-articles": "容",
        "searchprofile-images": "媒",
        "searchprofile-everything": "全",
        "unusedtemplates": "墨乾",
        "unusedtemplatestext": "此表閒模,篤刪前惠考支鏈。",
        "unusedtemplateswlh": "支鏈",
-       "randompage": "風掀",
+       "randompage": "清風翻書",
        "randompage-nopages": "下列{{PLURAL:$2|名集}}中無頁也:$1",
        "randomincategory-selectcategory-submit": "往",
        "randomredirect": "任渡",
        "mostcategories": "跨船",
        "mostimages": "名檔",
        "mostrevisions": "屢審",
-       "prefixindex": "以é\8f\88å¤\96æ\9f¥",
+       "prefixindex": "ä¾\9då\90\8dç´¢å¼\95",
        "shortpages": "短篇",
        "longpages": "長言",
        "deadendpages": "此無路也",
        "namespace": "名冊:",
        "invert": "反相",
        "blanknamespace": "主",
-       "contributions": "{{GENDER:$1|簿}} 之功績",
+       "contributions": "功績",
        "contributions-title": "$1之功績",
        "mycontris": "吾績",
        "contribsub2": "$1勛($2)",
index b68f8d7..852a339 100644 (file)
        "revdelete-modify-missing": "Ralat menyunting item ID $1: ia tiada dalam pangkalan data!",
        "revdelete-no-change": "'''Amaran:''' item bertarikh $2, $1 telah mempunyai aturan penglihatan yang diminta.",
        "revdelete-concurrent-change": "Ralat ketika mengubahsuai item bertarikh $2, $1: kelihatan statusnya telah diubah oleh orang lain ketika anda cuba untuk mengubahsuainya.\nMohon semak log.",
-       "revdelete-only-restricted": "Ralat menyembunyikan item bertarikh $2, $1: anda tidak boleh menyekat item-item dari pandangan pentadbir-pentadbir tanpa memilih juga salah satu pilihan pandangan lain.",
+       "revdelete-only-restricted": "Ralat menyembunyikan item bertarikh $2, $1: Anda tidak boleh menyekat item-item dari pandangan penyelia-penyelia tanpa memilih juga salah satu pilihan pandangan yang lain.",
        "revdelete-reason-dropdown": "*Sebab penghapusan yang biasa\n** Pencabulan hak cipta\n** Ulasan atau maklumat peribadi tidak sesuai\n** Nama pengguna tidak sesuai\n** Maklumat berkemungkinan fitnah",
        "revdelete-otherreason": "Sebab lain/tambahan:",
        "revdelete-reasonotherlist": "Sebab lain",
        "group-user-member": "{{GENDER:$1|pengguna}}",
        "group-autoconfirmed-member": "{{GENDER:$1|pengguna sah automatik}}",
        "group-bot-member": "{{GENDER:$1|bot}}",
-       "group-sysop-member": "{{GENDER:$1|pentadbir}}",
+       "group-sysop-member": "{{GENDER:$1|penyelia}}",
        "group-bureaucrat-member": "{{GENDER:$1|birokrat}}",
        "group-suppress-member": "{{GENDER:$1|penyemak}}",
        "grouppage-user": "{{ns:project}}:Pengguna",
        "activeusers-count": "$1 tindakan sejak {{PLURAL:$3|semalam|$3 hari lalu}}",
        "activeusers-from": "Tunjukkan pengguna bermula pada:",
        "activeusers-hidebots": "Sorokkan bot",
-       "activeusers-hidesysops": "Sorokkan pentadbir",
+       "activeusers-hidesysops": "Sorokkan penyelia",
        "activeusers-noresult": "Tiada pengguna dijumpai.",
        "listgrouprights": "Hak kumpulan pengguna",
        "listgrouprights-summary": "Berikut adalah senarai kumpulan pengguna yang ditubuhkan di wiki ini, dengan hak-hak mereka masing-masing.\nMungkin terdapat [[{{MediaWiki:Listgrouprights-helppage}}|maklumat tambahan]] mengenai setiap hak.",
        "protect-default": "Benarkan semua pengguna",
        "protect-fallback": "Benarkan pengguna yang berizin \"$1\" sahaja",
        "protect-level-autoconfirmed": "Benarkan pengguna yang diautosahkan sahaja",
-       "protect-level-sysop": "Benarkan pentadbir sahaja",
+       "protect-level-sysop": "Benarkan penyelia sahaja",
        "protect-summary-cascade": "melata",
        "protect-expiring": "sehingga $1 (UTC)",
        "protect-expiring-local": "luput $1",
        "blocklist-timestamp": "Cop masa",
        "blocklist-target": "Sasaran",
        "blocklist-expiry": "Luput",
-       "blocklist-by": "Pentadbir sekatan",
+       "blocklist-by": "Penyelia sekatan",
        "blocklist-params": "Parameter sekatan",
        "blocklist-reason": "Sebab",
        "ipblocklist-submit": "Cari",
index b194711..b22d111 100644 (file)
@@ -77,7 +77,7 @@
        "may_long": "مه",
        "june": "ژوئن",
        "july": "ژوئیه",
-       "august": "ئÙ\80Ù\88Ú¯Ù\80Ù\87â\80\8cسÙ\80ت",
+       "august": "Ø¢Ú¯Ù\88ست",
        "september": "سـه‌پـتـه‌مـبـر",
        "october": "اکتبر",
        "november": "نـووه‌مـبـر",
@@ -89,7 +89,7 @@
        "may-gen": "مه",
        "june-gen": "جـون",
        "july-gen": "ژوئیه",
-       "august-gen": "ئÙ\88Ú¯Ù\80Ù\87â\80\8cسÙ\80ت",
+       "august-gen": "Ø¢Ú¯Ù\88ست",
        "september-gen": "سـه‌پـتـه‌مـبـر",
        "october-gen": "اکتبر",
        "november-gen": "نـووه‌مـبـر",
        "uploadbtn": "باربی‌یشتن فایل",
        "uploadtext": "فرم زیر جه باربی‌یشتن نو پرونده‌ئون وسّه استفاده هاکنین.\nبدی‌ین پرونده‌ئونی که قبلاً باربی‌یشته بَینه به [[Special:FileList|فهرست پرونده‌ها]] بورین. باربی‌یشتن مجدد [[Special:Log/upload|سیاههٔ بارگذاری‌ها]] و حذف پرونده‌ئون [[Special:Log/delete|deletion log]] دله ثبت وانه.\n\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|alt text]]</nowiki></code>''' استفاده از اتا نسخه ۲۰۰ پیکسلی از پرونده که اتا جعبه سمت چپ متن دله دره و عبارت alt text ونه دله به عنوان توضیح استفاده بیّه وسّه\n*'''<code><nowiki>[[</nowiki>{{ns:media}}<nowiki>:File.ogg]]</nowiki></code>''' بساتن اتا پیوند مستقیم به پرونده بدون نمایش پرونده",
        "uploadlogpage": "باربی‌یشتن گزارش",
-       "uploadedimage": "\"[[$1]]\" ره باربی‌یشته",
        "imgfile": "فایل",
        "listfiles": "هارشی ئون ره لیست",
        "listfiles_name": "نـوم",
index 231b15f..a668d7d 100644 (file)
        "yesterday-at": "Ieri, la $1",
        "bad_image_list": "Formatul este următorul:\n\nNumai elementele unei liste sunt luate în considerare. (Acestea sunt linii ce încep cu *)\n\nPrima legătură de pe linie trebuie să fie spre un fișier defectuos.\n\nOrice legături ce urmează pe aceeași linie sunt considerate excepții, adică pagini unde fișierul poate apărea inclus direct.",
        "metadata": "Informații",
-       "metadata-help": "Acest fișier conține informații suplimentare, introduse probabil de aparatul fotografic digital sau scanerul care l-a generat.\nDacă fișierul a fost modificat între timp, este posibil ca unele detalii să nu mai fie valabile.",
+       "metadata-help": "Acest fișier conține informații suplimentare, introduse probabil de aparatul de fotografiat digital sau scanerul care l-a generat.\nDacă fișierul a fost modificat între timp, este posibil ca unele detalii să nu mai fie valabile.",
        "metadata-expand": "Afișează detalii suplimentare",
        "metadata-collapse": "Ascunde detalii suplimentare",
        "metadata-fields": "Câmpurile cu metadatele imaginii listate mai jos vor fi incluse în pagina de afișare a imaginii atunci când tabelul cu metadate este restrâns.\nAltele vor fi ascunse implicit.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude\n* gpsaltitude",
        "exif-imagewidth": "Lățime",
        "exif-imagelength": "Înălțime",
-       "exif-bitspersample": "Biți pe componentă",
+       "exif-bitspersample": "Biți per componentă",
        "exif-compression": "Metodă de comprimare",
-       "exif-photometricinterpretation": "Compoziția pixelilor",
+       "exif-photometricinterpretation": "Model de culoare",
        "exif-orientation": "Orientare",
-       "exif-samplesperpixel": "Numărul de componente",
+       "exif-samplesperpixel": "Număr de componente",
        "exif-planarconfiguration": "Aranjarea datelor",
        "exif-ycbcrsubsampling": "Mostră din fracția Y/C",
        "exif-ycbcrpositioning": "Poziționarea Y și C",
        "exif-yresolution": "Rezoluție verticală",
        "exif-stripoffsets": "Locația datelor imaginii",
        "exif-rowsperstrip": "Numărul de linii per bandă",
-       "exif-stripbytecounts": "Biți corespunzători benzii comprimate",
+       "exif-stripbytecounts": "Octeți corespunzători benzii comprimate",
        "exif-jpeginterchangeformat": "Offset pentru JPEG SOI",
-       "exif-jpeginterchangeformatlength": "Biți de date JPEG",
+       "exif-jpeginterchangeformatlength": "Octeți de date JPEG",
        "exif-whitepoint": "Cromaticitatea punctului alb",
        "exif-primarychromaticities": "Coordonatele cromatice ale culorilor primare",
        "exif-ycbcrcoefficients": "Tăria culorii coeficienților matricei de transformare",
        "exif-software": "Software folosit",
        "exif-artist": "Autor",
        "exif-copyright": "Titularul drepturilor de autor",
-       "exif-exifversion": "Versiune exif",
-       "exif-flashpixversion": "Versiune susținută de Flashpix",
+       "exif-exifversion": "Versiune EXIF",
+       "exif-flashpixversion": "Versiune de Flashpix suportată",
        "exif-colorspace": "Spațiu de culoare",
-       "exif-componentsconfiguration": "Semnificația componentelor",
+       "exif-componentsconfiguration": "Semnificația fiecărei componente",
        "exif-compressedbitsperpixel": "Mod de comprimare a imaginii",
        "exif-pixelydimension": "Lățimea imaginii",
        "exif-pixelxdimension": "Înălțimea imaginii",
        "exif-relatedsoundfile": "Fișierul audio asemănător",
        "exif-datetimeoriginal": "Data și ora producerii imaginii",
        "exif-datetimedigitized": "Data și ora digitizării",
-       "exif-subsectime": "Data/Ora milisecunde",
-       "exif-subsectimeoriginal": "Data/Ora/Original milisecunde",
-       "exif-subsectimedigitized": "Milisecunde DateTimeDigitized",
+       "exif-subsectime": "Subsecunde Data/Ora",
+       "exif-subsectimeoriginal": "Subsecunde Data/Ora/Original",
+       "exif-subsectimedigitized": "Subsecunde Data/Ora/Digitizare",
        "exif-exposuretime": "Timp de expunere",
        "exif-exposuretime-format": "$1 sec ($2)",
        "exif-fnumber": "Diafragmă",
        "exif-exposureprogram": "Program de expunere",
        "exif-spectralsensitivity": "Sensibilitate spectrală",
-       "exif-isospeedratings": "Evaluarea vitezei ISO",
+       "exif-isospeedratings": "Sensibilitate ISO",
        "exif-shutterspeedvalue": "Viteza obturatorului în APEX",
        "exif-aperturevalue": "Diafragmă în APEX",
        "exif-brightnessvalue": "Luminozitate în APEX",
        "exif-exposurebiasvalue": "Compensarea expunerii",
-       "exif-maxaperturevalue": "Apertura maximă",
+       "exif-maxaperturevalue": "Diafragmă maximă",
        "exif-subjectdistance": "Distanța față de subiect",
-       "exif-meteringmode": "Forma de măsurare",
+       "exif-meteringmode": "Mod de măsurare",
        "exif-lightsource": "Sursă de lumină",
        "exif-flash": "Bliț",
        "exif-focallength": "Distanța focală a obiectivului",
        "exif-subjectarea": "Suprafața subiectului",
        "exif-flashenergy": "Energie bliț",
-       "exif-focalplanexresolution": "Rezoluția focală plană X",
-       "exif-focalplaneyresolution": "Rezoluția focală plană Y",
-       "exif-focalplaneresolutionunit": "Unitatea de măsură pentru rezoluția focală plană",
+       "exif-focalplanexresolution": "Rezoluția orizontală a panului focal",
+       "exif-focalplaneyresolution": "Rezoluția verticală a panului focal",
+       "exif-focalplaneresolutionunit": "Unitate de măsură pentru rezoluția planului focal",
        "exif-subjectlocation": "Locația subiectului",
        "exif-exposureindex": "Indexul expunerii",
        "exif-sensingmethod": "Metoda sensibilă",
        "exif-filesource": "Fișier sursă",
        "exif-scenetype": "Tipul scenei",
-       "exif-customrendered": "Prelucrarea imaginii",
+       "exif-customrendered": "Prelucrare personalizată",
        "exif-exposuremode": "Mod de expunere",
        "exif-whitebalance": "Balanța albă",
        "exif-digitalzoomratio": "Raportul transfocării digitale",
        "exif-focallengthin35mmfilm": "Distanță focală pentru film de 35 mm",
-       "exif-scenecapturetype": "Tipul de surprindere a scenei",
+       "exif-scenecapturetype": "Tipul de captură a scenei",
        "exif-gaincontrol": "Controlul scenei",
        "exif-contrast": "Contrast",
        "exif-saturation": "Saturație",
        "exif-sharpness": "Ascuțime",
        "exif-devicesettingdescription": "Descrierea reglajelor aparatului",
        "exif-subjectdistancerange": "Distanța față de subiect",
-       "exif-imageuniqueid": "Identificarea imaginii unice",
+       "exif-imageuniqueid": "Identificator unic al imaginii",
        "exif-gpsversionid": "Versiunea de conversie GPS",
        "exif-gpslatituderef": "Latitudine nordică sau sudică",
        "exif-gpslatitude": "Latitudine",
        "exif-sensingmethod-8": "Senzorul linear al culorii secvențiale",
        "exif-filesource-3": "Aparat de fotografiat digital",
        "exif-scenetype-1": "O imagine fotografiată direct",
-       "exif-customrendered-0": "Prelucrare normală",
-       "exif-customrendered-1": "Prelucrare nestandard",
+       "exif-customrendered-0": "Procedeu normal",
+       "exif-customrendered-1": "Procedeu personalizat",
        "exif-exposuremode-0": "Expunere automată",
        "exif-exposuremode-1": "Expunere manuală",
        "exif-exposuremode-2": "Serie automată de expuneri",
-       "exif-whitebalance-0": "Balanță alb automată",
-       "exif-whitebalance-1": "Balanță alb manuală",
+       "exif-whitebalance-0": "Balans de alb automat",
+       "exif-whitebalance-1": "Balans de alb manual",
        "exif-scenecapturetype-0": "Standard",
        "exif-scenecapturetype-1": "Portret",
        "exif-scenecapturetype-2": "Portret",
        "exif-gpsdirection-t": "Direcția reală",
        "exif-gpsdirection-m": "Direcție magnetică",
        "exif-ycbcrpositioning-1": "Centrat",
-       "exif-ycbcrpositioning-2": "Co-amplasat",
+       "exif-ycbcrpositioning-2": "Coamplasat",
        "exif-dc-contributor": "Contribuitori",
        "exif-dc-coverage": "Întinderea spațială sau temporală a elementului media",
        "exif-dc-date": "Data (datele)",
index 75a2c7d..fb31594 100644 (file)
        "delete-edit-reasonlist": "Uredi razloge za brisanje",
        "delete-toobig": "Ta stran ima obsežno zgodovino urejanja, tj. čez $1 {{PLURAL:$1|redakcijo|redakciji|redakcije|redakcij}}.\nIzbris takšnih strani je bil omejen v izogib neželenim motnjam {{GRAMMAR:dative|{{SITENAME}}}}.",
        "delete-warning-toobig": "Ta stran ima obsežno zgodovino urejanja, tj. čez $1 {{PLURAL:$1|redakcijo|redakciji|redakcije|redakcij}}.\nNjeno brisanje lahko zmoti obratovanje zbirke podatkov {{GRAMMAR:dative|{{SITENAME}}}};\nnadaljujte s previdnostjo.",
+       "delete-cantedit": "Strani ne morete izbrisati, ker je nimate dovoljenja urejati.",
        "deleting-backlinks-warning": "'''Opozorilo:''' [[Special:WhatLinksHere/{{FULLPAGENAME}}|Druge strani]] se povezujejo na ali vključujejo stran, ki jo nameravate izbrisati.",
        "rollback": "Vrni spremembe",
        "rollback_short": "Vrni",
index 549d25b..4a54ea5 100644 (file)
        "category-empty": "<div style=\"margin:2em 1em 0 1em; padding:0.5em; border:1px solid #AAA; text-align:center;\">''Ова категорија тренутно не садржи странице или датотеке.''</div>",
        "hidden-categories": "{{PLURAL:$1|Сакривена категорија|Сакривене категорије}}",
        "hidden-category-category": "Сакривене категорије",
-       "category-subcat-count": "{{PLURAL:$2|1=Ова категорија садржи само следећу поткатегорију.|Ова категорија има {{PLURAL:$1|следећу поткатегорију|следеће $1 поткатегорије|следећих $1 поткатегорија}}, од укупно $2.}}",
+       "category-subcat-count": "{{PLURAL:$2|1=Ова категорија садржи само следећу поткатегорију.|Ова категорија има {{PLURAL:$1|1=следећу поткатегорију|следеће $1 поткатегорије|следећих $1 поткатегорија}}, од укупно $2.}}",
        "category-subcat-count-limited": "Ова категорија садржи {{PLURAL:$1|следећу поткатегорију|следеће $1 поткатегорије|следећих $1 поткатегорија}}.",
        "category-article-count": "{{PLURAL:$2|1=Ова категорија садржи само следећу страницу.|{{PLURAL:$1|Следећа страница је|Следеће $1 странице су|Следећих $1 страница је}} у овој категорији, од укупно $2.}}",
        "category-article-count-limited": "{{PLURAL:$1|1=Следећа страница је|Следеће $1 странице су|Следећих $1 страница је}} у овој категорији.",
-       "category-file-count": "{{PLURAL:$2|1=Ова категорија садржи само следећу датотеку.|{{PLURAL:$1|Следећа датотека је|Следеће $1 датотеке су|Следећих $1 датотека је}} у овој категорији, од укупно $2.}}",
+       "category-file-count": "{{PLURAL:$2|1=Ова категорија садржи само следећу датотеку.|{{PLURAL:$1|1=Следећа датотека је|Следеће $1 датотеке су|Следећих $1 датотека је}} у овој категорији, од укупно $2.}}",
        "category-file-count-limited": "{{PLURAL:$1|1=Следећа датотека је|Следеће $1 датотеке су|Следећих $1 датотека је}} у овој категорији.",
        "listingcontinuesabbrev": "наст.",
        "index-category": "Пописане странице",
index ce56980..b386295 100644 (file)
        "category-empty": "<div style=\"margin:2em 1em 0 1em; padding:0.5em; border:1px solid #AAA; text-align:center;\">''Ova kategorija trenutno ne sadrži stranice ili datoteke.''</div>",
        "hidden-categories": "{{PLURAL:$1|Sakrivena kategorija|Sakrivene kategorije}}",
        "hidden-category-category": "Sakrivene kategorije",
-       "category-subcat-count": "{{PLURAL:$2|1=Ova kategorija sadrži samo sledeću potkategoriju.|Ova kategorija ima {{PLURAL:$1|sledeću potkategoriju|sledeće $1 potkategorije|sledećih $1 potkategorija}}, od ukupno $2.}}",
+       "category-subcat-count": "{{PLURAL:$2|1=Ova kategorija sadrži samo sledeću potkategoriju.|Ova kategorija ima {{PLURAL:$1|1=sledeću potkategoriju|sledeće $1 potkategorije|sledećih $1 potkategorija}}, od ukupno $2.}}",
        "category-subcat-count-limited": "Ova kategorija sadrži {{PLURAL:$1|sledeću potkategoriju|sledeće $1 potkategorije|sledećih $1 potkategorija}}.",
        "category-article-count": "{{PLURAL:$2|1=Ova kategorija sadrži samo sledeću stranicu.|{{PLURAL:$1|Sledeća stranica je|Sledeće $1 stranice su|Sledećih $1 stranica je}} u ovoj kategoriji, od ukupno $2.}}",
        "category-article-count-limited": "{{PLURAL:$1|1=Sledeća stranica je|Sledeće $1 stranice su|Sledećih $1 stranica je}} u ovoj kategoriji.",
-       "category-file-count": "{{PLURAL:$2|1=Ova kategorija sadrži samo sledeću datoteku.|{{PLURAL:$1|Sledeća datoteka je|Sledeće $1 datoteke su|Sledećih $1 datoteka je}} u ovoj kategoriji, od ukupno $2.}}",
+       "category-file-count": "{{PLURAL:$2|1=Ova kategorija sadrži samo sledeću datoteku.|{{PLURAL:$1|1=Sledeća datoteka je|Sledeće $1 datoteke su|Sledećih $1 datoteka je}} u ovoj kategoriji, od ukupno $2.}}",
        "category-file-count-limited": "{{PLURAL:$1|1=Sledeća datoteka je|Sledeće $1 datoteke su|Sledećih $1 datoteka je}} u ovoj kategoriji.",
        "listingcontinuesabbrev": "nast.",
        "index-category": "Popisane stranice",
index 3d97630..d4aa3c9 100644 (file)
        "userjspreview": "'''Kom ihåg att du bara testar/förhandsgranskar ditt JavaScript.'''\n'''Det har inte sparats än!'''",
        "sitecsspreview": "'''Kom ihåg att du bara förhandsgranskar detta CSS.''' \n'''Det har ännu inte sparats!'''",
        "sitejspreview": "'''Kom ihåg att du bara förhandsgranskar denna JavaScript-kod.'''\n'''Det har ännu inte sparats!'''",
-       "userinvalidcssjstitle": "'''Varning:''' Skalet \"$1\" finns inte. Kom ihåg att .css- och .js-sidor för enskilda användare börjar på liten bokstav. Exempel: {{ns:user}}:Foo/vector.css i stället för {{ns:user}}:Foo/Vector.css.",
+       "userinvalidcssjstitle": "'''Varning:''' Utseendet \"$1\" finns inte. Kom ihåg att .css- och .js-sidor för enskilda användare börjar på liten bokstav. Exempel: {{ns:user}}:Foo/vector.css i stället för {{ns:user}}:Foo/Vector.css.",
        "updated": "(Uppdaterad)",
        "note": "'''Obs!'''",
        "previewnote": "'''Kom ihåg att detta bara är en förhandsvisning.'''\nDina ändringar har ännu inte sparats!",
        "prefs-files": "Filer",
        "prefs-custom-css": "personlig CSS",
        "prefs-custom-js": "personlig JavaScript",
-       "prefs-common-css-js": "Delad CSS/JS för alla teman:",
+       "prefs-common-css-js": "Delad CSS/JS för alla utseenden:",
        "prefs-reset-intro": "Du kan använda den här sidan till att återställa dina inställningar till webbplatsens standardinställningar.\nDetta kan inte återställas.",
        "prefs-emailconfirm-label": "E-postbekräftelse:",
        "youremail": "E-post:",
        "tooltip-preferences-save": "Spara inställningar",
        "tooltip-summary": "Skriv en kort sammanfattning",
        "interlanguage-link-title": "$1 - $2",
-       "common.css": "/* CSS som skrivs här påverkar alla skal */",
+       "common.css": "/* CSS som skrivs här påverkar alla utseenden */",
        "print.css": "/* CSS som skrivs här kommer att påverka utskriftsversionen */",
        "noscript.css": "/* CSS som placeras här kommer att påverka användare med JavaScript inaktiverat */",
        "group-autoconfirmed.css": "/* CSS som placeras här kommer bara att påverka bekräftade användare */",
index 45675e0..71252d3 100644 (file)
        "hidetoc": "באַהאַלטן",
        "collapsible-collapse": "אײַנציען",
        "collapsible-expand": "פֿאַרברייטערן",
+       "confirmable-confirm": "צי זענט {{GENDER:$1|איר}} זיכער?",
+       "confirmable-yes": "יא",
+       "confirmable-no": "ניין",
        "thisisdeleted": "זען אדער צוריקשטעלן $1?",
        "viewdeleted": "זען $1?",
        "restorelink": "{{PLURAL:$1|איין געמעקטע ענדערונג|$1 געמעקטע ענדערונגען}}",
        "invalidtitle-knownnamespace": "אומגילטירער טיטל מיט נאמענטייל \"$2\" און טעקסט \"$3\"",
        "invalidtitle-unknownnamespace": "אומגילטיקער טיטל מיט אומבאוואוסטן נאמענטייל נומער $1 און טעקסט \"$2\"",
        "exception-nologin": "נישט אַרײַנלאגירט",
-       "exception-nologin-text": "×\90×\99ר ×©×\90פר×\98 ×\96×\99×\99×\9f [[Special:Userlogin|×\90ר×\99×\99× ×\9c×\90×\92×\99ר×\98]] to כדי צו קענען צוקומען צו דעם בלאט אדער דער אקציע.",
+       "exception-nologin-text": "×\96ײַ×\98 ×\90×\96×\95×\99 ×\92×\95×\98 ×\90רײַנ×\9c×\90×\92×\99ר×\9f כדי צו קענען צוקומען צו דעם בלאט אדער דער אקציע.",
        "exception-nologin-text-manual": "זייט אזוי גוט $1 כדי צו קענען צוקומען צו דעם בלאט אדער דער אקציע.",
        "virus-badscanner": "שלעכטע קאנפֿיגוראציע: אומבאוואוסטער ווירוס איבערקוקער: ''$1''",
        "virus-scanfailed": "איבערקוקן נישט געראטן (קאד: $1)",
        "parser-template-recursion-depth-warning": "מוסטער רעקורסיע טיף מאקסימום איבערגעשטיגן ($1)",
        "language-converter-depth-warning": "אַריבער דעם שפּראַך קאַנווערטער טיף לימיט ($1)",
        "node-count-exceeded-category": "בלעטער וואו קנופצאל איז צו פיל",
-       "node-count-exceeded-category-desc": "×\90 ×§×\90×\98×¢×\92×\90ר×\99×¢ ×¤×\90ר ×\91×\9c×¢×\98ער ×\95×\95×\90×\95 ×\93×\99 ×§× ×\95פצ×\90×\9c ×\90×\99×\96 ×¦×\95 ×¤×\99ל.",
-       "node-count-exceeded-warning": "קנ×\95פנצ×\90×\9c ×\90×\95×\99פ×\9f ×\91×\9c×\90×\98 ×¦×\95 ×\94×\95×\99×\9a",
+       "node-count-exceeded-category-desc": "×\93×\99ר ×\91×\9c×\90×\98 ×©×\98×\99×\99×\92×\98 ×\90×\99×\91ער ×\93×\99 ×\9e×\90קס×\99×\9e×\95×\9d ×§× ×\95פצ×\90ל.",
+       "node-count-exceeded-warning": "×\93ער ×\91×\9c×\90×\98 ×\90×\99×\96 ×\90×\99×\91ער×\92עש×\98×\99×\92×\9f ×\93×¢×\9d ×§× ×\95פנצ×\90×\9c",
        "expansion-depth-exceeded-category": "בלעטער וואו מ'האט אריבערגעשטיגן די פארברייטערונג טיף",
-       "expansion-depth-exceeded-category-desc": "×\93×\90ס ×\90×\99×\96 ×\90 ×§×\90×\98×¢×\92×\90ר×\99×¢ ×¤×\90ר ×\91×\9c×¢×\98ער ×\95×\95×\90ס ×©×\98×\99×\92×\9f ×\90×\99×\91ער ×\93ער פארברייטערן־טיף.",
+       "expansion-depth-exceeded-category-desc": "×\93ער ×\91×\9c×\90×\98 ×©×\98×\99×\99×\92×\98 ×\90×\99×\91ער ×\93×\99 פארברייטערן־טיף.",
        "expansion-depth-exceeded-warning": "בלאט גייט אריבער דער פארברייטערונג טיף",
        "parser-unstrip-loop-warning": "פעטליע געטראפֿן",
        "converter-manual-rule-error": "געטראפן א גרײַז אין האנטלעכן שפראך־קאנווערטירן כלל",
        "preferences": "פרעפֿערענצן",
        "mypreferences": "פּרעפֿערענצן",
        "prefs-edits": "צאָל ענדערונגען:",
-       "prefsnologintext2": "זייט אזוי גוט $1 כדי צו שטעלן באניצער פרעפערענצן.",
+       "prefsnologintext2": "זייט אזוי גוט ארײַנלאגירן כדי צו ענדערן אײַערי באניצער פרעפערענצן.",
        "prefs-skin": "סקין",
        "skin-preview": "פארויסדיגע ווייזונג",
        "datedefault": "נישטא קיין פרעפערענץ",
        "upload-options": "אַרויפֿלאָדן ברירה'ס",
        "watchthisupload": "אויפֿפאַסן דעם בלאט",
        "filewasdeleted": "א טעקע מיט דעם נאמען האט מען שוין ארויפגעלאדן און דערנאך אויסגעמעקט.\nאיר זאלט בודק זיין דעם $1 איידער איר הייבט אן ארויפלאדן ווידעראמאל.",
+       "filename-bad-prefix": "דער נאמען פון דער טעקע וואס איר לאדט ארויף הייבט אן מיט  <strong>\"$1\"</strong>, וואס איז אן אלגעמיינער נאמען געשטעלט פון א דיגיטאלישער קאמערע.\nזײַט אזוי גוט קלויבט א נאמען פאר דער טעקע ואס באשרײַבט איר אינהאלט.",
        "upload-success-subj": "דערפֿאלגרייכער ארויפֿלאָד",
        "upload-success-msg": "אײַער אַרויפֿלאָד פֿון [$2] איז געווען דערפֿאלגרייך. עס איז פֿאַראָן דאָ: [[:{{ns:file}}:$1]]",
        "upload-failure-subj": "אַרויפֿלאָדן פראבלעם",
        "mywatchlist": "אויפפַּאסונג ליסטע",
        "watchlistfor2": "פֿאַר $1 $2",
        "nowatchlist": "איר האט נישט קיין שום בלעטער אין אייער אויפפַּאסונג ליסטע.",
-       "watchlistanontext": "ביטע $1 כדי צו זען אדער ענדערן בלעטער אין אייער אַכטגעבן ליסטע.",
+       "watchlistanontext": "ביטע לאגירט ארײַן כדי צו זען אדער ענדערן בלעטער אין אייער אַכטגעבן ליסטע.",
        "watchnologin": "איר זענט נישט אַרײַנלאגירט",
        "addwatch": "צולייגן צו דער אויפֿפאַסונג ליסטע",
        "addedwatchtext": "דער בלאט \"[[:$1]]\" איז צוגעלײגט געוואָרן צו אײַער [[Special:Watchlist|אויפֿפאַסונג ליסטע]].\n\nווײַטערע ענדערונגען צו דעם בלאַט און צו זײַן פארבינדענעם רעדן בלאַט וועלן זײַן אויסגערעכנט דארט.",
        "autoblockid": "אויטאמאטיש בלאק #$1",
        "block": "בלאקירן באַניצער",
        "unblock": "אויפֿבלאקירן באניצער",
-       "blockip": "בלאקירן באַניצער",
+       "blockip": "בלאקירן {{GENDER:$1|באַניצער}}",
        "blockip-legend": "בלאקירן באַניצער",
        "blockiptext": "באניצט די פארעם דא אונטן כדי צו בלאקירן שרײַבן רעכטן פֿון איינגעשריבענע באניצער אדער סתם ספעציפישע איי פי אדרעסן.\n\nאזאלכע בלאקירונגען מוזן דורכגעפירט ווערן בלויז צו פֿאַרמײַדן וואַנדאַליזם, און לויט די [[{{MediaWiki:Policy-url}}|פארשריפטן און פאליסיס]].\n\nביטע שרײַבט ארויס קלאָר די ספעציפֿישע סיבה (למשל, ציטירן וועלכע בלעטער מ'האט וואַנדאַליזירט).",
        "ipaddressorusername": "IP אדרעס אדער באַניצער נאמען:",
        "ipb-unblock-addr": "אויפֿבלאקירן $1",
        "ipb-unblock": "אויפֿבלאקירן א באַניצער נאמען אדער IP אדרעס",
        "ipb-blocklist": "זעט עקזיסטירנדע בלאקירונגען",
-       "ipb-blocklist-contribs": "בײַשטײַערונגען פֿון $1",
+       "ipb-blocklist-contribs": "בײַשטײַערונגען פֿון {{GENDER:$1|$1}}",
        "unblockip": "אויפֿבלאקירן באניצער",
        "unblockiptext": "מיט דעם פארמולאר קענט איר צוריקשטעלן שרייבן ערלויבניש צו אן IP אדרעס אדער באניצער נאמען וואס איז געווען בלאקירט.",
        "ipusubmit": "אוועקנעמען דעם בלאק",
index a51a673..9078e44 100644 (file)
        "logouttext": "<strong>您現在已登出。</strong>\n\n請注意,某些頁面會以登入的狀態持續顯示,直到您清除瀏覽器快取為止。",
        "welcomeuser": "歡迎光臨,$1!",
        "welcomecreation-msg": "您的帳號已建立。\n可至 [[Special:Preferences|偏好設定]] 更新您在 {{SITENAME}} 的個人化設定。",
-       "yourname": "使用者名稱:",
-       "userlogin-yourname": "使用者名稱",
+       "yourname": "用戶名:",
+       "userlogin-yourname": "用戶名",
        "userlogin-yourname-ph": "輸入您的使用者名稱",
        "createacct-another-username-ph": "輸入使用者名稱",
        "yourpassword": "您的密碼:",
        "nocookiesnew": "使用者帳號已建立成功,但您尚未登入。\n要登入 {{SITENAME}} 使用者需使用 Cookies,\n您的 Cookies 未尚開啟。\n請在開啟後使用您新的使用者名稱及密碼登入。",
        "nocookieslogin": "要登入 {{SITENAME}} 使用者需使用 Cookies,\n您的 Cookies 未尚開啟。\n請在開啟後重試。",
        "nocookiesfornew": "這個使用者的帳號未建立,我們不能確認它的來源。\n請確認您已開啟 Cookie,重新載入後再試。",
-       "noname": "您輸入的使用者名稱無效。",
+       "noname": "您輸入的用戶名無效。",
        "loginsuccesstitle": "登入成功",
        "loginsuccess": "<strong>{{GENDER:|你|妳|你}}正使用 \"$1\" 的身份登入 {{SITENAME}}。</strong>",
        "nosuchuser": "查無使用者 \"$1\"。\n使用者名稱有大小寫區分,\n請檢查您拼寫是否正確,或者 [[Special:UserLogin/signup|建立新帳號]]。",
        "wrongpassword": "您輸入的密碼錯誤,請再試一次。",
        "wrongpasswordempty": "輸入的密碼是空的。\n請再試一次。",
        "passwordtooshort": "您的密碼至少需要 $1 個字元。",
-       "password-name-match": "您的密碼不可以跟使用者名稱相同。",
-       "password-login-forbidden": "此使用者名稱和密碼已被禁止使用。",
+       "password-name-match": "您的密碼不可以跟用戶名相同。",
+       "password-login-forbidden": "此用戶名和密碼已被禁止使用。",
        "mailmypassword": "重設密碼",
        "passwordremindertitle": "{{SITENAME}} 的新臨時密碼",
        "passwordremindertext": "不明人士 (可能是您自己,來自 IP 位址 $1) 要求重設在 {{SITENAME}} ($4) 的密碼。\n給使用者 \"$2\" 的臨時密碼設為 \"$3\"。\n如果這個動作是您做的,您需要立即登入並設定一個新的密碼,\n您的臨時密碼將於{{PLURAL:$5|一|$5}}天內過期。\n\n如果不是您要求重設密碼,或您已想起密碼,並不準備修改,\n您可以忽略此訊息並且繼續使用您原本的密碼。",
        "passwordreset-legend": "重設密碼",
        "passwordreset-disabled": "此 Wiki 已停用重設密碼。",
        "passwordreset-emaildisabled": "此 Wiki 已停用電子郵件功能。",
-       "passwordreset-username": "使用者名稱:",
+       "passwordreset-username": "用戶名:",
        "passwordreset-domain": "網域名稱:",
        "passwordreset-capture": "檢視電子郵件內容?",
        "passwordreset-capture-help": "若您勾選此核選方塊,電子郵件 (包含臨時密碼) 將直接顯示,並寄給使用者。",
        "history-feed-item-nocomment": "$1 於 $2",
        "history-feed-empty": "請求的頁面不存在,\n可能已被刪除或重新命名。\n請嘗試 [[Special:Search|搜尋本站]] 取得其他相關的新頁面。",
        "rev-deleted-comment": "(已移除編輯摘要)",
-       "rev-deleted-user": "(已移除使用者名稱)",
+       "rev-deleted-user": "(已移除用戶名)",
        "rev-deleted-event": "(已移除日誌)",
        "rev-deleted-user-contribs": "[使用者名稱或 IP 位址已移除 - 已隱藏貢獻清單中的編輯]",
        "rev-deleted-text-permission": "此頁面修訂已被 <strong>刪除</strong>。\n可至 [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} 刪除日誌] 取得詳細資訊。",
        "usereditcount": "$1 次{{PLURAL:$1|編輯}}",
        "usercreated": "於 $1 $2 {{GENDER:$3|建立}}",
        "newpages": "最新頁面",
-       "newpages-username": "使用者名稱:",
+       "newpages-username": "用戶名:",
        "ancientpages": "最舊頁面",
        "move": "移動",
        "movethispage": "移動本頁",
        "noemailtext": "此使用者尚未指定一個有效的電子郵件位址。",
        "nowikiemailtext": "此使用者選擇不接收其他使用者的信件。",
        "emailnotarget": "收件人不存在或無效的使用者名稱。",
-       "emailtarget": "輸入收件人使用者名稱",
+       "emailtarget": "輸入收件人用戶名",
        "emailusername": "使用者名稱:",
        "emailusernamesubmit": "送出",
        "email-legend": "傳送電子郵件給另一位 {{SITENAME}} 使用者",
        "sp-contributions-blocked-notice": "此使用者目前已被封鎖。\n以下為最近的封鎖紀錄以供參考:",
        "sp-contributions-blocked-notice-anon": "此 IP 位址目前已被封鎖。\n以下為最近的封鎖紀錄以供參考:",
        "sp-contributions-search": "搜尋貢獻記錄",
-       "sp-contributions-username": "IP 位址或使用者名稱:",
+       "sp-contributions-username": "IP 位址或用戶名:",
        "sp-contributions-toponly": "只顯示最新修訂版本的編輯",
        "sp-contributions-newonly": "僅顯示建立頁面之編輯",
        "sp-contributions-submit": "搜尋",
        "block-log-flags-noemail": "停用電子郵件",
        "block-log-flags-nousertalk": "無法編輯自己的對話頁面",
        "block-log-flags-angry-autoblock": "加強自動封鎖已開啟",
-       "block-log-flags-hiddenname": "隱藏使用者名稱",
+       "block-log-flags-hiddenname": "隱藏用戶名",
        "range_block_disabled": "管理員可建立範圍封鎖的權限以被關閉。",
        "ipb_expiry_invalid": "無效的終止時間。",
        "ipb_expiry_temp": "隱藏使用者名稱的封鎖不可設定期限。",
        "logentry-suppress-revision-legacy": "$1 {{GENDER:$2|已暗中更改}}頁面 $3 中修訂的可見性",
        "revdelete-content-hid": "隱藏內容",
        "revdelete-summary-hid": "隱藏編輯摘要",
-       "revdelete-uname-hid": "隱藏使用者名稱",
+       "revdelete-uname-hid": "隱藏用戶名",
        "revdelete-content-unhid": "取消隱藏內容",
        "revdelete-summary-unhid": "取消隱藏編輯摘要",
-       "revdelete-uname-unhid": "取消隱藏使用者名稱",
+       "revdelete-uname-unhid": "取消隱藏用戶名",
        "revdelete-restricted": "已套用對管理員的限制",
        "revdelete-unrestricted": "已移除對管理員的限制",
        "logentry-move-move": "$1 {{GENDER:$2|已移動}}頁面 $3 至 $4",
index c9ea0f9..2eabcab 100644 (file)
@@ -102,6 +102,7 @@ class CLDRPluralRuleConverter {
 
        /**
         * Private constructor.
+        * @param string $rule
         */
        protected function __construct( $rule ) {
                $this->rule = $rule;
@@ -313,6 +314,7 @@ class CLDRPluralRuleConverter {
 
        /**
         * Throw an error
+        * @param string $message
         */
        protected function error( $message ) {
                throw new CLDRPluralRuleError( $message );
index 72b6aa5..eee1204 100644 (file)
@@ -148,6 +148,12 @@ class TitleCleanup extends TableCleanup {
                                $ns = 0;
                        }
 
+                       # Namespace which no longer exists. Put the page in the main namespace
+                       # since we don't have any idea of the old namespace name. See bug 68501.
+                       if ( !MWNamespace::exists( $ns ) ) {
+                               $ns = 0;
+                       }
+
                        $clean = 'Broken/' . $prior;
                        $verified = Title::makeTitleSafe( $ns, $clean );
                        if ( $verified->exists() ) {
index ea86e88..cbc389b 100644 (file)
@@ -186,8 +186,8 @@ class NamespaceConflictChecker extends Maintenance {
 
        /**
         * @todo Do this for real
-        * @param int $ns
-        * @param string $name
+        * @param int $key
+        * @param string $prefix
         * @param bool $fix
         * @param string $suffix
         * @return bool
index 271a3f6..054f792 100644 (file)
@@ -32,6 +32,7 @@ class PopulateBacklinkNamespace extends LoggedUpdateMaintenance {
        public function __construct() {
                parent::__construct();
                $this->mDescription = "Populate the *_from_namespace fields";
+               $this->addOption( 'lastUpdatedId', "Highest page_id with updated links", false, true );
        }
 
        protected function getUpdateKey() {
@@ -49,7 +50,10 @@ class PopulateBacklinkNamespace extends LoggedUpdateMaintenance {
 
                $this->output( "Updating *_from_namespace fields in links tables.\n" );
 
-               $start = $db->selectField( 'page', 'MIN(page_id)', false, __METHOD__ );
+               $start = $this->getOption( 'lastUpdatedId' );
+               if ( !$start ) {
+                       $start = $db->selectField( 'page', 'MIN(page_id)', false, __METHOD__ );
+               }
                if ( !$start ) {
                        $this->output( "Nothing to do." );
                        return false;
index 9825ba3..adeda88 100644 (file)
@@ -691,12 +691,15 @@ return array(
        'moment' => array(
                'scripts' => 'resources/lib/moment/moment.js',
                'languageScripts' => array(
+                       'af' => 'resources/lib/moment/lang/af.js',
                        'ar' => 'resources/lib/moment/lang/ar.js',
                        'ar-ma' => 'resources/lib/moment/lang/ar-ma.js',
                        'ar-sa' => 'resources/lib/moment/lang/ar-sa.js',
                        'az' => 'resources/lib/moment/lang/az.js',
+                       'be' => 'resources/lib/moment/lang/be.js',
                        'bg' => 'resources/lib/moment/lang/bg.js',
                        'bn' => 'resources/lib/moment/lang/bn.js',
+                       'bo' => 'resources/lib/moment/lang/bo.js',
                        'br' => 'resources/lib/moment/lang/br.js',
                        'bs' => 'resources/lib/moment/lang/bs.js',
                        'ca' => 'resources/lib/moment/lang/ca.js',
@@ -737,6 +740,7 @@ return array(
                        'ml' => 'resources/lib/moment/lang/ml.js',
                        'mr' => 'resources/lib/moment/lang/mr.js',
                        'ms-my' => 'resources/lib/moment/lang/ms-my.js',
+                       'my' => 'resources/lib/moment/lang/my.js',
                        'nb' => 'resources/lib/moment/lang/nb.js',
                        'ne' => 'resources/lib/moment/lang/ne.js',
                        'nl' => 'resources/lib/moment/lang/nl.js',
diff --git a/resources/lib/moment/lang/af.js b/resources/lib/moment/lang/af.js
new file mode 100644 (file)
index 0000000..2777e58
--- /dev/null
@@ -0,0 +1,65 @@
+// moment.js locale configuration
+// locale : afrikaans (af)
+// author : Werner Mollentze : https://github.com/wernerm
+
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['moment'], factory); // AMD
+    } else if (typeof exports === 'object') {
+        module.exports = factory(require('../moment')); // Node
+    } else {
+        factory(window.moment); // Browser global
+    }
+}(function (moment) {
+    return moment.defineLocale('af', {
+        months : "Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),
+        monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),
+        weekdays : "Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),
+        weekdaysShort : "Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),
+        weekdaysMin : "So_Ma_Di_Wo_Do_Vr_Sa".split("_"),
+        meridiem : function (hours, minutes, isLower) {
+            if (hours < 12) {
+                return isLower ? 'vm' : 'VM';
+            } else {
+                return isLower ? 'nm' : 'NM';
+            }
+        },
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY LT",
+            LLLL : "dddd, D MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay : '[Vandag om] LT',
+            nextDay : '[Môre om] LT',
+            nextWeek : 'dddd [om] LT',
+            lastDay : '[Gister om] LT',
+            lastWeek : '[Laas] dddd [om] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "oor %s",
+            past : "%s gelede",
+            s : "'n paar sekondes",
+            m : "'n minuut",
+            mm : "%d minute",
+            h : "'n uur",
+            hh : "%d ure",
+            d : "'n dag",
+            dd : "%d dae",
+            M : "'n maand",
+            MM : "%d maande",
+            y : "'n jaar",
+            yy : "%d jaar"
+        },
+        ordinal : function (number) {
+            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter
+        },
+        week : {
+            dow : 1, // Maandag is die eerste dag van die week.
+            doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
+        }
+    });
+}));
index 1c159f1..c8add2d 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Moroccan Arabic (ar-ma)
+// moment.js locale configuration
+// locale : Moroccan Arabic (ar-ma)
 // author : ElFadili Yassine : https://github.com/ElFadiliY
 // author : Abdel Said : https://github.com/abdelsaid
 
@@ -12,7 +12,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('ar-ma', {
+    return moment.defineLocale('ar-ma', {
         months : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),
         monthsShort : "يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),
         weekdays : "الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
index 162d386..64e2091 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Arabic Saudi Arabia (ar-sa)
+// moment.js locale configuration
+// locale : Arabic Saudi Arabia (ar-sa)
 // author : Suhail Alkowaileet : https://github.com/xsoh
 
 (function (factory) {
@@ -35,7 +35,7 @@
         '٠': '0'
     };
 
-    return moment.lang('ar-sa', {
+    return moment.defineLocale('ar-sa', {
         months : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),
         monthsShort : "يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),
         weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
index dd01a42..2af64ee 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Arabic (ar)
+// moment.js locale configuration
+// locale : Arabic (ar)
 // author : Abdel Said : https://github.com/abdelsaid
 // changes in months, weekdays : Ahmed Elkhatib
 
@@ -36,7 +36,7 @@
         '٠': '0'
     };
 
-    return moment.lang('ar', {
+    return moment.defineLocale('ar', {
         months : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"),
         monthsShort : "يناير/ كانون الثاني_فبراير/ شباط_مارس/ آذار_أبريل/ نيسان_مايو/ أيار_يونيو/ حزيران_يوليو/ تموز_أغسطس/ آب_سبتمبر/ أيلول_أكتوبر/ تشرين الأول_نوفمبر/ تشرين الثاني_ديسمبر/ كانون الأول".split("_"),
         weekdays : "الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),
index bee1f9a..a6a5aff 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : azerbaijani (az)
+// moment.js locale configuration
+// locale : azerbaijani (az)
 // author : topchiyev : https://github.com/topchiyev
 
 (function (factory) {
@@ -11,7 +11,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     var suffixes = {
         1: "-inci",
         5: "-inci",
@@ -37,7 +36,7 @@
         60: "-ıncı",
         90: "-ıncı"
     };
-    return moment.lang('az', {
+    return moment.defineLocale('az', {
         months : "yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),
         monthsShort : "yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),
         weekdays : "Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),
diff --git a/resources/lib/moment/lang/be.js b/resources/lib/moment/lang/be.js
new file mode 100644 (file)
index 0000000..6e0aef1
--- /dev/null
@@ -0,0 +1,150 @@
+// moment.js locale configuration
+// locale : belarusian (be)
+// author : Dmitry Demidov : https://github.com/demidov91
+// author: Praleska: http://praleska.pro/
+// Author : Menelion Elensúle : https://github.com/Oire
+
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['moment'], factory); // AMD
+    } else if (typeof exports === 'object') {
+        module.exports = factory(require('../moment')); // Node
+    } else {
+        factory(window.moment); // Browser global
+    }
+}(function (moment) {
+    function plural(word, num) {
+        var forms = word.split('_');
+        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
+    }
+
+    function relativeTimeWithPlural(number, withoutSuffix, key) {
+        var format = {
+            'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
+            'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
+            'dd': 'дзень_дні_дзён',
+            'MM': 'месяц_месяцы_месяцаў',
+            'yy': 'год_гады_гадоў'
+        };
+        if (key === 'm') {
+            return withoutSuffix ? 'хвіліна' : 'хвіліну';
+        }
+        else if (key === 'h') {
+            return withoutSuffix ? 'гадзіна' : 'гадзіну';
+        }
+        else {
+            return number + ' ' + plural(format[key], +number);
+        }
+    }
+
+    function monthsCaseReplace(m, format) {
+        var months = {
+            'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),
+            'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')
+        },
+
+        nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+            'accusative' :
+            'nominative';
+
+        return months[nounCase][m.month()];
+    }
+
+    function weekdaysCaseReplace(m, format) {
+        var weekdays = {
+            'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),
+            'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_')
+        },
+
+        nounCase = (/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/).test(format) ?
+            'accusative' :
+            'nominative';
+
+        return weekdays[nounCase][m.day()];
+    }
+
+    return moment.defineLocale('be', {
+        months : monthsCaseReplace,
+        monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),
+        weekdays : weekdaysCaseReplace,
+        weekdaysShort : "нд_пн_ат_ср_чц_пт_сб".split("_"),
+        weekdaysMin : "нд_пн_ат_ср_чц_пт_сб".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "DD.MM.YYYY",
+            LL : "D MMMM YYYY г.",
+            LLL : "D MMMM YYYY г., LT",
+            LLLL : "dddd, D MMMM YYYY г., LT"
+        },
+        calendar : {
+            sameDay: '[Сёння ў] LT',
+            nextDay: '[Заўтра ў] LT',
+            lastDay: '[Учора ў] LT',
+            nextWeek: function () {
+                return '[У] dddd [ў] LT';
+            },
+            lastWeek: function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                case 5:
+                case 6:
+                    return '[У мінулую] dddd [ў] LT';
+                case 1:
+                case 2:
+                case 4:
+                    return '[У мінулы] dddd [ў] LT';
+                }
+            },
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "праз %s",
+            past : "%s таму",
+            s : "некалькі секунд",
+            m : relativeTimeWithPlural,
+            mm : relativeTimeWithPlural,
+            h : relativeTimeWithPlural,
+            hh : relativeTimeWithPlural,
+            d : "дзень",
+            dd : relativeTimeWithPlural,
+            M : "месяц",
+            MM : relativeTimeWithPlural,
+            y : "год",
+            yy : relativeTimeWithPlural
+        },
+
+
+        meridiem : function (hour, minute, isLower) {
+            if (hour < 4) {
+                return "ночы";
+            } else if (hour < 12) {
+                return "раніцы";
+            } else if (hour < 17) {
+                return "дня";
+            } else {
+                return "вечара";
+            }
+        },
+
+        ordinal: function (number, period) {
+            switch (period) {
+            case 'M':
+            case 'd':
+            case 'DDD':
+            case 'w':
+            case 'W':
+                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';
+            case 'D':
+                return number + '-га';
+            default:
+                return number;
+            }
+        },
+
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 7  // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
index f47ed65..b8a8c32 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : bulgarian (bg)
+// moment.js locale configuration
+// locale : bulgarian (bg)
 // author : Krasen Borisov : https://github.com/kraz
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('bg', {
+    return moment.defineLocale('bg', {
         months : "януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),
         monthsShort : "янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),
         weekdays : "неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),
index fb23bd0..8ceb8eb 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Bengali (bn)
+// moment.js locale configuration
+// locale : Bengali (bn)
 // author : Kaushik Gandhi : https://github.com/kaushikgandhi
 
 (function (factory) {
@@ -36,7 +36,7 @@
         '০': '0'
     };
 
-    return moment.lang('bn', {
+    return moment.defineLocale('bn', {
         months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split("_"),
         monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split("_"),
         weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split("_"),
@@ -82,7 +82,7 @@
                 return symbolMap[match];
             });
         },
-        //Bengali is a vast language its spoken 
+        //Bengali is a vast language its spoken
         //in different forms in various parts of the world.
         //I have just generalized with most common one used
         meridiem : function (hour, minute, isLower) {
diff --git a/resources/lib/moment/lang/bo.js b/resources/lib/moment/lang/bo.js
new file mode 100644 (file)
index 0000000..f1567ab
--- /dev/null
@@ -0,0 +1,103 @@
+// moment.js locale configuration
+// locale : tibetan (bo)
+// author : Thupten N. Chakrishar : https://github.com/vajradog
+
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['moment'], factory); // AMD
+    } else if (typeof exports === 'object') {
+        module.exports = factory(require('../moment')); // Node
+    } else {
+        factory(window.moment); // Browser global
+    }
+}(function (moment) {
+    var symbolMap = {
+        '1': '༡',
+        '2': '༢',
+        '3': '༣',
+        '4': '༤',
+        '5': '༥',
+        '6': '༦',
+        '7': '༧',
+        '8': '༨',
+        '9': '༩',
+        '0': '༠'
+    },
+    numberMap = {
+        '༡': '1',
+        '༢': '2',
+        '༣': '3',
+        '༤': '4',
+        '༥': '5',
+        '༦': '6',
+        '༧': '7',
+        '༨': '8',
+        '༩': '9',
+        '༠': '0'
+    };
+
+    return moment.defineLocale('bo', {
+        months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split("_"),
+        monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split("_"),
+        weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split("_"),
+        weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split("_"),
+        weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split("_"),
+        longDateFormat : {
+            LT : "A h:mm",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY, LT",
+            LLLL : "dddd, D MMMM YYYY, LT"
+        },
+        calendar : {
+            sameDay : '[དི་རིང] LT',
+            nextDay : '[སང་ཉིན] LT',
+            nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',
+            lastDay : '[ཁ་སང] LT',
+            lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s ལ་",
+            past : "%s སྔན་ལ",
+            s : "ལམ་སང",
+            m : "སྐར་མ་གཅིག",
+            mm : "%d སྐར་མ",
+            h : "ཆུ་ཚོད་གཅིག",
+            hh : "%d ཆུ་ཚོད",
+            d : "ཉིན་གཅིག",
+            dd : "%d ཉིན་",
+            M : "ཟླ་བ་གཅིག",
+            MM : "%d ཟླ་བ",
+            y : "ལོ་གཅིག",
+            yy : "%d ལོ"
+        },
+        preparse: function (string) {
+            return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
+                return numberMap[match];
+            });
+        },
+        postformat: function (string) {
+            return string.replace(/\d/g, function (match) {
+                return symbolMap[match];
+            });
+        },
+        meridiem : function (hour, minute, isLower) {
+            if (hour < 4) {
+                return "མཚན་མོ";
+            } else if (hour < 10) {
+                return "ཞོགས་ཀས";
+            } else if (hour < 17) {
+                return "ཉིན་གུང";
+            } else if (hour < 20) {
+                return "དགོང་དག";
+            } else {
+                return "མཚན་མོ";
+            }
+        },
+        week : {
+            dow : 0, // Sunday is the first day of the week.
+            doy : 6  // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
index 39c60df..fb11fe1 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : breton (br)
+// moment.js locale configuration
+// locale : breton (br)
 // author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
 
 (function (factory) {
@@ -59,7 +59,7 @@
         return mutationTable[text.charAt(0)] + text.substring(1);
     }
 
-    return moment.lang('br', {
+    return moment.defineLocale('br', {
         months : "Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),
         monthsShort : "Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),
         weekdays : "Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),
index 83a9b4c..d69015a 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : bosnian (bs)
+// moment.js locale configuration
+// locale : bosnian (bs)
 // author : Nedim Cholich : https://github.com/frontyard
 // based on (hr) translation by Bojan Marković
 
@@ -12,7 +12,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     function translate(number, withoutSuffix, key) {
         var result = number + " ";
         switch (key) {
@@ -66,9 +65,9 @@
         }
     }
 
-    return moment.lang('bs', {
-               months : "januar_februar_mart_april_maj_juni_juli_avgust_septembar_oktobar_novembar_decembar".split("_"),
-               monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
+    return moment.defineLocale('bs', {
+        months : "januar_februar_mart_april_maj_juni_juli_avgust_septembar_oktobar_novembar_decembar".split("_"),
+        monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
         weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),
         weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"),
         weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"),
index cf47113..932c1cb 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : catalan (ca)
+// moment.js locale configuration
+// locale : catalan (ca)
 // author : Juan G. Hurtado : https://github.com/juanghurtado
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('ca', {
+    return moment.defineLocale('ca', {
         months : "gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),
         monthsShort : "gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),
         weekdays : "diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),
index cb79c9b..085bba0 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : czech (cs)
+// moment.js locale configuration
+// locale : czech (cs)
 // author : petrbela : https://github.com/petrbela
 
 (function (factory) {
@@ -71,7 +71,7 @@
         }
     }
 
-    return moment.lang('cs', {
+    return moment.defineLocale('cs', {
         months : months,
         monthsShort : monthsShort,
         monthsParse : (function (months, monthsShort) {
index a5812de..0a290d8 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : chuvash (cv)
+// moment.js locale configuration
+// locale : chuvash (cv)
 // author : Anatoly Mironov : https://github.com/mirontoli
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('cv', {
+    return moment.defineLocale('cv', {
         months : "кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"),
         monthsShort : "кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"),
         weekdays : "вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун".split("_"),
index 5cd8476..6231a52 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Welsh (cy)
+// moment.js locale configuration
+// locale : Welsh (cy)
 // author : Robert Allen
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang("cy", {
+    return moment.defineLocale("cy", {
         months: "Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),
         monthsShort: "Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),
         weekdays: "Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),
index e06f8c3..9c1c68f 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : danish (da)
+// moment.js locale configuration
+// locale : danish (da)
 // author : Ulrik Nielsen : https://github.com/mrbase
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('da', {
+    return moment.defineLocale('da', {
         months : "januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),
         monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),
         weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),
index 565c12b..48d1b88 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : austrian german (de-at)
+// moment.js locale configuration
+// locale : austrian german (de-at)
 // author : lluchs : https://github.com/lluchs
 // author: Menelion Elensúle: https://github.com/Oire
 // author : Martin Groller : https://github.com/MadMG
@@ -27,7 +27,7 @@
         return withoutSuffix ? format[key][0] : format[key][1];
     }
 
-    return moment.lang('de-at', {
+    return moment.defineLocale('de-at', {
         months : "Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
         monthsShort : "Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
         weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),
index 86cd268..0c389f9 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : german (de)
+// moment.js locale configuration
+// locale : german (de)
 // author : lluchs : https://github.com/lluchs
 // author: Menelion Elensúle: https://github.com/Oire
 
@@ -26,7 +26,7 @@
         return withoutSuffix ? format[key][0] : format[key][1];
     }
 
-    return moment.lang('de', {
+    return moment.defineLocale('de', {
         months : "Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
         monthsShort : "Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
         weekdays : "Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),
index e2a38cd..7f31628 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : modern greek (el)
+// moment.js locale configuration
+// locale : modern greek (el)
 // author : Aggelos Karalias : https://github.com/mehiel
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('el', {
+    return moment.defineLocale('el', {
         monthsNominativeEl : "Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),
         monthsGenitiveEl : "Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),
         months : function (momentToFormat, format) {
@@ -44,7 +44,7 @@
             nextDay : '[Αύριο {}] LT',
             nextWeek : 'dddd [{}] LT',
             lastDay : '[Χθες {}] LT',
-            lastWeek : function() {
+            lastWeek : function () {
                 switch (this.day()) {
                     case 6:
                         return '[το προηγούμενο] dddd [{}] LT';
index 4d91e25..852ecc9 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : australian english (en-au)
+// moment.js locale configuration
+// locale : australian english (en-au)
 
 (function (factory) {
     if (typeof define === 'function' && define.amd) {
@@ -10,7 +10,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('en-au', {
+    return moment.defineLocale('en-au', {
         months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
         monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
         weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
@@ -48,7 +48,7 @@
         },
         ordinal : function (number) {
             var b = number % 10,
-                output = (~~ (number % 100 / 10) === 1) ? 'th' :
+                output = (~~(number % 100 / 10) === 1) ? 'th' :
                 (b === 1) ? 'st' :
                 (b === 2) ? 'nd' :
                 (b === 3) ? 'rd' : 'th';
index a97e9f3..ce253a8 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : canadian english (en-ca)
+// moment.js locale configuration
+// locale : canadian english (en-ca)
 // author : Jonathan Abourbih : https://github.com/jonbca
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('en-ca', {
+    return moment.defineLocale('en-ca', {
         months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
         monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
         weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
@@ -49,7 +49,7 @@
         },
         ordinal : function (number) {
             var b = number % 10,
-                output = (~~ (number % 100 / 10) === 1) ? 'th' :
+                output = (~~(number % 100 / 10) === 1) ? 'th' :
                 (b === 1) ? 'st' :
                 (b === 2) ? 'nd' :
                 (b === 3) ? 'rd' : 'th';
index 3a7907b..14ccbab 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : great britain english (en-gb)
+// moment.js locale configuration
+// locale : great britain english (en-gb)
 // author : Chris Gedrim : https://github.com/chrisgedrim
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('en-gb', {
+    return moment.defineLocale('en-gb', {
         months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
         monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
         weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
@@ -49,7 +49,7 @@
         },
         ordinal : function (number) {
             var b = number % 10,
-                output = (~~ (number % 100 / 10) === 1) ? 'th' :
+                output = (~~(number % 100 / 10) === 1) ? 'th' :
                 (b === 1) ? 'st' :
                 (b === 2) ? 'nd' :
                 (b === 3) ? 'rd' : 'th';
index 03b1abf..318385b 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : esperanto (eo)
+// moment.js locale configuration
+// locale : esperanto (eo)
 // author : Colin Dean : https://github.com/colindean
 // komento: Mi estas malcerta se mi korekte traktis akuzativojn en tiu traduko.
 //          Se ne, bonvolu korekti kaj avizi min por ke mi povas lerni!
@@ -13,7 +13,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('eo', {
+    return moment.defineLocale('eo', {
         months : "januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"),
         monthsShort : "jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec".split("_"),
         weekdays : "Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato".split("_"),
index 67432ca..ed0b564 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : spanish (es)
+// moment.js locale configuration
+// locale : spanish (es)
 // author : Julio Napurí : https://github.com/julionc
 
 (function (factory) {
@@ -14,7 +14,7 @@
     var monthsShortDot = "ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),
         monthsShort = "ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_");
 
-    return moment.lang('es', {
+    return moment.defineLocale('es', {
         months : "enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),
         monthsShort : function (m, format) {
             if (/-MMM-/.test(format)) {
index fb410ef..2241529 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : estonian (et)
+// moment.js locale configuration
+// locale : estonian (et)
 // author : Henry Kehlmann : https://github.com/madhenry
 // improvements : Illimar Tambek : https://github.com/ragulka
 
@@ -31,7 +31,7 @@
         return isFuture ? format[key][0] : format[key][1];
     }
 
-    return moment.lang('et', {
+    return moment.defineLocale('et', {
         months        : "jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),
         monthsShort   : "jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),
         weekdays      : "pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"),
index 659b739..fe2dddb 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : euskara (eu)
+// moment.js locale configuration
+// locale : euskara (eu)
 // author : Eneko Illarramendi : https://github.com/eillarra
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('eu', {
+    return moment.defineLocale('eu', {
         months : "urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),
         monthsShort : "urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),
         weekdays : "igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),
index 4a690c4..09c7909 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Persian Language
+// moment.js locale configuration
+// locale : Persian
 // author : Ebrahim Byagowi : https://github.com/ebraminio
 
 (function (factory) {
@@ -35,7 +35,7 @@
         '۰': '0'
     };
 
-    return moment.lang('fa', {
+    return moment.defineLocale('fa', {
         months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
         monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
         weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
index 49f477c..2afc5e8 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : finnish (fi)
+// moment.js locale configuration
+// locale : finnish (fi)
 // author : Tarmo Aidantausta : https://github.com/bleadof
 
 (function (factory) {
     }
 }(function (moment) {
     var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),
-        numbersFuture = ['nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
-                          numbersPast[7], numbersPast[8], numbersPast[9]];
+        numbersFuture = [
+            'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
+            numbersPast[7], numbersPast[8], numbersPast[9]
+        ];
 
     function translate(number, withoutSuffix, key, isFuture) {
         var result = "";
@@ -54,7 +56,7 @@
         return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;
     }
 
-    return moment.lang('fi', {
+    return moment.defineLocale('fi', {
         months : "tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),
         monthsShort : "tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),
         weekdays : "sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),
index 2f1cbb8..cdc9eda 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : faroese (fo)
+// moment.js locale configuration
+// locale : faroese (fo)
 // author : Ragnar Johannesen : https://github.com/ragnar123
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('fo', {
+    return moment.defineLocale('fo', {
         months : "januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"),
         monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),
         weekdays : "sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"),
index 3280d79..714b11b 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : canadian french (fr-ca)
+// moment.js locale configuration
+// locale : canadian french (fr-ca)
 // author : Jonathan Abourbih : https://github.com/jonbca
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('fr-ca', {
+    return moment.defineLocale('fr-ca', {
         months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
         monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
         weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
index 6b3dc52..106ab11 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : french (fr)
+// moment.js locale configuration
+// locale : french (fr)
 // author : John Fischer : https://github.com/jfroffice
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('fr', {
+    return moment.defineLocale('fr', {
         months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
         monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
         weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
index 8b14127..e82065f 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : galician (gl)
+// moment.js locale configuration
+// locale : galician (gl)
 // author : Juan G. Hurtado : https://github.com/juanghurtado
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('gl', {
+    return moment.defineLocale('gl', {
         months : "Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro".split("_"),
         monthsShort : "Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.".split("_"),
         weekdays : "Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado".split("_"),
index b85dbe8..0af4e09 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Hebrew (he)
+// moment.js locale configuration
+// locale : Hebrew (he)
 // author : Tomer Cohen : https://github.com/tomer
 // author : Moshe Simantov : https://github.com/DevelopmentIL
 // author : Tal Ater : https://github.com/TalAter
@@ -13,7 +13,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('he', {
+    return moment.defineLocale('he', {
         months : "ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),
         monthsShort : "ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),
         weekdays : "ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),
index 8e6e99c..6dd7098 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : hindi (hi)
+// moment.js locale configuration
+// locale : hindi (hi)
 // author : Mayank Singhal : https://github.com/mayanksinghal
 
 (function (factory) {
@@ -36,7 +36,7 @@
         '०': '0'
     };
 
-    return moment.lang('hi', {
+    return moment.defineLocale('hi', {
         months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split("_"),
         monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split("_"),
         weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"),
index 2e3bf11..20fe8c1 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : hrvatski (hr)
+// moment.js locale configuration
+// locale : hrvatski (hr)
 // author : Bojan Marković : https://github.com/bmarkovic
 
 // based on (sl) translation by Robert Sedovšek
@@ -13,7 +13,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     function translate(number, withoutSuffix, key) {
         var result = number + " ";
         switch (key) {
@@ -67,7 +66,7 @@
         }
     }
 
-    return moment.lang('hr', {
+    return moment.defineLocale('hr', {
         months : "sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_"),
         monthsShort : "sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),
         weekdays : "nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),
index 9833024..910f086 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : hungarian (hu)
+// moment.js locale configuration
+// locale : hungarian (hu)
 // author : Adam Brunner : https://github.com/adambrunner
 
 (function (factory) {
@@ -49,7 +49,7 @@
         return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
     }
 
-    return moment.lang('hu', {
+    return moment.defineLocale('hu', {
         months : "január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),
         monthsShort : "jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec".split("_"),
         weekdays : "vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),
index 951655b..b6984a2 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Armenian (hy-am)
+// moment.js locale configuration
+// locale : Armenian (hy-am)
 // author : Armendarabyan : https://github.com/armendarabyan
 
 (function (factory) {
@@ -11,7 +11,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     function monthsCaseReplace(m, format) {
         var months = {
             'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),
@@ -37,7 +36,7 @@
         return weekdays[m.day()];
     }
 
-    return moment.lang('hy-am', {
+    return moment.defineLocale('hy-am', {
         months : monthsCaseReplace,
         monthsShort : monthsShortCaseReplace,
         weekdays : weekdaysCaseReplace,
index f186280..6043f30 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Bahasa Indonesia (id)
+// moment.js locale configuration
+// locale : Bahasa Indonesia (id)
 // author : Mohammad Satrio Utomo : https://github.com/tyok
 // reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
 
@@ -12,7 +12,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('id', {
+    return moment.defineLocale('id', {
         months : "Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),
         monthsShort : "Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des".split("_"),
         weekdays : "Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),
index 5b6b2a8..ed22406 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : icelandic (is)
+// moment.js locale configuration
+// locale : icelandic (is)
 // author : Hinrik Örn Sigurðsson : https://github.com/hinrik
 
 (function (factory) {
@@ -79,7 +79,7 @@
         }
     }
 
-    return moment.lang('is', {
+    return moment.defineLocale('is', {
         months : "janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),
         monthsShort : "jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),
         weekdays : "sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),
index 9c27f66..a151ccc 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : italian (it)
+// moment.js locale configuration
+// locale : italian (it)
 // author : Lorenzo : https://github.com/aliem
 // author: Mattia Larentis: https://github.com/nostalgiaz
 
@@ -12,7 +12,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('it', {
+    return moment.defineLocale('it', {
         months : "gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),
         monthsShort : "gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),
         weekdays : "Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato".split("_"),
index 9cd7e9e..34c4b89 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : japanese (ja)
+// moment.js locale configuration
+// locale : japanese (ja)
 // author : LI Long : https://github.com/baryon
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('ja', {
+    return moment.defineLocale('ja', {
         months : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
         monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
         weekdays : "日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),
index 0cebdaa..3134524 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Georgian (ka)
+// moment.js locale configuration
+// locale : Georgian (ka)
 // author : Irakli Janiashvili : https://github.com/irakli-janiashvili
 
 (function (factory) {
@@ -11,7 +11,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     function monthsCaseReplace(m, format) {
         var months = {
             'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
@@ -38,7 +37,7 @@
         return weekdays[nounCase][m.day()];
     }
 
-    return moment.lang('ka', {
+    return moment.defineLocale('ka', {
         months : monthsCaseReplace,
         monthsShort : "იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),
         weekdays : weekdaysCaseReplace,
index 0759c8f..f457e8d 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : khmer (km)
+// moment.js locale configuration
+// locale : khmer (km)
 // author : Kruy Vanna : https://github.com/kruyvanna
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('km', {
+    return moment.defineLocale('km', {
         months: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),
         monthsShort: "មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),
         weekdays: "អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),
index 3b469df..7de2e51 100644 (file)
@@ -1,7 +1,7 @@
-// moment.js language configuration
-// language : korean (ko)
+// moment.js locale configuration
+// locale : korean (ko)
 //
-// authors 
+// authors
 //
 // - Kyungwook, Park : https://github.com/kyungw00k
 // - Jeeeyul Lee <jeeeyul@gmail.com>
@@ -14,7 +14,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('ko', {
+    return moment.defineLocale('ko', {
         months : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),
         monthsShort : "1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),
         weekdays : "일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),
index 946ba13..c878b79 100644 (file)
@@ -1,6 +1,6 @@
-// moment.js language configuration
-// language : Luxembourgish (lb)
-// author : mweimerskirch : https://github.com/mweimerskirch
+// moment.js locale configuration
+// locale : Luxembourgish (lb)
+// author : mweimerskirch : https://github.com/mweimerskirch, David Raison : https://github.com/kwisatz
 
 // Note: Luxembourgish has a very particular phonological rule ("Eifeler Regel") that causes the
 // deletion of the final "n" in certain contexts. That's what the "eifelerRegelAppliesToWeekday"
             'm': ['eng Minutt', 'enger Minutt'],
             'h': ['eng Stonn', 'enger Stonn'],
             'd': ['een Dag', 'engem Dag'],
-            'dd': [number + ' Deeg', number + ' Deeg'],
             'M': ['ee Mount', 'engem Mount'],
-            'MM': [number + ' Méint', number + ' Méint'],
-            'y': ['ee Joer', 'engem Joer'],
-            'yy': [number + ' Joer', number + ' Joer']
+            'y': ['ee Joer', 'engem Joer']
         };
         return withoutSuffix ? format[key][0] : format[key][1];
     }
         return "virun " + string;
     }
 
-    function processLastWeek(string1) {
-        var weekday = this.format('d');
-        if (eifelerRegelAppliesToWeekday(weekday)) {
-            return '[Leschte] dddd [um] LT';
-        }
-        return '[Leschten] dddd [um] LT';
-    }
-
-    /**
-     * Returns true if the word before the given week day loses the "-n" ending.
-     * e.g. "Leschten Dënschdeg" but "Leschte Méindeg"
-     *
-     * @param weekday {integer}
-     * @returns {boolean}
-     */
-    function eifelerRegelAppliesToWeekday(weekday) {
-        weekday = parseInt(weekday, 10);
-        switch (weekday) {
-        case 0: // Sonndeg
-        case 1: // Méindeg
-        case 3: // Mëttwoch
-        case 5: // Freideg
-        case 6: // Samschdeg
-            return true;
-        default: // 2 Dënschdeg, 4 Donneschdeg
-            return false;
-        }
-    }
-
     /**
      * Returns true if the word before the given number loses the "-n" ending.
      * e.g. "an 10 Deeg" but "a 5 Deeg"
         }
     }
 
-    return moment.lang('lb', {
+    return moment.defineLocale('lb', {
         months: "Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),
         monthsShort: "Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),
         weekdays: "Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),
             nextDay: '[Muer um] LT',
             nextWeek: 'dddd [um] LT',
             lastDay: '[Gëschter um] LT',
-            lastWeek: processLastWeek
+            lastWeek: function () {
+                // Different date string for "Dënschdeg" (Tuesday) and "Donneschdeg" (Thursday) due to phonological rule
+                switch (this.day()) {
+                    case 2:
+                    case 4:
+                        return '[Leschten] dddd [um] LT';
+                    default:
+                        return '[Leschte] dddd [um] LT';
+                }
+            }
         },
-        relativeTime: {
-            future: processFutureTime,
-            past: processPastTime,
-            s: "e puer Sekonnen",
-            m: processRelativeTime,
-            mm: "%d Minutten",
-            h: processRelativeTime,
-            hh: "%d Stonnen",
-            d: processRelativeTime,
-            dd: processRelativeTime,
-            M: processRelativeTime,
-            MM: processRelativeTime,
-            y: processRelativeTime,
-            yy: processRelativeTime
+        relativeTime : {
+            future : processFutureTime,
+            past : processPastTime,
+            s : "e puer Sekonnen",
+            m : processRelativeTime,
+            mm : "%d Minutten",
+            h : processRelativeTime,
+            hh : "%d Stonnen",
+            d : processRelativeTime,
+            dd : "%d Deeg",
+            M : processRelativeTime,
+            MM : "%d Méint",
+            y : processRelativeTime,
+            yy : "%d Joer"
         },
         ordinal: '%d.',
         week: {
index 3c11b89..7d7b93f 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Lithuanian (lt)
+// moment.js locale configuration
+// locale : Lithuanian (lt)
 // author : Mindaugas Mozūras : https://github.com/mmozuras
 
 (function (factory) {
@@ -67,8 +67,8 @@
         return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + "į";
     }
 
-    return moment.lang("lt", {
-        months : "sausio_vasario_kovo_balandžio_gegužės_biržėlio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),
+    return moment.defineLocale("lt", {
+        months : "sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),
         monthsShort : "sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),
         weekdays : relativeWeekDay,
         weekdaysShort : "Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),
index ffe25cf..0df007d 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : latvian (lv)
+// moment.js locale configuration
+// locale : latvian (lv)
 // author : Kristaps Karlsons : https://github.com/skakri
 
 (function (factory) {
@@ -32,7 +32,7 @@
         return number + ' ' + format(units[key], number, withoutSuffix);
     }
 
-    return moment.lang('lv', {
+    return moment.defineLocale('lv', {
         months : "janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),
         monthsShort : "jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),
         weekdays : "svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),
index 5f272fa..2d8a739 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : macedonian (mk)
+// moment.js locale configuration
+// locale : macedonian (mk)
 // author : Borislav Mickov : https://github.com/B0k0
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('mk', {
+    return moment.defineLocale('mk', {
         months : "јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),
         monthsShort : "јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),
         weekdays : "недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),
index cc7db9a..d3cee1d 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : malayalam (ml)
+// moment.js locale configuration
+// locale : malayalam (ml)
 // author : Floyd Pink : https://github.com/floydpink
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('ml', {
+    return moment.defineLocale('ml', {
         months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split("_"),
         monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split("_"),
         weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split("_"),
index 0d1adfd..8cbfe7c 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Marathi (mr)
+// moment.js locale configuration
+// locale : Marathi (mr)
 // author : Harshad Kale : https://github.com/kalehv
 
 (function (factory) {
@@ -36,7 +36,7 @@
         '०': '0'
     };
 
-    return moment.lang('mr', {
+    return moment.defineLocale('mr', {
         months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split("_"),
         monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split("_"),
         weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split("_"),
index 501d5aa..eee412f 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Bahasa Malaysia (ms-MY)
+// moment.js locale configuration
+// locale : Bahasa Malaysia (ms-MY)
 // author : Weldan Jamili : https://github.com/weldan
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('ms-my', {
+    return moment.defineLocale('ms-my', {
         months : "Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),
         monthsShort : "Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),
         weekdays : "Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),
diff --git a/resources/lib/moment/lang/my.js b/resources/lib/moment/lang/my.js
new file mode 100644 (file)
index 0000000..442d569
--- /dev/null
@@ -0,0 +1,88 @@
+// moment.js locale configuration
+// locale : Burmese (my)
+// author : Squar team, mysquar.com
+
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['moment'], factory); // AMD
+    } else if (typeof exports === 'object') {
+        module.exports = factory(require('../moment')); // Node
+    } else {
+        factory(window.moment); // Browser global
+    }
+}(function (moment) {
+    var symbolMap = {
+        '1': '၁',
+        '2': '၂',
+        '3': '၃',
+        '4': '၄',
+        '5': '၅',
+        '6': '၆',
+        '7': '၇',
+        '8': '၈',
+        '9': '၉',
+        '0': '၀'
+    }, numberMap = {
+        '၁': '1',
+        '၂': '2',
+        '၃': '3',
+        '၄': '4',
+        '၅': '5',
+        '၆': '6',
+        '၇': '7',
+        '၈': '8',
+        '၉': '9',
+        '၀': '0'
+    };
+    return moment.defineLocale('my', {
+        months: "ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ".split("_"),
+        monthsShort: "ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ".split("_"),
+        weekdays: "တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ".split("_"),
+        weekdaysShort: "နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),
+        weekdaysMin: "နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),
+        longDateFormat: {
+            LT: "HH:mm",
+            L: "DD/MM/YYYY",
+            LL: "D MMMM YYYY",
+            LLL: "D MMMM YYYY LT",
+            LLLL: "dddd D MMMM YYYY LT"
+        },
+        calendar: {
+            sameDay: '[ယနေ.] LT [မှာ]',
+            nextDay: '[မနက်ဖြန်] LT [မှာ]',
+            nextWeek: 'dddd LT [မှာ]',
+            lastDay: '[မနေ.က] LT [မှာ]',
+            lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',
+            sameElse: 'L'
+        },
+        relativeTime: {
+            future: "လာမည့် %s မှာ",
+            past: "လွန်ခဲ့သော %s က",
+            s: "စက္ကန်.အနည်းငယ်",
+            m: "တစ်မိနစ်",
+            mm: "%d မိနစ်",
+            h: "တစ်နာရီ",
+            hh: "%d နာရီ",
+            d: "တစ်ရက်",
+            dd: "%d ရက်",
+            M: "တစ်လ",
+            MM: "%d လ",
+            y: "တစ်နှစ်",
+            yy: "%d နှစ်"
+        },
+        preparse: function (string) {
+            return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {
+                return numberMap[match];
+            });
+        },
+        postformat: function (string) {
+            return string.replace(/\d/g, function (match) {
+                return symbolMap[match];
+            });
+        },
+        week: {
+            dow: 1, // Monday is the first day of the week.
+            doy: 4 // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
index 2f652ef..5e4a511 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : norwegian bokmål (nb)
+// moment.js locale configuration
+// locale : norwegian bokmål (nb)
 // authors : Espen Hovlandsdal : https://github.com/rexxars
 //           Sigurd Gartmann : https://github.com/sigurdga
 
@@ -12,7 +12,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('nb', {
+    return moment.defineLocale('nb', {
         months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),
         monthsShort : "jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.".split("_"),
         weekdays : "søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),
index 1d57b8c..836fb4d 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : nepali/nepalese
+// moment.js locale configuration
+// locale : nepali/nepalese
 // author : suvash : https://github.com/suvash
 
 (function (factory) {
@@ -36,7 +36,7 @@
         '०': '0'
     };
 
-    return moment.lang('ne', {
+    return moment.defineLocale('ne', {
         months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split("_"),
         monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split("_"),
         weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split("_"),
index ffd454f..1577673 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : dutch (nl)
+// moment.js locale configuration
+// locale : dutch (nl)
 // author : Joris Röling : https://github.com/jjupiter
 
 (function (factory) {
@@ -14,7 +14,7 @@
     var monthsShortWithDots = "jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),
         monthsShortWithoutDots = "jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_");
 
-    return moment.lang('nl', {
+    return moment.defineLocale('nl', {
         months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),
         monthsShort : function (m, format) {
             if (/-MMM-/.test(format)) {
index 8c15108..e479b45 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : norwegian nynorsk (nn)
+// moment.js locale configuration
+// locale : norwegian nynorsk (nn)
 // author : https://github.com/mechuwind
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('nn', {
+    return moment.defineLocale('nn', {
         months : "januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),
         monthsShort : "jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),
         weekdays : "sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),
index 97770d2..75e978b 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : polish (pl)
+// moment.js locale configuration
+// locale : polish (pl)
 // author : Rafal Hirsz : https://github.com/evoL
 
 (function (factory) {
@@ -36,7 +36,7 @@
         }
     }
 
-    return moment.lang('pl', {
+    return moment.defineLocale('pl', {
         months : function (momentToFormat, format) {
             if (/D MMMM/.test(format)) {
                 return monthsSubjective[momentToFormat.month()];
index 8f142d1..d577018 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : brazilian portuguese (pt-br)
+// moment.js locale configuration
+// locale : brazilian portuguese (pt-br)
 // author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('pt-br', {
+    return moment.defineLocale('pt-br', {
         months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),
         monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),
         weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),
index 3042844..8086414 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : portuguese (pt)
+// moment.js locale configuration
+// locale : portuguese (pt)
 // author : Jefferson : https://github.com/jalex79
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('pt', {
+    return moment.defineLocale('pt', {
         months : "janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),
         monthsShort : "jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),
         weekdays : "domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),
index fc27509..21a3293 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : romanian (ro)
+// moment.js locale configuration
+// locale : romanian (ro)
 // author : Vlad Gurdiga : https://github.com/gurdiga
 // author : Valentin Agachi : https://github.com/avaly
 
 }(function (moment) {
     function relativeTimeWithPlural(number, withoutSuffix, key) {
         var format = {
-            'mm': 'minute',
-            'hh': 'ore',
-            'dd': 'zile',
-            'MM': 'luni',
-            'yy': 'ani'
-        },
+                'mm': 'minute',
+                'hh': 'ore',
+                'dd': 'zile',
+                'MM': 'luni',
+                'yy': 'ani'
+            },
             separator = ' ';
         if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
             separator = ' de ';
@@ -28,7 +28,7 @@
         return number + separator + format[key];
     }
 
-    return moment.lang('ro', {
+    return moment.defineLocale('ro', {
         months : "ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),
         monthsShort : "ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),
         weekdays : "duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),
index dc013a7..3ae8d23 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : russian (ru)
+// moment.js locale configuration
+// locale : russian (ru)
 // author : Viktorminator : https://github.com/Viktorminator
 // Author : Menelion Elensúle : https://github.com/Oire
 
@@ -72,7 +72,7 @@
         return weekdays[nounCase][m.day()];
     }
 
-    return moment.lang('ru', {
+    return moment.defineLocale('ru', {
         months : monthsCaseReplace,
         monthsShort : monthsShortCaseReplace,
         weekdays : weekdaysCaseReplace,
index ed8a41d..d03fff8 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : slovak (sk)
+// moment.js locale configuration
+// locale : slovak (sk)
 // author : Martin Minka : https://github.com/k2s
 // based on work of petrbela : https://github.com/petrbela
 
@@ -72,7 +72,7 @@
         }
     }
 
-    return moment.lang('sk', {
+    return moment.defineLocale('sk', {
         months : months,
         monthsShort : monthsShort,
         monthsParse : (function (months, monthsShort) {
index d260f80..6174ae6 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : slovenian (sl)
+// moment.js locale configuration
+// locale : slovenian (sl)
 // author : Robert Sedovšek : https://github.com/sedovsek
 
 (function (factory) {
@@ -72,7 +72,7 @@
         }
     }
 
-    return moment.lang('sl', {
+    return moment.defineLocale('sl', {
         months : "januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),
         monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
         weekdays : "nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),
index 0d3cdcf..4a3dfea 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Albanian (sq)
+// moment.js locale configuration
+// locale : Albanian (sq)
 // author : Flakërim Ismani : https://github.com/flakerimi
 // author: Menelion Elensúle: https://github.com/Oire (tests)
 // author : Oerd Cukalla : https://github.com/oerd (fixes)
@@ -13,7 +13,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('sq', {
+    return moment.defineLocale('sq', {
         months : "Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"),
         monthsShort : "Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"),
         weekdays : "E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"),
index ae1754b..ef6e7ce 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Serbian-cyrillic (sr-cyrl)
+// moment.js locale configuration
+// locale : Serbian-cyrillic (sr-cyrl)
 // author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
 
 (function (factory) {
@@ -11,7 +11,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     var translator = {
         words: { //Different grammatical cases
             m: ['један минут', 'једне минуте'],
@@ -35,7 +34,7 @@
         }
     };
 
-    return moment.lang('sr-cyrl', {
+    return moment.defineLocale('sr-cyrl', {
         months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],
         monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],
         weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],
index 54a5f4f..86e8e84 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Serbian-latin (sr)
+// moment.js locale configuration
+// locale : Serbian-latin (sr)
 // author : Milan Janačković<milanjanackovic@gmail.com> : https://github.com/milan-j
 
 (function (factory) {
@@ -11,7 +11,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     var translator = {
         words: { //Different grammatical cases
             m: ['jedan minut', 'jedne minute'],
@@ -35,7 +34,7 @@
         }
     };
 
-    return moment.lang('sr', {
+    return moment.defineLocale('sr', {
         months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],
         monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],
         weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],
index 0de8c40..9e39a30 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : swedish (sv)
+// moment.js locale configuration
+// locale : swedish (sv)
 // author : Jens Alm : https://github.com/ulmus
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('sv', {
+    return moment.defineLocale('sv', {
         months : "januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),
         monthsShort : "jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),
         weekdays : "söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),
@@ -49,7 +49,7 @@
         },
         ordinal : function (number) {
             var b = number % 10,
-                output = (~~ (number % 100 / 10) === 1) ? 'e' :
+                output = (~~(number % 100 / 10) === 1) ? 'e' :
                 (b === 1) ? 'a' :
                 (b === 2) ? 'a' :
                 (b === 3) ? 'e' : 'e';
index cc742c9..963d403 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : tamil (ta)
+// moment.js locale configuration
+// locale : tamil (ta)
 // author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
 
 (function (factory) {
@@ -36,7 +36,7 @@
             '௦': '0'
         }; */
 
-    return moment.lang('ta', {
+    return moment.defineLocale('ta', {
         months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"),
         monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split("_"),
         weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split("_"),
         },
 
 
-// refer http://ta.wikipedia.org/s/1er1      
+        // refer http://ta.wikipedia.org/s/1er1
 
         meridiem : function (hour, minute, isLower) {
             if (hour >= 6 && hour <= 10) {
                 return " காலை";
-            } else   if (hour >= 10 && hour <= 14) {
+            } else if (hour >= 10 && hour <= 14) {
                 return " நண்பகல்";
-            } else    if (hour >= 14 && hour <= 18) {
+            } else if (hour >= 14 && hour <= 18) {
                 return " எற்பாடு";
-            } else   if (hour >= 18 && hour <= 20) {
+            } else if (hour >= 18 && hour <= 20) {
                 return " மாலை";
-            } else  if (hour >= 20 && hour <= 24) {
+            } else if (hour >= 20 && hour <= 24) {
                 return " இரவு";
-            } else  if (hour >= 0 && hour <= 6) {
+            } else if (hour >= 0 && hour <= 6) {
                 return " வைகறை";
             }
         },
index 70336c8..30b41e6 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : thai (th)
+// moment.js locale configuration
+// locale : thai (th)
 // author : Kridsada Thanabulpong : https://github.com/sirn
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('th', {
+    return moment.defineLocale('th', {
         months : "มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),
         monthsShort : "มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),
         weekdays : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),
index 8044483..dfacf18 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Tagalog/Filipino (tl-ph)
+// moment.js locale configuration
+// locale : Tagalog/Filipino (tl-ph)
 // author : Dan Hagman
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('tl-ph', {
+    return moment.defineLocale('tl-ph', {
         months : "Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),
         monthsShort : "Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),
         weekdays : "Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),
index e90f250..e6c2ada 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : turkish (tr)
+// moment.js locale configuration
+// locale : turkish (tr)
 // authors : Erhan Gundogan : https://github.com/erhangundogan,
 //           Burak Yiğit Kaya: https://github.com/BYK
 
@@ -12,7 +12,6 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-
     var suffixes = {
         1: "'inci",
         5: "'inci",
@@ -39,7 +38,7 @@
         90: "'ıncı"
     };
 
-    return moment.lang('tr', {
+    return moment.defineLocale('tr', {
         months : "Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),
         monthsShort : "Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),
         weekdays : "Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),
index f7e9089..1411e16 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
+// moment.js locale configuration
+// locale : Morocco Central Atlas Tamaziɣt in Latin (tzm-latn)
 // author : Abdel Said : https://github.com/abdelsaid
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('tzm-latn', {
+    return moment.defineLocale('tzm-latn', {
         months : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),
         monthsShort : "innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),
         weekdays : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
index c7c76bd..615eb97 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : Morocco Central Atlas Tamaziɣt (tzm)
+// moment.js locale configuration
+// locale : Morocco Central Atlas Tamaziɣt (tzm)
 // author : Abdel Said : https://github.com/abdelsaid
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('tzm', {
+    return moment.defineLocale('tzm', {
         months : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),
         monthsShort : "ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),
         weekdays : "ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),
index 47056cb..f27d9f3 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : ukrainian (uk)
+// moment.js locale configuration
+// locale : ukrainian (uk)
 // author : zemlanin : https://github.com/zemlanin
 // Author : Menelion Elensúle : https://github.com/Oire
 
@@ -71,7 +71,7 @@
         };
     }
 
-    return moment.lang('uk', {
+    return moment.defineLocale('uk', {
         months : monthsCaseReplace,
         monthsShort : "січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),
         weekdays : weekdaysCaseReplace,
index a5b06fa..aeaad63 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : uzbek
+// moment.js locale configuration
+// locale : uzbek
 // author : Sardor Muminov : https://github.com/muminoff
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('uz', {
+    return moment.defineLocale('uz', {
         months : "январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),
         monthsShort : "янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),
         weekdays : "Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"),
index 94890b0..3f8f5f5 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : vietnamese (vi)
+// moment.js locale configuration
+// locale : vietnamese (vi)
 // author : Bang Nguyen : https://github.com/bangnk
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('vi', {
+    return moment.defineLocale('vi', {
         months : "tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),
         monthsShort : "Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12".split("_"),
         weekdays : "chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),
index 50a3ed9..e73acd7 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : chinese
+// moment.js locale configuration
+// locale : chinese
 // author : suupic : https://github.com/suupic
 // author : Zeno Zeng : https://github.com/zenozeng
 
@@ -12,7 +12,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('zh-cn', {
+    return moment.defineLocale('zh-cn', {
         months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
         monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
         weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
index bbb0737..edb1fb9 100644 (file)
@@ -1,5 +1,5 @@
-// moment.js language configuration
-// language : traditional chinese (zh-tw)
+// moment.js locale configuration
+// locale : traditional chinese (zh-tw)
 // author : Ben : https://github.com/ben-lin
 
 (function (factory) {
@@ -11,7 +11,7 @@
         factory(window.moment); // Browser global
     }
 }(function (moment) {
-    return moment.lang('zh-tw', {
+    return moment.defineLocale('zh-tw', {
         months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
         monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
         weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
index 83282c6..03a2460 100644 (file)
@@ -1,17 +1,16 @@
 //! moment.js
-//! version : 2.7.0
+//! version : 2.8.1
 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
 //! license : MIT
 //! momentjs.com
 
 (function (undefined) {
-
     /************************************
         Constants
     ************************************/
 
     var moment,
-        VERSION = "2.7.0",
+        VERSION = '2.8.1',
         // the global-scope this is NOT the global object in Node.js
         globalScope = typeof global !== 'undefined' ? global : this,
         oldGlobalMoment,
         SECOND = 5,
         MILLISECOND = 6,
 
-        // internal storage for language config files
-        languages = {},
+        // internal storage for locale config files
+        locales = {},
 
-        // moment internal properties
-        momentProperties = {
-            _isAMomentObject: null,
-            _i : null,
-            _f : null,
-            _l : null,
-            _strict : null,
-            _tzm : null,
-            _isUTC : null,
-            _offset : null,  // optional. Combine with _isUTC
-            _pf : null,
-            _lang : null  // optional
-        },
+        // extra moment internal properties (plugins register props here)
+        momentProperties = [],
 
         // check for nodeJS
         hasModule = (typeof module !== 'undefined' && module.exports),
 
         // default relative time thresholds
         relativeTimeThresholds = {
-          s: 45,   //seconds to minutes
-          m: 45,   //minutes to hours
-          h: 22,   //hours to days
-          dd: 25,  //days to month (month == 1)
-          dm: 45,  //days to months (months > 1)
-          dy: 345  //days to year
+            s: 45,  // seconds to minute
+            m: 45,  // minutes to hour
+            h: 22,  // hours to day
+            d: 26,  // days to month
+            M: 11   // months to year
         },
 
         // tokens to ordinalize and pad
                 return this.month() + 1;
             },
             MMM  : function (format) {
-                return this.lang().monthsShort(this, format);
+                return this.localeData().monthsShort(this, format);
             },
             MMMM : function (format) {
-                return this.lang().months(this, format);
+                return this.localeData().months(this, format);
             },
             D    : function () {
                 return this.date();
                 return this.day();
             },
             dd   : function (format) {
-                return this.lang().weekdaysMin(this, format);
+                return this.localeData().weekdaysMin(this, format);
             },
             ddd  : function (format) {
-                return this.lang().weekdaysShort(this, format);
+                return this.localeData().weekdaysShort(this, format);
             },
             dddd : function (format) {
-                return this.lang().weekdays(this, format);
+                return this.localeData().weekdays(this, format);
             },
             w    : function () {
                 return this.week();
                 return this.isoWeekday();
             },
             a    : function () {
-                return this.lang().meridiem(this.hours(), this.minutes(), true);
+                return this.localeData().meridiem(this.hours(), this.minutes(), true);
             },
             A    : function () {
-                return this.lang().meridiem(this.hours(), this.minutes(), false);
+                return this.localeData().meridiem(this.hours(), this.minutes(), false);
             },
             H    : function () {
                 return this.hours();
             },
             Z    : function () {
                 var a = -this.zone(),
-                    b = "+";
+                    b = '+';
                 if (a < 0) {
                     a = -a;
-                    b = "-";
+                    b = '-';
                 }
-                return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
+                return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);
             },
             ZZ   : function () {
                 var a = -this.zone(),
-                    b = "+";
+                    b = '+';
                 if (a < 0) {
                     a = -a;
-                    b = "-";
+                    b = '-';
                 }
                 return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
             },
             }
         },
 
+        deprecations = {},
+
         lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
 
     // Pick the first defined of two or three arguments. dfl comes from
         switch (arguments.length) {
             case 2: return a != null ? a : b;
             case 3: return a != null ? a : b != null ? b : c;
-            default: throw new Error("Implement me");
+            default: throw new Error('Implement me');
         }
     }
 
         };
     }
 
+    function printMsg(msg) {
+        if (moment.suppressDeprecationWarnings === false &&
+                typeof console !== 'undefined' && console.warn) {
+            console.warn("Deprecation warning: " + msg);
+        }
+    }
+
     function deprecate(msg, fn) {
         var firstTime = true;
-        function printMsg() {
-            if (moment.suppressDeprecationWarnings === false &&
-                    typeof console !== 'undefined' && console.warn) {
-                console.warn("Deprecation warning: " + msg);
-            }
-        }
         return extend(function () {
             if (firstTime) {
-                printMsg();
+                printMsg(msg);
                 firstTime = false;
             }
             return fn.apply(this, arguments);
         }, fn);
     }
 
+    function deprecateSimple(name, msg) {
+        if (!deprecations[name]) {
+            printMsg(msg);
+            deprecations[name] = true;
+        }
+    }
+
     function padToken(func, count) {
         return function (a) {
             return leftZeroFill(func.call(this, a), count);
     }
     function ordinalizeToken(func, period) {
         return function (a) {
-            return this.lang().ordinal(func.call(this, a), period);
+            return this.localeData().ordinal(func.call(this, a), period);
         };
     }
 
         Constructors
     ************************************/
 
-    function Language() {
-
+    function Locale() {
     }
 
     // Moment prototype object
-    function Moment(config) {
-        checkOverflow(config);
-        extend(this, config);
+    function Moment(config, skipOverflow) {
+        if (skipOverflow !== false) {
+            checkOverflow(config);
+        }
+        copyConfig(this, config);
+        this._d = new Date(+config._d);
     }
 
     // Duration Constructor
 
         this._data = {};
 
+        this._locale = moment.localeData();
+
         this._bubble();
     }
 
             }
         }
 
-        if (b.hasOwnProperty("toString")) {
+        if (b.hasOwnProperty('toString')) {
             a.toString = b.toString;
         }
 
-        if (b.hasOwnProperty("valueOf")) {
+        if (b.hasOwnProperty('valueOf')) {
             a.valueOf = b.valueOf;
         }
 
         return a;
     }
 
-    function cloneMoment(m) {
-        var result = {}, i;
-        for (i in m) {
-            if (m.hasOwnProperty(i) && momentProperties.hasOwnProperty(i)) {
-                result[i] = m[i];
+    function copyConfig(to, from) {
+        var i, prop, val;
+
+        if (typeof from._isAMomentObject !== 'undefined') {
+            to._isAMomentObject = from._isAMomentObject;
+        }
+        if (typeof from._i !== 'undefined') {
+            to._i = from._i;
+        }
+        if (typeof from._f !== 'undefined') {
+            to._f = from._f;
+        }
+        if (typeof from._l !== 'undefined') {
+            to._l = from._l;
+        }
+        if (typeof from._strict !== 'undefined') {
+            to._strict = from._strict;
+        }
+        if (typeof from._tzm !== 'undefined') {
+            to._tzm = from._tzm;
+        }
+        if (typeof from._isUTC !== 'undefined') {
+            to._isUTC = from._isUTC;
+        }
+        if (typeof from._offset !== 'undefined') {
+            to._offset = from._offset;
+        }
+        if (typeof from._pf !== 'undefined') {
+            to._pf = from._pf;
+        }
+        if (typeof from._locale !== 'undefined') {
+            to._locale = from._locale;
+        }
+
+        if (momentProperties.length > 0) {
+            for (i in momentProperties) {
+                prop = momentProperties[i];
+                val = from[prop];
+                if (typeof val !== 'undefined') {
+                    to[prop] = val;
+                }
             }
         }
 
-        return result;
+        return to;
     }
 
     function absRound(number) {
         return (sign ? (forceSign ? '+' : '') : '-') + output;
     }
 
-    // helper function for _.addTime and _.subtractTime
+    function positiveMomentsDifference(base, other) {
+        var res = {milliseconds: 0, months: 0};
+
+        res.months = other.month() - base.month() +
+            (other.year() - base.year()) * 12;
+        if (base.clone().add(res.months, 'M').isAfter(other)) {
+            --res.months;
+        }
+
+        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));
+
+        return res;
+    }
+
+    function momentsDifference(base, other) {
+        var res;
+        other = makeAs(other, base);
+        if (base.isBefore(other)) {
+            res = positiveMomentsDifference(base, other);
+        } else {
+            res = positiveMomentsDifference(other, base);
+            res.milliseconds = -res.milliseconds;
+            res.months = -res.months;
+        }
+
+        return res;
+    }
+
+    // TODO: remove 'name' arg after deprecation is removed
+    function createAdder(direction, name) {
+        return function (val, period) {
+            var dur, tmp;
+            //invert the arguments, but complain about it
+            if (period !== null && !isNaN(+period)) {
+                deprecateSimple(name, "moment()." + name  + "(period, number) is deprecated. Please use moment()." + name + "(number, period).");
+                tmp = val; val = period; period = tmp;
+            }
+
+            val = typeof val === 'string' ? +val : val;
+            dur = moment.duration(val, period);
+            addOrSubtractDurationFromMoment(this, dur, direction);
+            return this;
+        };
+    }
+
     function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {
         var milliseconds = duration._milliseconds,
             days = duration._days,
     }
 
     function isDate(input) {
-        return  Object.prototype.toString.call(input) === '[object Date]' ||
-                input instanceof Date;
+        return Object.prototype.toString.call(input) === '[object Date]' ||
+            input instanceof Date;
     }
 
     // compare two arrays, return the number of differences
 
         moment[field] = function (format, index) {
             var i, getter,
-                method = moment.fn._lang[field],
+                method = moment._locale[field],
                 results = [];
 
             if (typeof format === 'number') {
 
             getter = function (i) {
                 var m = moment().utc().set(setter, i);
-                return method.call(moment.fn._lang, m, format || '');
+                return method.call(moment._locale, m, format || '');
             };
 
             if (index != null) {
         return m._isValid;
     }
 
-    function normalizeLanguage(key) {
+    function normalizeLocale(key) {
         return key ? key.toLowerCase().replace('_', '-') : key;
     }
 
+    // pick the locale from the array
+    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
+    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
+    function chooseLocale(names) {
+        var i = 0, j, next, locale, split;
+
+        while (i < names.length) {
+            split = normalizeLocale(names[i]).split('-');
+            j = split.length;
+            next = normalizeLocale(names[i + 1]);
+            next = next ? next.split('-') : null;
+            while (j > 0) {
+                locale = loadLocale(split.slice(0, j).join('-'));
+                if (locale) {
+                    return locale;
+                }
+                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
+                    //the next array item is better than a shallower substring of this one
+                    break;
+                }
+                j--;
+            }
+            i++;
+        }
+        return null;
+    }
+
+    function loadLocale(name) {
+        var oldLocale = null;
+        if (!locales[name] && hasModule) {
+            try {
+                oldLocale = moment.locale();
+                require('./locale/' + name);
+                // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales
+                moment.locale(oldLocale);
+            } catch (e) { }
+        }
+        return locales[name];
+    }
+
     // Return a moment from input, that is local/utc/zone equivalent to model.
     function makeAs(input, model) {
         return model._isUTC ? moment(input).zone(model._offset || 0) :
     }
 
     /************************************
-        Languages
+        Locale
     ************************************/
 
 
-    extend(Language.prototype, {
+    extend(Locale.prototype, {
 
         set : function (config) {
             var prop, i;
             }
         },
 
-        _months : "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
+        _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
         months : function (m) {
             return this._months[m.month()];
         },
 
-        _monthsShort : "Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),
+        _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
         monthsShort : function (m) {
             return this._monthsShort[m.month()];
         },
             }
         },
 
-        _weekdays : "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
+        _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
         weekdays : function (m) {
             return this._weekdays[m.day()];
         },
 
-        _weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+        _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
         weekdaysShort : function (m) {
             return this._weekdaysShort[m.day()];
         },
 
-        _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+        _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
         weekdaysMin : function (m) {
             return this._weekdaysMin[m.day()];
         },
         },
 
         _longDateFormat : {
-            LT : "h:mm A",
-            L : "MM/DD/YYYY",
-            LL : "MMMM D YYYY",
-            LLL : "MMMM D YYYY LT",
-            LLLL : "dddd, MMMM D YYYY LT"
+            LT : 'h:mm A',
+            L : 'MM/DD/YYYY',
+            LL : 'MMMM D, YYYY',
+            LLL : 'MMMM D, YYYY LT',
+            LLLL : 'dddd, MMMM D, YYYY LT'
         },
         longDateFormat : function (key) {
             var output = this._longDateFormat[key];
         },
 
         _relativeTime : {
-            future : "in %s",
-            past : "%s ago",
-            s : "a few seconds",
-            m : "a minute",
-            mm : "%d minutes",
-            h : "an hour",
-            hh : "%d hours",
-            d : "a day",
-            dd : "%d days",
-            M : "a month",
-            MM : "%d months",
-            y : "a year",
-            yy : "%d years"
+            future : 'in %s',
+            past : '%s ago',
+            s : 'a few seconds',
+            m : 'a minute',
+            mm : '%d minutes',
+            h : 'an hour',
+            hh : '%d hours',
+            d : 'a day',
+            dd : '%d days',
+            M : 'a month',
+            MM : '%d months',
+            y : 'a year',
+            yy : '%d years'
         },
+
         relativeTime : function (number, withoutSuffix, string, isFuture) {
             var output = this._relativeTime[string];
             return (typeof output === 'function') ?
                 output(number, withoutSuffix, string, isFuture) :
                 output.replace(/%d/i, number);
         },
+
         pastFuture : function (diff, output) {
             var format = this._relativeTime[diff > 0 ? 'future' : 'past'];
             return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);
         },
 
         ordinal : function (number) {
-            return this._ordinal.replace("%d", number);
+            return this._ordinal.replace('%d', number);
         },
-        _ordinal : "%d",
+        _ordinal : '%d',
 
         preparse : function (string) {
             return string;
         }
     });
 
-    // Loads a language definition into the `languages` cache.  The function
-    // takes a key and optionally values.  If not in the browser and no values
-    // are provided, it will load the language file module.  As a convenience,
-    // this function also returns the language values.
-    function loadLang(key, values) {
-        values.abbr = key;
-        if (!languages[key]) {
-            languages[key] = new Language();
-        }
-        languages[key].set(values);
-        return languages[key];
-    }
-
-    // Remove a language from the `languages` cache. Mostly useful in tests.
-    function unloadLang(key) {
-        delete languages[key];
-    }
-
-    // Determines which language definition to use and returns it.
-    //
-    // With no parameters, it will return the global language.  If you
-    // pass in a language key, such as 'en', it will return the
-    // definition for 'en', so long as 'en' has already been loaded using
-    // moment.lang.
-    function getLangDefinition(key) {
-        var i = 0, j, lang, next, split,
-            get = function (k) {
-                if (!languages[k] && hasModule) {
-                    try {
-                        require('./lang/' + k);
-                    } catch (e) { }
-                }
-                return languages[k];
-            };
-
-        if (!key) {
-            return moment.fn._lang;
-        }
-
-        if (!isArray(key)) {
-            //short-circuit everything else
-            lang = get(key);
-            if (lang) {
-                return lang;
-            }
-            key = [key];
-        }
-
-        //pick the language from the array
-        //try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
-        //substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
-        while (i < key.length) {
-            split = normalizeLanguage(key[i]).split('-');
-            j = split.length;
-            next = normalizeLanguage(key[i + 1]);
-            next = next ? next.split('-') : null;
-            while (j > 0) {
-                lang = get(split.slice(0, j).join('-'));
-                if (lang) {
-                    return lang;
-                }
-                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
-                    //the next array item is better than a shallower substring of this one
-                    break;
-                }
-                j--;
-            }
-            i++;
-        }
-        return moment.fn._lang;
-    }
-
     /************************************
         Formatting
     ************************************/
 
     function removeFormattingTokens(input) {
         if (input.match(/\[[\s\S]/)) {
-            return input.replace(/^\[|\]$/g, "");
+            return input.replace(/^\[|\]$/g, '');
         }
-        return input.replace(/\\/g, "");
+        return input.replace(/\\/g, '');
     }
 
     function makeFormatFunction(format) {
         }
 
         return function (mom) {
-            var output = "";
+            var output = '';
             for (i = 0; i < length; i++) {
                 output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
             }
 
     // format date using native date object
     function formatMoment(m, format) {
-
         if (!m.isValid()) {
-            return m.lang().invalidDate();
+            return m.localeData().invalidDate();
         }
 
-        format = expandFormat(format, m.lang());
+        format = expandFormat(format, m.localeData());
 
         if (!formatFunctions[format]) {
             formatFunctions[format] = makeFormatFunction(format);
         return formatFunctions[format](m);
     }
 
-    function expandFormat(format, lang) {
+    function expandFormat(format, locale) {
         var i = 5;
 
         function replaceLongDateFormatTokens(input) {
-            return lang.longDateFormat(input) || input;
+            return locale.longDateFormat(input) || input;
         }
 
         localFormattingTokens.lastIndex = 0;
         case 'ggggg':
             return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
         case 'S':
-            if (strict) { return parseTokenOneDigit; }
+            if (strict) {
+                return parseTokenOneDigit;
+            }
             /* falls through */
         case 'SS':
-            if (strict) { return parseTokenTwoDigits; }
+            if (strict) {
+                return parseTokenTwoDigits;
+            }
             /* falls through */
         case 'SSS':
-            if (strict) { return parseTokenThreeDigits; }
+            if (strict) {
+                return parseTokenThreeDigits;
+            }
             /* falls through */
         case 'DDD':
             return parseTokenOneToThreeDigits;
             return parseTokenWord;
         case 'a':
         case 'A':
-            return getLangDefinition(config._l)._meridiemParse;
+            return config._locale._meridiemParse;
         case 'X':
             return parseTokenTimestampMs;
         case 'Z':
         case 'Do':
             return parseTokenOrdinal;
         default :
-            a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
+            a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), 'i'));
             return a;
         }
     }
 
     function timezoneMinutesFromString(string) {
-        string = string || "";
+        string = string || '';
         var possibleTzMatches = (string.match(parseTokenTimezone) || []),
             tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
             parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
             break;
         case 'MMM' : // fall through to MMMM
         case 'MMMM' :
-            a = getLangDefinition(config._l).monthsParse(input);
+            a = config._locale.monthsParse(input);
             // if we didn't find a month name, mark the date as invalid.
             if (a != null) {
                 datePartArray[MONTH] = a;
         // AM / PM
         case 'a' : // fall through to A
         case 'A' :
-            config._isPm = getLangDefinition(config._l).isPM(input);
+            config._isPm = config._locale.isPM(input);
             break;
         // 24 HOUR
         case 'H' : // fall through to hh
         case 'dd':
         case 'ddd':
         case 'dddd':
-            a = getLangDefinition(config._l).weekdaysParse(input);
+            a = config._locale.weekdaysParse(input);
             // if we didn't get a weekday name, mark the date as invalid
             if (a != null) {
                 config._w = config._w || {};
     }
 
     function dayOfYearFromWeekInfo(config) {
-        var w, weekYear, week, weekday, dow, doy, temp, lang;
+        var w, weekYear, week, weekday, dow, doy, temp;
 
         w = config._w;
         if (w.GG != null || w.W != null || w.E != null) {
             week = dfl(w.W, 1);
             weekday = dfl(w.E, 1);
         } else {
-            lang = getLangDefinition(config._l);
-            dow = lang._week.dow;
-            doy = lang._week.doy;
+            dow = config._locale._week.dow;
+            doy = config._locale._week.doy;
 
             weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);
             week = dfl(w.w, 1);
 
     // date from string and format string
     function makeDateFromStringAndFormat(config) {
-
         if (config._f === moment.ISO_8601) {
             parseISO(config);
             return;
         config._pf.empty = true;
 
         // This array is used to make a Date, either with `new Date` or `Date.UTC`
-        var lang = getLangDefinition(config._l),
-            string = '' + config._i,
+        var string = '' + config._i,
             i, parsedInput, tokens, token, skipped,
             stringLength = string.length,
             totalParsedInputLength = 0;
 
-        tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
+        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];
 
         for (i = 0; i < tokens.length; i++) {
             token = tokens[i];
 
         for (i = 0; i < config._f.length; i++) {
             currentScore = 0;
-            tempConfig = extend({}, config);
+            tempConfig = copyConfig({}, config);
             tempConfig._pf = defaultParsingFlags();
             tempConfig._f = config._f[i];
             makeDateFromStringAndFormat(tempConfig);
             for (i = 0, l = isoDates.length; i < l; i++) {
                 if (isoDates[i][1].exec(string)) {
                     // match[5] should be "T" or undefined
-                    config._f = isoDates[i][0] + (match[6] || " ");
+                    config._f = isoDates[i][0] + (match[6] || ' ');
                     break;
                 }
             }
                 }
             }
             if (string.match(parseTokenTimezone)) {
-                config._f += "Z";
+                config._f += 'Z';
             }
             makeDateFromStringAndFormat(config);
         } else {
     }
 
     function makeDateFromInput(config) {
-        var input = config._i,
-            matched = aspNetJsonRegex.exec(input);
-
+        var input = config._i, matched;
         if (input === undefined) {
             config._d = new Date();
-        } else if (matched) {
+        } else if (isDate(input)) {
+            config._d = new Date(+input);
+        } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {
             config._d = new Date(+matched[1]);
         } else if (typeof input === 'string') {
             makeDateFromString(config);
         } else if (isArray(input)) {
             config._a = input.slice(0);
             dateFromConfig(config);
-        } else if (isDate(input)) {
-            config._d = new Date(+input);
         } else if (typeof(input) === 'object') {
             dateFromObject(config);
         } else if (typeof(input) === 'number') {
         return date;
     }
 
-    function parseWeekday(input, language) {
+    function parseWeekday(input, locale) {
         if (typeof input === 'string') {
             if (!isNaN(input)) {
                 input = parseInt(input, 10);
             }
             else {
-                input = language.weekdaysParse(input);
+                input = locale.weekdaysParse(input);
                 if (typeof input !== 'number') {
                     return null;
                 }
 
 
     // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
-    function substituteTimeAgo(string, number, withoutSuffix, isFuture, lang) {
-        return lang.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
+    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
+        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
     }
 
-    function relativeTime(milliseconds, withoutSuffix, lang) {
-        var seconds = round(Math.abs(milliseconds) / 1000),
-            minutes = round(seconds / 60),
-            hours = round(minutes / 60),
-            days = round(hours / 24),
-            years = round(days / 365),
-            args = seconds < relativeTimeThresholds.s  && ['s', seconds] ||
+    function relativeTime(posNegDuration, withoutSuffix, locale) {
+        var duration = moment.duration(posNegDuration).abs(),
+            seconds = round(duration.as('s')),
+            minutes = round(duration.as('m')),
+            hours = round(duration.as('h')),
+            days = round(duration.as('d')),
+            months = round(duration.as('M')),
+            years = round(duration.as('y')),
+
+            args = seconds < relativeTimeThresholds.s && ['s', seconds] ||
                 minutes === 1 && ['m'] ||
                 minutes < relativeTimeThresholds.m && ['mm', minutes] ||
                 hours === 1 && ['h'] ||
                 hours < relativeTimeThresholds.h && ['hh', hours] ||
                 days === 1 && ['d'] ||
-                days <= relativeTimeThresholds.dd && ['dd', days] ||
-                days <= relativeTimeThresholds.dm && ['M'] ||
-                days < relativeTimeThresholds.dy && ['MM', round(days / 30)] ||
+                days < relativeTimeThresholds.d && ['dd', days] ||
+                months === 1 && ['M'] ||
+                months < relativeTimeThresholds.M && ['MM', months] ||
                 years === 1 && ['y'] || ['yy', years];
+
         args[2] = withoutSuffix;
-        args[3] = milliseconds > 0;
-        args[4] = lang;
+        args[3] = +posNegDuration > 0;
+        args[4] = locale;
         return substituteTimeAgo.apply({}, args);
     }
 
             daysToDayOfWeek += 7;
         }
 
-        adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
+        adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');
         return {
             week: Math.ceil(adjustedMoment.dayOfYear() / 7),
             year: adjustedMoment.year()
         var input = config._i,
             format = config._f;
 
+        config._locale = config._locale || moment.localeData(config._l);
+
         if (input === null || (format === undefined && input === '')) {
             return moment.invalid({nullInput: true});
         }
 
         if (typeof input === 'string') {
-            config._i = input = getLangDefinition().preparse(input);
+            config._i = input = config._locale.preparse(input);
         }
 
         if (moment.isMoment(input)) {
-            config = cloneMoment(input);
-
-            config._d = new Date(+input._d);
+            return new Moment(input, true);
         } else if (format) {
             if (isArray(format)) {
                 makeDateFromStringAndArray(config);
         return new Moment(config);
     }
 
-    moment = function (input, format, lang, strict) {
+    moment = function (input, format, locale, strict) {
         var c;
 
-        if (typeof(lang) === "boolean") {
-            strict = lang;
-            lang = undefined;
+        if (typeof(locale) === "boolean") {
+            strict = locale;
+            locale = undefined;
         }
         // object construction must be done this way.
         // https://github.com/moment/moment/issues/1423
         c._isAMomentObject = true;
         c._i = input;
         c._f = format;
-        c._l = lang;
+        c._l = locale;
         c._strict = strict;
         c._isUTC = false;
         c._pf = defaultParsingFlags();
     moment.suppressDeprecationWarnings = false;
 
     moment.createFromInputFallback = deprecate(
-            "moment construction falls back to js Date. This is " +
-            "discouraged and will be removed in upcoming major " +
-            "release. Please refer to " +
-            "https://github.com/moment/moment/issues/1407 for more info.",
-            function (config) {
-        config._d = new Date(config._i);
-    });
+        'moment construction falls back to js Date. This is ' +
+        'discouraged and will be removed in upcoming major ' +
+        'release. Please refer to ' +
+        'https://github.com/moment/moment/issues/1407 for more info.',
+        function (config) {
+            config._d = new Date(config._i);
+        }
+    );
 
     // Pick a moment m from moments so that m[fn](other) is true for all
     // other. This relies on the function fn to be transitive.
     };
 
     // creating with utc
-    moment.utc = function (input, format, lang, strict) {
+    moment.utc = function (input, format, locale, strict) {
         var c;
 
-        if (typeof(lang) === "boolean") {
-            strict = lang;
-            lang = undefined;
+        if (typeof(locale) === "boolean") {
+            strict = locale;
+            locale = undefined;
         }
         // object construction must be done this way.
         // https://github.com/moment/moment/issues/1423
         c._isAMomentObject = true;
         c._useUTC = true;
         c._isUTC = true;
-        c._l = lang;
+        c._l = locale;
         c._i = input;
         c._f = format;
         c._strict = strict;
             match = null,
             sign,
             ret,
-            parseIso;
+            parseIso,
+            diffRes;
 
         if (moment.isDuration(input)) {
             duration = {
                 duration.milliseconds = input;
             }
         } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
-            sign = (match[1] === "-") ? -1 : 1;
+            sign = (match[1] === '-') ? -1 : 1;
             duration = {
                 y: 0,
                 d: toInt(match[DATE]) * sign,
                 ms: toInt(match[MILLISECOND]) * sign
             };
         } else if (!!(match = isoDurationRegex.exec(input))) {
-            sign = (match[1] === "-") ? -1 : 1;
+            sign = (match[1] === '-') ? -1 : 1;
             parseIso = function (inp) {
                 // We'd normally use ~~inp for this, but unfortunately it also
                 // converts floats to ints.
                 s: parseIso(match[7]),
                 w: parseIso(match[8])
             };
+        } else if (typeof duration === 'object' &&
+                ('from' in duration || 'to' in duration)) {
+            diffRes = momentsDifference(moment(duration.from), moment(duration.to));
+
+            duration = {};
+            duration.ms = diffRes.milliseconds;
+            duration.M = diffRes.months;
         }
 
         ret = new Duration(duration);
 
-        if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
-            ret._lang = input._lang;
+        if (moment.isDuration(input) && input.hasOwnProperty('_locale')) {
+            ret._locale = input._locale;
         }
 
         return ret;
     moment.updateOffset = function () {};
 
     // This function allows you to set a threshold for relative time strings
-    moment.relativeTimeThreshold = function(threshold, limit) {
-      if (relativeTimeThresholds[threshold] === undefined) {
-        return false;
-      }
-      relativeTimeThresholds[threshold] = limit;
-      return true;
+    moment.relativeTimeThreshold = function (threshold, limit) {
+        if (relativeTimeThresholds[threshold] === undefined) {
+            return false;
+        }
+        if (limit === undefined) {
+            return relativeTimeThresholds[threshold];
+        }
+        relativeTimeThresholds[threshold] = limit;
+        return true;
     };
 
-    // This function will load languages and then set the global language.  If
+    moment.lang = deprecate(
+        "moment.lang is deprecated. Use moment.locale instead.",
+        function (key, value) {
+            return moment.locale(key, value);
+        }
+    );
+
+    // This function will load locale and then set the global locale.  If
     // no arguments are passed in, it will simply return the current global
-    // language key.
-    moment.lang = function (key, values) {
-        var r;
-        if (!key) {
-            return moment.fn._lang._abbr;
-        }
-        if (values) {
-            loadLang(normalizeLanguage(key), values);
-        } else if (values === null) {
-            unloadLang(key);
-            key = 'en';
-        } else if (!languages[key]) {
-            getLangDefinition(key);
-        }
-        r = moment.duration.fn._lang = moment.fn._lang = getLangDefinition(key);
-        return r._abbr;
+    // locale key.
+    moment.locale = function (key, values) {
+        var data;
+        if (key) {
+            if (typeof(values) !== "undefined") {
+                data = moment.defineLocale(key, values);
+            }
+            else {
+                data = moment.localeData(key);
+            }
+
+            if (data) {
+                moment.duration._locale = moment._locale = data;
+            }
+        }
+
+        return moment._locale._abbr;
     };
 
-    // returns language data
-    moment.langData = function (key) {
-        if (key && key._lang && key._lang._abbr) {
-            key = key._lang._abbr;
+    moment.defineLocale = function (name, values) {
+        if (values !== null) {
+            values.abbr = name;
+            if (!locales[name]) {
+                locales[name] = new Locale();
+            }
+            locales[name].set(values);
+
+            // backwards compat for now: also set the locale
+            moment.locale(name);
+
+            return locales[name];
+        } else {
+            // useful for testing
+            delete locales[name];
+            return null;
+        }
+    };
+
+    moment.langData = deprecate(
+        "moment.langData is deprecated. Use moment.localeData instead.",
+        function (key) {
+            return moment.localeData(key);
+        }
+    );
+
+    // returns locale data
+    moment.localeData = function (key) {
+        var locale;
+
+        if (key && key._locale && key._locale._abbr) {
+            key = key._locale._abbr;
+        }
+
+        if (!key) {
+            return moment._locale;
         }
-        return getLangDefinition(key);
+
+        if (!isArray(key)) {
+            //short-circuit everything else
+            locale = loadLocale(key);
+            if (locale) {
+                return locale;
+            }
+            key = [key];
+        }
+
+        return chooseLocale(key);
     };
 
     // compare moment object
         },
 
         toString : function () {
-            return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
+            return this.clone().locale('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
         },
 
         toDate : function () {
         },
 
         isDSTShifted : function () {
-
             if (this._a) {
                 return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
             }
             return this._pf.overflow;
         },
 
-        utc : function () {
-            return this.zone(0);
+        utc : function (keepLocalTime) {
+            return this.zone(0, keepLocalTime);
         },
 
-        local : function () {
-            this.zone(0);
-            this._isUTC = false;
+        local : function (keepLocalTime) {
+            if (this._isUTC) {
+                this.zone(0, keepLocalTime);
+                this._isUTC = false;
+
+                if (keepLocalTime) {
+                    this.add(this._d.getTimezoneOffset(), 'm');
+                }
+            }
             return this;
         },
 
         format : function (inputString) {
             var output = formatMoment(this, inputString || moment.defaultFormat);
-            return this.lang().postformat(output);
+            return this.localeData().postformat(output);
         },
 
-        add : function (input, val) {
-            var dur;
-            // switch args to support add('s', 1) and add(1, 's')
-            if (typeof input === 'string' && typeof val === 'string') {
-                dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
-            } else if (typeof input === 'string') {
-                dur = moment.duration(+val, input);
-            } else {
-                dur = moment.duration(input, val);
-            }
-            addOrSubtractDurationFromMoment(this, dur, 1);
-            return this;
-        },
+        add : createAdder(1, 'add'),
 
-        subtract : function (input, val) {
-            var dur;
-            // switch args to support subtract('s', 1) and subtract(1, 's')
-            if (typeof input === 'string' && typeof val === 'string') {
-                dur = moment.duration(isNaN(+val) ? +input : +val, isNaN(+val) ? val : input);
-            } else if (typeof input === 'string') {
-                dur = moment.duration(+val, input);
-            } else {
-                dur = moment.duration(input, val);
-            }
-            addOrSubtractDurationFromMoment(this, dur, -1);
-            return this;
-        },
+        subtract : createAdder(-1, 'subtract'),
 
         diff : function (input, units, asFloat) {
             var that = makeAs(input, this),
         },
 
         from : function (time, withoutSuffix) {
-            return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
+            return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);
         },
 
         fromNow : function (withoutSuffix) {
                     diff < 1 ? 'sameDay' :
                     diff < 2 ? 'nextDay' :
                     diff < 7 ? 'nextWeek' : 'sameElse';
-            return this.format(this.lang().calendar(format, this));
+            return this.format(this.localeData().calendar(format, this));
         },
 
         isLeapYear : function () {
         day : function (input) {
             var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();
             if (input != null) {
-                input = parseWeekday(input, this.lang());
-                return this.add({ d : input - day });
+                input = parseWeekday(input, this.localeData());
+                return this.add(input - day, 'd');
             } else {
                 return day;
             }
 
         month : makeAccessor('Month', true),
 
-        startOf: function (units) {
+        startOf : function (units) {
             units = normalizeUnits(units);
             // the following switch intentionally omits break keywords
             // to utilize falling through the cases.
 
         endOf: function (units) {
             units = normalizeUnits(units);
-            return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
+            return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');
         },
 
         isAfter: function (input, units) {
         },
 
         min: deprecate(
-                 "moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",
+                 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',
                  function (other) {
                      other = moment.apply(null, arguments);
                      return other < this ? this : other;
          ),
 
         max: deprecate(
-                "moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",
+                'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',
                 function (other) {
                     other = moment.apply(null, arguments);
                     return other > this ? this : other;
                 }
         ),
 
-        // keepTime = true means only change the timezone, without affecting
-        // the local hour. So 5:31:26 +0300 --[zone(2, true)]--> 5:31:26 +0200
-        // It is possible that 5:31:26 doesn't exist int zone +0200, so we
-        // adjust the time as needed, to be valid.
+        // keepLocalTime = true means only change the timezone, without
+        // affecting the local hour. So 5:31:26 +0300 --[zone(2, true)]-->
+        // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist int zone
+        // +0200, so we adjust the time as needed, to be valid.
         //
         // Keeping the time actually adds/subtracts (one hour)
         // from the actual represented time. That is why we call updateOffset
         // a second time. In case it wants us to change the offset again
         // _changeInProgress == true case, then we have to adjust, because
         // there is no such time in the given timezone.
-        zone : function (input, keepTime) {
-            var offset = this._offset || 0;
+        zone : function (input, keepLocalTime) {
+            var offset = this._offset || 0,
+                localAdjust;
             if (input != null) {
-                if (typeof input === "string") {
+                if (typeof input === 'string') {
                     input = timezoneMinutesFromString(input);
                 }
                 if (Math.abs(input) < 16) {
                     input = input * 60;
                 }
+                if (!this._isUTC && keepLocalTime) {
+                    localAdjust = this._d.getTimezoneOffset();
+                }
                 this._offset = input;
                 this._isUTC = true;
+                if (localAdjust != null) {
+                    this.subtract(localAdjust, 'm');
+                }
                 if (offset !== input) {
-                    if (!keepTime || this._changeInProgress) {
+                    if (!keepLocalTime || this._changeInProgress) {
                         addOrSubtractDurationFromMoment(this,
                                 moment.duration(offset - input, 'm'), 1, false);
                     } else if (!this._changeInProgress) {
         },
 
         zoneAbbr : function () {
-            return this._isUTC ? "UTC" : "";
+            return this._isUTC ? 'UTC' : '';
         },
 
         zoneName : function () {
-            return this._isUTC ? "Coordinated Universal Time" : "";
+            return this._isUTC ? 'Coordinated Universal Time' : '';
         },
 
         parseZone : function () {
 
         dayOfYear : function (input) {
             var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;
-            return input == null ? dayOfYear : this.add("d", (input - dayOfYear));
+            return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
         },
 
         quarter : function (input) {
         },
 
         weekYear : function (input) {
-            var year = weekOfYear(this, this.lang()._week.dow, this.lang()._week.doy).year;
-            return input == null ? year : this.add("y", (input - year));
+            var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;
+            return input == null ? year : this.add((input - year), 'y');
         },
 
         isoWeekYear : function (input) {
             var year = weekOfYear(this, 1, 4).year;
-            return input == null ? year : this.add("y", (input - year));
+            return input == null ? year : this.add((input - year), 'y');
         },
 
         week : function (input) {
-            var week = this.lang().week(this);
-            return input == null ? week : this.add("d", (input - week) * 7);
+            var week = this.localeData().week(this);
+            return input == null ? week : this.add((input - week) * 7, 'd');
         },
 
         isoWeek : function (input) {
             var week = weekOfYear(this, 1, 4).week;
-            return input == null ? week : this.add("d", (input - week) * 7);
+            return input == null ? week : this.add((input - week) * 7, 'd');
         },
 
         weekday : function (input) {
-            var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
-            return input == null ? weekday : this.add("d", input - weekday);
+            var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;
+            return input == null ? weekday : this.add(input - weekday, 'd');
         },
 
         isoWeekday : function (input) {
         },
 
         weeksInYear : function () {
-            var weekInfo = this._lang._week;
+            var weekInfo = this.localeData()._week;
             return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);
         },
 
             return this;
         },
 
-        // If passed a language key, it will set the language for this
-        // instance.  Otherwise, it will return the language configuration
+        // If passed a locale key, it will set the locale for this
+        // instance.  Otherwise, it will return the locale configuration
         // variables for this instance.
-        lang : function (key) {
+        locale : function (key) {
             if (key === undefined) {
-                return this._lang;
+                return this._locale._abbr;
             } else {
-                this._lang = getLangDefinition(key);
+                this._locale = moment.localeData(key);
                 return this;
             }
+        },
+
+        lang : deprecate(
+            "moment().lang() is deprecated. Use moment().localeData() instead.",
+            function (key) {
+                if (key === undefined) {
+                    return this.localeData();
+                } else {
+                    this._locale = moment.localeData(key);
+                    return this;
+                }
+            }
+        ),
+
+        localeData : function () {
+            return this._locale;
         }
     });
 
 
         // TODO: Move this out of here!
         if (typeof value === 'string') {
-            value = mom.lang().monthsParse(value);
+            value = mom.localeData().monthsParse(value);
             // TODO: Another silent failure?
             if (typeof value !== 'number') {
                 return mom;
     moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);
     // moment.fn.month is defined separately
     moment.fn.date = makeAccessor('Date', true);
-    moment.fn.dates = deprecate("dates accessor is deprecated. Use date instead.", makeAccessor('Date', true));
+    moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));
     moment.fn.year = makeAccessor('FullYear', true);
-    moment.fn.years = deprecate("years accessor is deprecated. Use year instead.", makeAccessor('FullYear', true));
+    moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));
 
     // add plural methods
     moment.fn.days = moment.fn.day;
     ************************************/
 
 
+    function daysToYears (days) {
+        // 400 years have 146097 days (taking into account leap year rules)
+        return days * 400 / 146097;
+    }
+
+    function yearsToDays (years) {
+        // years * 365 + absRound(years / 4) -
+        //     absRound(years / 100) + absRound(years / 400);
+        return years * 146097 / 400;
+    }
+
     extend(moment.duration.fn = Duration.prototype, {
 
         _bubble : function () {
                 days = this._days,
                 months = this._months,
                 data = this._data,
-                seconds, minutes, hours, years;
+                seconds, minutes, hours, years = 0;
 
             // The following code bubbles up values, see the tests for
             // examples of what that means.
             data.hours = hours % 24;
 
             days += absRound(hours / 24);
-            data.days = days % 30;
 
+            // Accurately convert days to years, assume start from year 0.
+            years = absRound(daysToYears(days));
+            days -= absRound(yearsToDays(years));
+
+            // 30 days to a month
+            // TODO (iskren): Use anchor date (like 1st Jan) to compute this.
             months += absRound(days / 30);
-            data.months = months % 12;
+            days %= 30;
+
+            // 12 months -> 1 year
+            years += absRound(months / 12);
+            months %= 12;
 
-            years = absRound(months / 12);
+            data.days = days;
+            data.months = months;
             data.years = years;
         },
 
+        abs : function () {
+            this._milliseconds = Math.abs(this._milliseconds);
+            this._days = Math.abs(this._days);
+            this._months = Math.abs(this._months);
+
+            this._data.milliseconds = Math.abs(this._data.milliseconds);
+            this._data.seconds = Math.abs(this._data.seconds);
+            this._data.minutes = Math.abs(this._data.minutes);
+            this._data.hours = Math.abs(this._data.hours);
+            this._data.months = Math.abs(this._data.months);
+            this._data.years = Math.abs(this._data.years);
+
+            return this;
+        },
+
         weeks : function () {
             return absRound(this.days() / 7);
         },
         },
 
         humanize : function (withSuffix) {
-            var difference = +this,
-                output = relativeTime(difference, !withSuffix, this.lang());
+            var output = relativeTime(this, !withSuffix, this.localeData());
 
             if (withSuffix) {
-                output = this.lang().pastFuture(difference, output);
+                output = this.localeData().pastFuture(+this, output);
             }
 
-            return this.lang().postformat(output);
+            return this.localeData().postformat(output);
         },
 
         add : function (input, val) {
         },
 
         as : function (units) {
+            var days, months;
             units = normalizeUnits(units);
-            return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
+
+            days = this._days + this._milliseconds / 864e5;
+            if (units === 'month' || units === 'year') {
+                months = this._months + daysToYears(days) * 12;
+                return units === 'month' ? months : months / 12;
+            } else {
+                days += yearsToDays(this._months / 12);
+                switch (units) {
+                    case 'week': return days / 7;
+                    case 'day': return days;
+                    case 'hour': return days * 24;
+                    case 'minute': return days * 24 * 60;
+                    case 'second': return days * 24 * 60 * 60;
+                    case 'millisecond': return days * 24 * 60 * 60 * 1000;
+                    default: throw new Error('Unknown unit ' + units);
+                }
+            }
         },
 
         lang : moment.fn.lang,
+        locale : moment.fn.locale,
+
+        toIsoString : deprecate(
+            "toIsoString() is deprecated. Please use toISOString() instead " +
+            "(notice the capitals)",
+            function () {
+                return this.toISOString();
+            }
+        ),
 
-        toIsoString : function () {
+        toISOString : function () {
             // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
             var years = Math.abs(this.years()),
                 months = Math.abs(this.months()),
                 (hours ? hours + 'H' : '') +
                 (minutes ? minutes + 'M' : '') +
                 (seconds ? seconds + 'S' : '');
+        },
+
+        localeData : function () {
+            return this._locale;
         }
     });
 
         };
     }
 
-    function makeDurationAsGetter(name, factor) {
-        moment.duration.fn['as' + name] = function () {
-            return +this / factor;
-        };
-    }
-
     for (i in unitMillisecondFactors) {
         if (unitMillisecondFactors.hasOwnProperty(i)) {
-            makeDurationAsGetter(i, unitMillisecondFactors[i]);
             makeDurationGetter(i.toLowerCase());
         }
     }
 
-    makeDurationAsGetter('Weeks', 6048e5);
+    moment.duration.fn.asMilliseconds = function () {
+        return this.as('ms');
+    };
+    moment.duration.fn.asSeconds = function () {
+        return this.as('s');
+    };
+    moment.duration.fn.asMinutes = function () {
+        return this.as('m');
+    };
+    moment.duration.fn.asHours = function () {
+        return this.as('h');
+    };
+    moment.duration.fn.asDays = function () {
+        return this.as('d');
+    };
+    moment.duration.fn.asWeeks = function () {
+        return this.as('weeks');
+    };
     moment.duration.fn.asMonths = function () {
-        return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
+        return this.as('M');
+    };
+    moment.duration.fn.asYears = function () {
+        return this.as('y');
     };
-
 
     /************************************
-        Default Lang
+        Default Locale
     ************************************/
 
 
-    // Set default language, other languages will inherit from English.
-    moment.lang('en', {
+    // Set default locale, other locale will inherit from English.
+    moment.locale('en', {
         ordinal : function (number) {
             var b = number % 10,
                 output = (toInt(number % 100 / 10) === 1) ? 'th' :
         }
     });
 
-    /* EMBED_LANGUAGES */
+    /* EMBED_LOCALES */
 
     /************************************
         Exposing Moment
         oldGlobalMoment = globalScope.moment;
         if (shouldDeprecate) {
             globalScope.moment = deprecate(
-                    "Accessing Moment through the global scope is " +
-                    "deprecated, and will be removed in an upcoming " +
-                    "release.",
+                    'Accessing Moment through the global scope is ' +
+                    'deprecated, and will be removed in an upcoming ' +
+                    'release.',
                     moment);
         } else {
             globalScope.moment = moment;
     // CommonJS module is defined
     if (hasModule) {
         module.exports = moment;
-    } else if (typeof define === "function" && define.amd) {
-        define("moment", function (require, exports, module) {
+    } else if (typeof define === 'function' && define.amd) {
+        define('moment', function (require, exports, module) {
             if (module.config && module.config() && module.config().noGlobal === true) {
                 // release the global variable
                 globalScope.moment = oldGlobalMoment;
index b46ab37..ea2c5f9 100644 (file)
                        } );
                        // We want to find the row that has the most columns (ignoring colspan)
                        $.each( exploded, function ( index, cellArray ) {
-                               headerCount = $.unique( $( cellArray ) ).length;
+                               headerCount = $( uniqueElements( cellArray ) ).filter( 'th' ).length;
                                if ( headerCount >= maxSeen ) {
                                        maxSeen = headerCount;
                                        longestTR = index;
                                }
                        } );
                        // We cannot use $.unique() here because it sorts into dom order, which is undesirable
-                       $tableHeaders = $( uniqueElements( exploded[longestTR] ) );
+                       $tableHeaders = $( uniqueElements( exploded[longestTR] ) ).filter( 'th' );
                }
 
                // as each header can span over multiple columns (using colspan=N),
index 743d651..c1e1dab 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * @class mw.plugin.notify
  */
-( function ( mw, $ ) {
+( function ( mw ) {
        'use strict';
 
        /**
         * @return {jQuery.Promise}
         */
        mw.notify = function ( message, options ) {
-               var d = $.Deferred();
                // Don't bother loading the whole notification system if we never use it.
-               mw.loader.using( 'mediawiki.notification', function () {
-                       // Call notify with the notification the user requested of us.
-                       d.resolve( mw.notification.notify( message, options ) );
-               }, d.reject );
-               return d.promise();
+               return mw.loader.using( 'mediawiki.notification' )
+                       .then( function () {
+                               // Call notify with the notification the user requested of us.
+                               return mw.notification.notify( message, options );
+                       } );
        };
 
        /**
@@ -25,4 +24,4 @@
         * @mixins mw.plugin.notify
         */
 
-}( mediaWiki, jQuery ) );
+}( mediaWiki ) );
diff --git a/skins/README b/skins/README
new file mode 100644 (file)
index 0000000..4145b35
--- /dev/null
@@ -0,0 +1,29 @@
+Skins, such as the default skin Vector, are distributed separately. Drop them
+into this directory and enable as per the skin's installation instructions.
+
+You can find a list of available skins at
+<https://www.mediawiki.org/wiki/Category:All_skins>,
+and more information about installing and configuring skins at
+<https://www.mediawiki.org/wiki/Manual:Skin_configuration>.
+
+If you are a developer, you might want to fetch the skin tree in another
+directory and make a symbolic link:
+
+ mediawiki/skins$ ln -s ../../skins-trunk/FooBar
+
+Most skins are available through Git:
+    https://gerrit.wikimedia.org/r/#/admin/projects/?filter=mediawiki%252Fskins%252F
+    https://git.wikimedia.org/project/mediawiki
+
+
+Please note that under POSIX systems (Linux...), parent of a symbolic path
+refers to the link source, NOT to the target! You should check the env
+variable MW_INSTALL_PATH in case the extension is not in the default location.
+
+The following code snippet lets you override the default path:
+
+ $IP = getenv( 'MW_INSTALL_PATH' );
+ if( $IP === false ) {
+       $IP = __DIR__ . '/../..';
+ }
+ require_once "$IP/maintenance/Maintenance.php"; // a MediaWiki core file
index 0b7c6cf..0078d7e 100644 (file)
@@ -35,6 +35,7 @@ $wgAutoloadClasses += array(
        'TestRecorder' => "$testDir/testHelpers.inc",
        'ITestRecorder' => "$testDir/testHelpers.inc",
        'DjVuSupport' => "$testDir/testHelpers.inc",
+       'TidySupport' => "$testDir/testHelpers.inc",
 
        # tests/phpunit
        'MediaWikiTestCase' => "$testDir/phpunit/MediaWikiTestCase.php",
index e76b9df..2c44150 100644 (file)
@@ -69,6 +69,11 @@ class ParserTest {
         */
        private $djVuSupport;
 
+       /**
+        * @var TidySupport
+        */
+       private $tidySupport;
+
        private $maxFuzzTestLength = 300;
        private $fuzzSeed = 0;
        private $memoryLimit = 50;
@@ -137,6 +142,10 @@ class ParserTest {
                $this->runParsoid = isset( $options['run-parsoid'] );
 
                $this->djVuSupport = new DjVuSupport();
+               $this->tidySupport = new TidySupport();
+               if ( !$this->tidySupport->isEnabled() ) {
+                       echo "Warning: tidy is not installed, skipping some tests\n";
+               }
 
                $this->hooks = array();
                $this->functionHooks = array();
@@ -611,6 +620,13 @@ class ParserTest {
                        $output = $parser->parse( $input, $title, $options, true, true, 1337 );
                        $output->setTOCEnabled( !isset( $opts['notoc'] ) );
                        $out = $output->getText();
+                       if ( isset( $opts['tidy'] ) ) {
+                               if ( !$this->tidySupport->isEnabled() ) {
+                                       return $this->showSkipped();
+                               }
+                               $out = MWTidy::tidy( $out );
+                               $out = preg_replace( '/\s+$/', '', $out);
+                       }
 
                        if ( isset( $opts['showtitle'] ) ) {
                                if ( $output->getTitleText() ) {
@@ -621,20 +637,18 @@ class ParserTest {
                        }
 
                        if ( isset( $opts['ill'] ) ) {
-                               $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) );
+                               $out = implode( ' ', $output->getLanguageLinks() );
                        } elseif ( isset( $opts['cat'] ) ) {
                                $outputPage = $context->getOutput();
                                $outputPage->addCategoryLinks( $output->getCategories() );
                                $cats = $outputPage->getCategoryLinks();
 
                                if ( isset( $cats['normal'] ) ) {
-                                       $out = $this->tidy( implode( ' ', $cats['normal'] ) );
+                                       $out = implode( ' ', $cats['normal'] );
                                } else {
                                        $out = '';
                                }
                        }
-
-                       $result = $this->tidy( $result );
                }
 
                $this->teardownGlobals();
@@ -770,6 +784,8 @@ class ParserTest {
         * @param string $config
         */
        private function setupGlobals( $opts = '', $config = '' ) {
+               global $IP;
+
                # Find out values for some special options.
                $lang =
                        self::getOptionValue( 'language', $opts, 'en' );
@@ -813,6 +829,7 @@ class ParserTest {
                                ) )
                        ),
                        'wgEnableUploads' => self::getOptionValue( 'wgEnableUploads', $opts, true ),
+                       'wgUploadNavigationUrl' => false,
                        'wgStylePath' => '/skins',
                        'wgSitename' => 'MediaWiki',
                        'wgLanguageCode' => $lang,
@@ -832,7 +849,6 @@ class ParserTest {
                        'wgLocaltimezone' => 'UTC',
                        'wgAllowExternalImages' => self::getOptionValue( 'wgAllowExternalImages', $opts, true ),
                        'wgThumbLimits' => array( self::getOptionValue( 'thumbsize', $opts, 180 ) ),
-                       'wgUseTidy' => false,
                        'wgDefaultLanguageVariant' => $variant,
                        'wgVariantArticlePath' => false,
                        'wgGroupPermissions' => array( '*' => array(
@@ -848,13 +864,22 @@ class ParserTest {
                        'wgLinkHolderBatchSize' => $linkHolderBatchSize,
                        'wgExperimentalHtmlIds' => false,
                        'wgExternalLinkTarget' => false,
-                       'wgAlwaysUseTidy' => false,
                        'wgHtml5' => true,
                        'wgWellFormedXml' => true,
                        'wgAllowMicrodataAttributes' => true,
                        'wgAdaptiveMessageCache' => true,
                        'wgDisableLangConversion' => false,
                        'wgDisableTitleConversion' => false,
+                       // Tidy options.
+                       // We always set 'wgUseTidy' to false when parsing, but certain
+                       // test-running modes still use tidy if available, so ensure
+                       // that the tidy-related options are all set to their defaults.
+                       'wgUseTidy' => false,
+                       'wgAlwaysUseTidy' => false,
+                       'wgDebugTidy' => false,
+                       'wgTidyConf' => $IP . '/includes/tidy.conf',
+                       'wgTidyOpts' => '',
+                       'wgTidyInternal' => $this->tidySupport->isInternal(),
                );
 
                if ( $config ) {
@@ -1564,23 +1589,6 @@ class ParserTest {
                return true;
        }
 
-       /**
-        * Run the "tidy" command on text if the $wgUseTidy
-        * global is true
-        *
-        * @param string $text The text to tidy
-        * @return string
-        */
-       private function tidy( $text ) {
-               global $wgUseTidy;
-
-               if ( $wgUseTidy ) {
-                       $text = MWTidy::tidy( $text );
-               }
-
-               return $text;
-       }
-
        private function wellFormed( $text ) {
                $html =
                        Sanitizer::hackDocType() .
index 62e160b..3a315e1 100644 (file)
@@ -46,6 +46,12 @@ Main Page
 blah blah
 !! endarticle
 
+!!article
+Foo
+!!text
+FOO
+!!endarticle
+
 !!article
 Template:Foo
 !!text
@@ -401,6 +407,13 @@ http://fr.wikipedia.org/wiki/🍺
 </p>
 !! end
 
+# Note that the html+tidy output removes the spaces after the <li>,
+# which is a bug (http://sourceforge.net/p/tidy/bugs/945/, etc).
+# This is an issue for all tests with lists.  We intentionally do
+# *not* add html+tidy clauses for these, as we don't want to
+# document/test the broken behavior.  (Parsoid matches the non-tidy
+# output in these cases.)
+
 !! test
 Simple list
 !! wikitext
@@ -757,7 +770,7 @@ Italics and bold: 5-quote opening sequence: (5,2+3)
 parsoid=wt2wt,html2wt
 !! wikitext
 '''''foo'''''
-!! html/*
+!! html
 <p><b><i>foo</i></b>
 </p>
 !! end
@@ -1037,7 +1050,16 @@ parsoid=wt2html,wt2wt
 !''a!!''b
 |''a||''b
 |}
-!! html
+!! html/php+tidy
+<table>
+<tr>
+<th><i>a</i></th>
+<th><i>b</i></th>
+<td><i>a</i></td>
+<td><i>b</i></td>
+</tr>
+</table>
+!! html/parsoid
 <table>
 <tbody><tr><th><i>a</i></th><th><i>b</i></th>
 <td><i>a</i></td><td><i>b</i></td></tr>
@@ -1179,6 +1201,7 @@ Ruby markup (W3C-style)
 </p>
 !! end
 
+# There is a tidy bug here: http://sourceforge.net/p/tidy/bugs/946/
 !! test
 Non-word characters don't terminate tag names (bug 17663, 40670, 52022)
 !! wikitext
@@ -1539,6 +1562,10 @@ b
 a <div>foo</div>
 <p>b
 </p>
+!! html+tidy
+<p>a</p>
+<div>foo</div>
+<p>b</p>
 !! end
 
 !! test
@@ -1551,6 +1578,12 @@ b
 a <blockquote>foo</blockquote>
 <p>b
 </p>
+!! html+tidy
+<p>a</p>
+<blockquote>
+<p>foo</p>
+</blockquote>
+<p>b</p>
 !! end
 
 !! test
@@ -1563,6 +1596,11 @@ b <div>foo</div>
 a <div>foo</div>
 b <div>foo</div>
 
+!! html+tidy
+<p>a</p>
+<div>foo</div>
+<p>b</p>
+<div>foo</div>
 !! end
 
 !! test
@@ -1575,6 +1613,15 @@ b <blockquote>foo</blockquote>
 a <blockquote>foo</blockquote>
 b <blockquote>foo</blockquote>
 
+!! html+tidy
+<p>a</p>
+<blockquote>
+<p>foo</p>
+</blockquote>
+<p>b</p>
+<blockquote>
+<p>foo</p>
+</blockquote>
 !! end
 
 !! test
@@ -1593,6 +1640,13 @@ d e
 </p>
 x <div>foo</div> z
 
+!! html+tidy
+<div>foo</div>
+<p>a</p>
+<p>b c d e</p>
+<p>x</p>
+<div>foo</div>
+<p>z</p>
 !! end
 
 !! test
@@ -1623,9 +1677,20 @@ b
 </p>
 <div>e</div>
 
+!! html+tidy
+<p><br /></p>
+<p>a</p>
+<p>b</p>
+<div>a</div>
+<p>b</p>
+<div>b</div>
+<p>d</p>
+<p><br /></p>
+<div>e</div>
 !! end
 
 ## PHP parser emits output which is broken
+## XXX The parsoid output doesn't match the tidy output.
 !! test
 Unclosed HTML p-tags should be handled properly
 !! wikitext
@@ -1633,6 +1698,11 @@ Unclosed HTML p-tags should be handled properly
 a
 
 b
+!! html/php+tidy
+<div>
+<p>foo&lt;/div&gt;</p>
+<p>a</p>
+b</div>
 !! html/parsoid
 <div data-parsoid='{"stx":"html"}'><p data-parsoid='{"stx":"html", "autoInsertedEnd":true}'>foo</p></div>
 <p>a</p>
@@ -1784,6 +1854,10 @@ Bug 15491: <ins>/<del> in blockquote (2)
 <blockquote>Foo <del>bar</del> <ins>baz</ins> quux
 </blockquote>
 
+!! html+tidy
+<blockquote>
+<p>Foo</p>
+<del>bar</del> <ins>baz</ins> quux</blockquote>
 !! end
 
 !! test
@@ -1909,6 +1983,12 @@ foo
 </pre></div>
 <pre></pre>
 
+!! html+tidy
+<p>a</p>
+<div>
+<pre>
+foo
+</pre></div>
 !! end
 
 !! test
  a
  | b
  | c
-!! html/parsoid
+!! html/php
 <pre>a
 | b
-| c</pre>
+| c
+</pre>
 !!end
 
 !!test
@@ -2506,6 +2587,12 @@ c
 a
  | b
  | c
+!! html/php
+<p>a
+</p>
+<pre>| b
+| c
+</pre>
 !! html/parsoid
 <p>a</p>
 <pre>
@@ -2526,7 +2613,19 @@ a
  c <blockquote> foo </blockquote>
 <pre><span> foo </span>
 </pre>
-!!end
+!! html+tidy
+<p>a</p>
+<p>foo</p>
+<p>b</p>
+<div>foo</div>
+<p>c</p>
+<blockquote>
+<p>foo</p>
+</blockquote>
+<pre>
+<span> foo </span>
+</pre>
+!! end
 
 !!test
 3b. Indent-Pre and block tags (multi-line html)
@@ -2538,6 +2637,12 @@ a
 </pre>
  b <div> foo </div>
 
+!! html+tidy
+<pre>
+a <span>foo</span>
+</pre>
+<p>b</p>
+<div>foo</div>
 !!end
 
 !!test
@@ -2619,6 +2724,18 @@ File:foobar.jpg
                </div></li>
 </ul>
 
+!! html+tidy
+<p>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="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg" width="120" height="14" /></a></div>
+</div>
+<div class="gallerytext"></div>
+</div>
+</li>
+</ul>
 !!end
 
 !! test
@@ -3390,6 +3507,9 @@ Definition Lists: Nesting: Test 4
 ## The Parsoid team believes the following three test exposes a
 ## bug in the PHP parser.  (Parsoid team thinks the PHP parser is
 ## wrong to close the <dl> after the <dt> containing the <ul>.)
+## It also exposes a "misfeature" in tidy, which doesn't like
+## <dl> tags with a single <dt> child; it converts the <dt> into
+## a <dd> in that case.  (Parsoid leaves the <dt> alone!)
 !! test
 Definition Lists: Mixed Lists: Test 1
 !! wikitext
@@ -3401,6 +3521,22 @@ Definition Lists: Mixed Lists: Test 1
 <li> bar</li></ul></dt></dl>
 <dl><dt> baz</dt></dl></dd></dl>
 
+!! html/php+tidy
+<dl>
+<dd>
+<dl>
+<dd>
+<ul>
+<li>foo</li>
+<li>bar</li>
+</ul>
+</dd>
+</dl>
+<dl>
+<dt>baz</dt>
+</dl>
+</dd>
+</dl>
 !! html/parsoid
 <dl>
 <dd><dl>
@@ -3528,6 +3664,7 @@ Definition Lists: Mixed Lists: Test 10
 # rules regarding dd/dt on the next two tests.  Parsoid is more
 # consistent, and recognizes the shared nesting and keeps the
 # still-open tags around until the nesting is complete.
+# (And tidy again converts <dt> to <dd> before 'bar'.)
 
 !! test
 Definition Lists: Mixed Lists: Test 11
@@ -3540,6 +3677,43 @@ Definition Lists: Mixed Lists: Test 11
 <dl><dt>boo&#160;</dt>
 <dd>baz</dd></dl></li></ol></li></ul></li></ol></li></ul>
 
+!! html/php+tidy
+<ul>
+<li>
+<ol>
+<li>
+<ul>
+<li>
+<ol>
+<li>
+<dl>
+<dt>foo&#160;</dt>
+<dd>
+<ul>
+<li>
+<dl>
+<dd>
+<dl>
+<dt>bar</dt>
+</dl>
+</dd>
+</dl>
+</li>
+</ul>
+</dd>
+</dl>
+<dl>
+<dt>boo&#160;</dt>
+<dd>baz</dd>
+</dl>
+</li>
+</ol>
+</li>
+</ul>
+</li>
+</ol>
+</li>
+</ul>
 !! html/parsoid
 <ul>
 <li>
@@ -3571,6 +3745,7 @@ Definition Lists: Mixed Lists: Test 11
 !! end
 
 
+# Another case where tidy converts a <dt> to a <dd> (but Parsoid doesn't).
 !! test
 Definition Lists: Weird Ones: Test 1
 !! wikitext
@@ -3579,6 +3754,39 @@ Definition Lists: Weird Ones: Test 1
 <ul><li><ol><li><dl><dt> foo&#160;</dt>
 <dd><ul><li><dl><dd><dl><dd><dl><dt><dl><dt> bar (who uses this?)</dt></dl></dd></dl></dd></dl></dd></dl></li></ul></dd></dl></li></ol></li></ul>
 
+!! html/php+tidy
+<ul>
+<li>
+<ol>
+<li>
+<dl>
+<dt>foo&#160;</dt>
+<dd>
+<ul>
+<li>
+<dl>
+<dd>
+<dl>
+<dd>
+<dl>
+<dd>
+<dl>
+<dt>bar (who uses this?)</dt>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</li>
+</ul>
+</dd>
+</dl>
+</li>
+</ol>
+</li>
+</ul>
 !! html/parsoid
 <ul>
 <li>
@@ -3789,6 +3997,11 @@ External links: with no contents
 [[wikipedia:Foo|Bar]]
 
 [[wikipedia:Foo|<span>Bar</span>]]
+!! html/php
+<p><a rel="nofollow" class="external autonumber" href="http://en.wikipedia.org/wiki/Foo">[1]</a>
+</p><p><a href="http://en.wikipedia.org/wiki/Foo" class="extiw" title="wikipedia:Foo">Bar</a>
+</p><p><a href="http://en.wikipedia.org/wiki/Foo" class="extiw" title="wikipedia:Foo"><span>Bar</span></a>
+</p>
 !! html/parsoid
 <p><a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/Foo"></a></p>
 <p><a rel="mw:ExtLink" href="http://en.wikipedia.org/wiki/Foo">Bar</a></p>
@@ -4374,6 +4587,8 @@ External link containing double-single-quotes with no space separating the url f
 !! html/php
 <p><a rel="nofollow" class="external text" href="http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm"><i>La muerte de Casagemas</i> (1901) en el sitio de <a href="/index.php?title=Museo_Picasso_(Par%C3%ADs)&amp;action=edit&amp;redlink=1" class="new" title="Museo Picasso (París) (page does not exist)">Museo Picasso</a>.</a>
 </p>
+!! html/php+tidy
+<p><a rel="nofollow" class="external text" href="http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm"><i>La muerte de Casagemas</i> (1901) en el sitio de</a> <a href="/index.php?title=Museo_Picasso_(Par%C3%ADs)&amp;action=edit&amp;redlink=1" class="new" title="Museo Picasso (París) (page does not exist)">Museo Picasso</a>.</p>
 !! html/parsoid
 <p><a rel="mw:ExtLink" href="http://www.musee-picasso.fr/pages/page_id18528_u1l2.htm"><i>La muerte de Casagemas</i> (1901) en el sitio de </a><a rel="mw:WikiLink" href="./Museo_Picasso_(París)">Museo Picasso</a><span>.</span></p>
 !! end
@@ -4906,6 +5121,13 @@ Accept "!!" in table data
 {|
 | Foo!! ||
 |}
+!! html
+<table>
+<tr>
+<td> Foo!! </td>
+<td>
+</td></tr></table>
+
 !! html/parsoid
 <table data-parsoid='{}'>
 <tbody data-parsoid='{}'><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'> Foo!! </td><td data-parsoid='{"stx_v":"row","autoInsertedEnd":true}'></td></tr>
@@ -5286,6 +5508,14 @@ Table-cell after a comment-only-empty-line
 <!--c1-->
 <!--c2-->| b
 |}
+!! html
+<table>
+<tr>
+<td>a
+</td>
+<td> b
+</td></tr></table>
+
 !! html/parsoid
 <table>
 <tbody><tr data-parsoid='{"autoInsertedEnd":true,"autoInsertedStart":true}'><td data-parsoid='{"autoInsertedEnd":true}'>a</td>
@@ -5312,9 +5542,14 @@ Wikitext table with html-syntax row
 <td>foo</td></tr></tbody></table>
 !! end
 
+## Note that Parsoid output differs from PHP and PHP+tidy here.
+## The lack of <tr> tags in the PHP output is arguably a bug in the
+## PHP parser, which tidy then compounds by fostering the content
+## entirely out of the table.  Parsoid recognizes the table context
+## and generates <tr> and <td> wrappers as needed.  Hopefully nobody
+## depends on PHP's treatment of broken table markup!
 !! test
 Implicit <td> after a |-
-(PHP parser relies on Tidy to add the missing <td> tags)
 !! options
 parsoid=wt2html,wt2wt
 !! wikitext
@@ -5322,15 +5557,23 @@ parsoid=wt2html,wt2wt
 |-
 a
 |}
-!! html
+!! html/php
+<table>
+
+a
+</table>
+
+!! html/php+tidy
+<p>a</p>
+!! html/parsoid
 <table>
 <tr><td>a</td></tr>
 </table>
 !! end
 
+# Again, Parsoid adds implicit <td>s here, PHP and Tidy strip the b out.
 !! test
-Pres should be recognized in an explicit <td> context, but not in an implicit <td> context
-(PHP parser relies on Tidy to add the missing <td> tags)
+<pre> tags should be recognized in an explicit <td> context, but not in an implicit <td> context
 !! options
 parsoid=wt2html,wt2wt
 !! wikitext
@@ -5341,7 +5584,28 @@ parsoid=wt2html,wt2wt
 |-
  b
 |}
-!! html
+!! html/php
+<table>
+
+<tr>
+<td>
+<pre>a
+</pre>
+</td></tr>
+ b
+</table>
+
+!! html/php+tidy
+<p>b</p>
+<table>
+<tr>
+<td>
+<pre>
+a
+</pre></td>
+</tr>
+</table>
+!! html/parsoid
 <table>
 <tbody>
 <tr><td><pre>a</pre></td></tr>
@@ -5350,9 +5614,9 @@ parsoid=wt2html,wt2wt
 </table>
 !! end
 
+# PHP + Tidy strips the list out of the table; Parsoid wraps it.
 !! test
 Lists should be recognized in an implicit <td> context
-(PHP parser relies on Tidy to add the missing <td> tags)
 !! options
 parsoid=wt2html,wt2wt
 !! wikitext
@@ -5360,7 +5624,17 @@ parsoid=wt2html,wt2wt
 |-
 *a
 |}
-!! html
+!! html/php
+<table>
+
+<ul><li>a</li></ul>
+</table>
+
+!! html/php+tidy
+<ul>
+<li>a</li>
+</ul>
+!! html/parsoid
 <table>
 <tr>
 <td><ul>
@@ -5433,15 +5707,26 @@ parsoid=wt2html,wt2wt
 ! foo || bar
 <!-- foo -->  || baz || quux
 |}
+!! html/php
+<table>
+<tr>
+<th> foo </th>
+<th> bar
+</th>
+<td> baz </td>
+<td> quux
+</td></tr></table>
+
 !! html/parsoid
 <table>
-<tbody>
-<tr><th>foo </th><th>bar  </th>
-<td>baz </td>
-<td>quux</td></tr></tbody></table>
+<tbody><tr><th> foo </th><th> bar
+<!-- foo -->  </th><td> baz </td><td> quux</td></tr>
+</tbody></table>
 !! end
 
 
+# PHP throws away the (semi-broken) "foo" class here; Parsoid
+# preserves it.
 !!test
 Parsoid: Recover better from broken table attributes
 !!options
@@ -5451,6 +5736,14 @@ parsoid=wt2html
 | class="bar" |
 foo
 |}
+!!html/php+tidy
+<table>
+<tr>
+<td class="bar">
+<p>foo</p>
+</td>
+</tr>
+</table>
 !!html/parsoid
 <table class="foo">
 <tr>
@@ -6028,6 +6321,8 @@ title=[[Bug462]]
 !! html/php
 <p><strong class="selflink">Bu&#103;462</strong> <strong class="selflink">Bug462</strong>
 </p>
+!! html/php+tidy
+<p><strong class="selflink">Bug462</strong> <strong class="selflink">Bug462</strong></p>
 !! html/parsoid
 <p><a rel="mw:WikiLink" href="./Bug462">Bug462</a> <a rel="mw:WikiLink" href="./Bug462">Bug462</a></p>
 !! end
@@ -6161,6 +6456,9 @@ Purely hash wikilink
 title=[[User:test/123]]
 !! wikitext
 [[#a|b]]
+!! html/php
+<p><a href="#a">b</a>
+</p>
 !! html/parsoid
 <p data-parsoid='{}'><a rel="mw:WikiLink" href="../User:Test/123#a" data-parsoid='{"stx":"piped","a":{"href":"../User:Test/123#a"},"sa":{"href":"#a"}}'>b</a></p>
 !! end
@@ -6269,8 +6567,8 @@ Parsoid-centric test: Whitespace in ext- and wiki-links should be preserved
 
 [http://wp.org   ''foo'']
 !! html
-<p><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">  bar</a>
-</p><p><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">  <i>bar</i></a>
+<p><a href="/wiki/Foo" title="Foo">  bar</a>
+</p><p><a href="/wiki/Foo" title="Foo">  <i>bar</i></a>
 </p><p><a rel="nofollow" class="external text" href="http://wp.org">foo</a>
 </p><p><a rel="nofollow" class="external text" href="http://wp.org"><i>foo</i></a>
 </p>
@@ -6290,6 +6588,9 @@ parsoid
 Link with angle bracket after anchor
 !! wikitext
 [[Foo#<bar>]]
+!! html/php
+<p><a href="/wiki/Foo#.3Cbar.3E" title="Foo">Foo#&lt;bar&gt;</a>
+</p>
 !! html/parsoid
 <p><a rel="mw:WikiLink" href="./Foo#%3Cbar%3E" data-parsoid='{"stx":"simple","a":{"href":"./Foo#%3Cbar%3E"},"sa":{"href":"Foo#&lt;bar>"}}'>Foo#&lt;bar></a></p>
 !! end
@@ -6325,6 +6626,11 @@ Interwiki link encoding conversion (bug 1636)
 <ul><li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li>
 <li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteni&#355;a</a></li></ul>
 
+!! html+tidy
+<ul>
+<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a></li>
+<li><a href="http://en.wikipedia.org/wiki/ro:Olteni%C5%A3a" class="extiw" title="wikipedia:ro:Olteniţa">Wikipedia:ro:Olteniţa</a></li>
+</ul>
 !! end
 
 !! test
@@ -6803,6 +7109,9 @@ Broken br tag sanitization
 !! end
 
 # TODO: Fix html2html mode (bug 51055)!
+# This </br> handling was added as part of bug 50831; but it
+# differs from how PHP+tidy handles this.  We should investigate
+# this.
 !! test
 Parsoid: Broken br tag recognition
 !! options
@@ -6811,6 +7120,9 @@ parsoid=wt2html
 </br>
 
 <br/ >
+!! html/php+tidy
+<p>&lt;/br&gt;</p>
+<p><br /></p>
 !! html/parsoid
 <p><br></p>
 <p><br/></p>
@@ -6938,6 +7250,9 @@ Horizontal ruler -- Supports content following dashes on same line
 !! html
 <hr /> Foo
 
+!! html+tidy
+<hr />
+<p>Foo</p>
 !! end
 
 ###
@@ -7189,6 +7504,12 @@ Multiple list tags generated by templates
 </li>
 </li>
 
+!! html+tidy
+<ul>
+<li>a</li>
+<li>b</li>
+<li>c</li>
+</ul>
 !!end
 
 !!test
@@ -7230,7 +7551,7 @@ Replacing whitespace with tabs still doesn't break the list (gerrit 78327)
 
 !!test
 Test the li-hack
-(Cannot test this with PHP parser since it relies on Tidy for the hack)
+(The PHP parser relies on Tidy for the hack)
 !!options
 parsoid=wt2html,wt2wt
 !! wikitext
@@ -7243,19 +7564,15 @@ parsoid=wt2html,wt2wt
 <li><li>not a li-hack
 </li>
 </ul>
-!! html
+!! html+tidy
 <ul>
-<li> foo</li>
+<li>foo</li>
 <li>li-hack</li>
-<li about="#mwt1" typeof="mw:Transclusion" data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"<li>templated li-hack"}}}}]}'>templated li-hack</li>
-<li> <!--foo--> </li>
-<li> li-hack with preceding comments</li>
+<li>templated li-hack</li>
+<li>unsupported li-hack with preceding comments</li>
 </ul>
-
 <ul>
-<li></li>
-<li>not a li-hack
-</li>
+<li>not a li-hack</li>
 </ul>
 !!end
 
@@ -7305,47 +7622,60 @@ parsoid
 
 !! test
 Unbalanced closing block tags break a list
-(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up)
+(php parser relies on Tidy to fix up)
 !! wikitext
 <div>
 *a</div><div>
 *b</div>
-!! html/parsoid
+!! html+tidy
 <div>
 <ul>
-<li>a
-</li>
-</ul></div><div>
+<li>a</li>
+</ul>
+</div>
+<div>
 <ul>
-<li>b
-</li>
-</ul></div>
+<li>b</li>
+</ul>
+</div>
 !! end
 
+# Parsoid fails this test, but it might be tricky to support properly.
+# See bug 68395.
 !! test
 Unbalanced closing non-block tags don't break a list
-(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up)
+(php parser relies on Tidy to fix up)
 !! wikitext
 <span>
 *a</span><span>
 *b</span>
+!! html/php+tidy
+<ul>
+<li><span>a</span></li>
+<li><span>b</span></li>
+</ul>
 !! html/parsoid
-<p><span></span>
-</p>
+<span>
 <ul>
 <li>a<span></span>
 </li>
 <li>b
 </li>
 </ul>
+</span>
 !! end
 
 !! test
 Unclosed formatting tags that straddle lists are closed and reopened
-(Parsoid-only since php parser generates broken html -- relies on Tidy to fix up)
+(php parser relies on Tidy to fix up)
 !! wikitext
 # <s> a
 # b </s>
+!! html/php+tidy
+<ol>
+<li><s>a</s></li>
+<li><s>b</s></li>
+</ol>
 !! html/parsoid
 <ol>
 <li> <s> a </s>
@@ -7355,23 +7685,31 @@ Unclosed formatting tags that straddle lists are closed and reopened
 </ol>
 !! end
 
+# Parsoid fails this test, but it might be tricky to support properly.
+# See bug 68395.
 !!test
 List embedded in a non-block tag
-(Ugly Parsoid output -- worth fixing; Disabled for PHP parser since it relies on Tidy)
+(Ugly Parsoid output -- worth fixing; PHP parser relies on Tidy)
 !! wikitext
 <small>
 * foo
 </small>
+!! html/php+tidy
+<ul>
+<li><small>foo</small></li>
+</ul>
 !! html/parsoid
-<p><small></small></p>
 <small>
 <ul>
 <li> foo</li>
 </ul>
 </small>
-<p><small></small></p>
 !!end
 
+# This is a bug in the PHP parser + tidy combination.
+# (The </tr> tag gets parsed as text and html-escaped by PHP,
+# and then fostered out of the table by tidy.)
+# We believe the Parsoid output to be correct.
 !! test
 Table with missing opening <tr> tag
 !! options
@@ -7381,6 +7719,13 @@ parsoid=wt2html,wt2wt
 <td>foo</td>
 </tr>
 </table>
+!! html/php+tidy
+<p>&lt;/tr&gt;</p>
+<table>
+<tr>
+<td>foo</td>
+</tr>
+</table>
 !! html/parsoid
 <table>
 <tr>
@@ -7837,9 +8182,11 @@ Magic Word: {{PAGENAME}} with metacharacters
 title=[['foo & bar = baz']]
 !! wikitext
 ''{{PAGENAME}}''
-!! html
+!! html/php
 <p><i>&#39;foo &#38; bar &#61; baz&#39;</i>
 </p>
+!! html+tidy
+<p><i>'foo &amp; bar = baz'</i></p>
 !! end
 
 !! test
@@ -7848,9 +8195,11 @@ Magic Word: {{PAGENAME}} with metacharacters (bug 26781)
 title=[[*RFC 1234 http://example.com/]]
 !! wikitext
 {{PAGENAME}}
-!! html
+!! html/php
 <p>&#42;RFC&#32;1234 http&#58;//example.com/
 </p>
+!! html+tidy
+<p>*RFC 1234 http://example.com/</p>
 !! end
 
 !! test
@@ -7870,9 +8219,11 @@ Magic Word: {{PAGENAMEE}} with metacharacters (bug 26781)
 title=[[*RFC 1234 http://example.com/]]
 !! wikitext
 {{PAGENAMEE}}
-!! html
+!! html/php
 <p>&#42;RFC_1234_http&#58;//example.com/
 </p>
+!! html+tidy
+<p>*RFC_1234_http://example.com/</p>
 !! end
 
 !! test
@@ -8376,9 +8727,16 @@ Template with thumb image (with link in description)
 !! wikitext
 {{paramtest|
   param =[[Image:noimage.png|thumb|[[no link|link]] [[no link|caption]]]]}}
-!! html
+!! html/php
 This is a test template with parameter <div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&amp;wpDestFile=Noimage.png" class="new" title="File:Noimage.png">File:Noimage.png</a>  <div class="thumbcaption"><a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">caption</a></div></div></div>
 
+!! html+tidy
+<p>This is a test template with parameter</p>
+<div class="thumb tright">
+<div class="thumbinner" style="width:182px;"><a href="/index.php?title=Special:Upload&amp;wpDestFile=Noimage.png" class="new" title="File:Noimage.png">File:Noimage.png</a>
+<div class="thumbcaption"><a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">link</a> <a href="/index.php?title=No_link&amp;action=edit&amp;redlink=1" class="new" title="No link (page does not exist)">caption</a></div>
+</div>
+</div>
 !! end
 
 !! article
@@ -8580,8 +8938,8 @@ Template with targets containing wikilinks
 
 {{{{echo|[[foo}}]]}}
 !! html
-<p>{{<a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">foo</a>}}
-</p><p>{{<a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">foo</a>}}
+<p>{{<a href="/wiki/Foo" title="Foo">foo</a>}}
+</p><p>{{<a href="/wiki/Foo" title="Foo">foo</a>}}
 </p><p>{{[[foo}}]]
 </p>
 !! end
@@ -9071,6 +9429,11 @@ Templates: 2. Inside a block tag
 <div>Foo</div>
 <blockquote>Foo</blockquote>
 
+!! html+tidy
+<div>Foo</div>
+<blockquote>
+<p>Foo</p>
+</blockquote>
 !!end
 
 !!test
@@ -9108,7 +9471,11 @@ Templates: P-wrapping: 1c. Templates on consecutive lines
 </p>
 bar <div>baz</div>
 
-!!end
+!! html+tidy
+<p>Foo</p>
+<p>bar</p>
+<div>baz</div>
+!! end
 
 !!test
 Templates: P-wrapping: 1d. Template preceded by comment-only line
@@ -9164,7 +9531,7 @@ Templates: Links: 1. Simple example
 !! wikitext
 {{echo|[[Foo|bar]]}}
 !! html
-<p><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">bar</a>
+<p><a href="/wiki/Foo" title="Foo">bar</a>
 </p>
 !!end
 
@@ -9173,7 +9540,7 @@ Templates: Links: 2. Generation of link href
 !! wikitext
 [[{{echo|Foo}}|bar]]
 !! html
-<p><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">bar</a>
+<p><a href="/wiki/Foo" title="Foo">bar</a>
 </p>
 !!end
 
@@ -9192,7 +9559,7 @@ Templates: Links: 3. Generation of part of a link href
 
 [[:Foo{{echo|bar}}|bar]]
 !! html
-<p><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">bar</a>
+<p><a href="/wiki/Foo" title="Foo">bar</a>
 </p><p><a href="/index.php?title=Foobar&amp;action=edit&amp;redlink=1" class="new" title="Foobar (page does not exist)">Foobar</a>
 </p><p><a href="/index.php?title=Foobarbaz&amp;action=edit&amp;redlink=1" class="new" title="Foobarbaz (page does not exist)">Foobarbaz</a>
 </p><p><a href="/index.php?title=Foobar&amp;action=edit&amp;redlink=1" class="new" title="Foobar (page does not exist)">bar</a>
@@ -9215,7 +9582,7 @@ Templates: Links: 5. Generation of link text
 !! wikitext
 [[Foo|{{echo|bar}}]]
 !! html
-<p><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">bar</a>
+<p><a href="/wiki/Foo" title="Foo">bar</a>
 </p>
 !!end
 
@@ -9224,7 +9591,7 @@ Templates: Links: 5. Nested templates (only outermost template should be marked)
 !! wikitext
 {{echo|[[{{echo|Foo}}|bar]]}}
 !! html
-<p><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">bar</a>
+<p><a href="/wiki/Foo" title="Foo">bar</a>
 </p>
 !!end
 
@@ -9406,7 +9773,14 @@ Templates: Wiki Tables: 1a. Fostering of entire template content
 a
 <tr><td></td></tr></table>
 
-!!end
+!! html+tidy
+<p>a</p>
+<table>
+<tr>
+<td></td>
+</tr>
+</table>
+!! end
 
 !!test
 Templates: Wiki Tables: 1b. Fostering of entire template content
@@ -9424,7 +9798,16 @@ foo
 </div>
 <tr><td></td></tr></table>
 
-!!end
+!! html+tidy
+<div>
+<p>foo</p>
+</div>
+<table>
+<tr>
+<td></td>
+</tr>
+</table>
+!! end
 
 !!test
 Templates: Wiki Tables: 2. Fostering of partial template content
@@ -9439,7 +9822,15 @@ a
 <div>b</div>
 <tr><td></td></tr></table>
 
-!!end
+!! html+tidy
+<p>a</p>
+<div>b</div>
+<table>
+<tr>
+<td></td>
+</tr>
+</table>
+!! end
 
 !!test
 Templates: Wiki Tables: 3. td-content via multiple templates
@@ -9545,7 +9936,11 @@ a<div>b{{echo|c</div>d}}e
 !! html
 a<div>bc</div>de
 
-!!end
+!! html+tidy
+<p>a</p>
+<div>bc</div>
+<p>de</p>
+!! end
 
 !!test
 Templates: Ugly templates: 1. Navbox template parses badly leading to table misnesting
@@ -10535,6 +10930,7 @@ Image with multiple attributes from the same template
 <figure class="mw-default-size mw-halign-right" typeof="mw:Image mw:Placeholder"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a><figcaption>Caption text</figcaption></figure>
 !! end
 
+# Parsoid's output here is broken (incorrect p-wrapping); see bug 64901.
 !! test
 Image with link tails
 !! options
@@ -10549,6 +10945,19 @@ thumbsize=220
 123<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div>456
 123<div class="thumb tright"><div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>  <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div></div></div></div>456
 
+!! html/php+tidy
+<p>123<a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a>456</p>
+<p>123</p>
+<div class="floatright"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/3/3a/Foobar.jpg" width="1941" height="220" /></a></div>
+<p>456 123</p>
+<div class="thumb tright">
+<div class="thumbinner" style="width:222px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="Foobar.jpg" src="http://example.com/images/thumb/3/3a/Foobar.jpg/220px-Foobar.jpg" width="220" height="25" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/330px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/440px-Foobar.jpg 2x" /></a>
+<div class="thumbcaption">
+<div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div>
+</div>
+</div>
+</div>
+<p>456</p>
 !! html/parsoid
 <p>123<span class="mw-default-size" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></span>456</p>
 123<figure class="mw-default-size mw-halign-right" typeof="mw:Image"><a href="File:Foobar.jpg"><img resource="./File:Foobar.jpg" src="//example.com/images/3/3a/Foobar.jpg" height="220" width="1941"></a></figure>456
@@ -12761,6 +13170,8 @@ I always thought &eacute; was a cute letter.
 !! html
 <p>I always thought &#233; was a cute letter.
 </p>
+!! html+tidy
+<p>I always thought é was a cute letter.</p>
 !! end
 
 !! test
@@ -12822,6 +13233,7 @@ Ensure that HTML adoption agency algorithm is properly implemented.
 !! end
 
 # This was bug 41545 in the PHP parser.
+# Note that tidy doesn't handle this correctly.
 !! test
 Nesting of <kbd>
 !! wikitext
@@ -12834,6 +13246,8 @@ Nesting of <kbd>
 # The following cases were bug 51081 in the PHP parser.
 # Note that there are some other nestable tags (b, i, etc) which are
 # not covered; see bug 51081 for discussion.
+
+# Note that tidy doesn't handle this correctly.
 !! test
 Nesting of <em>
 !! wikitext
@@ -12843,6 +13257,7 @@ Nesting of <em>
 </p>
 !! end
 
+# Note that tidy doesn't handle this correctly.
 !! test
 Nesting of <strong>
 !! wikitext
@@ -12856,11 +13271,11 @@ Nesting of <strong>
 Nesting of <q>
 !! wikitext
 <q>X<q>Y</q>Z</q>
-!! html
-<p><q>X<q>Y</q>Z</q>
-</p>
+!! html+tidy
+<p><q>X<q>Y</q>Z</q></p>
 !! end
 
+# Note that tidy doesn't handle this correctly.
 !! test
 Nesting of <ruby>
 !! wikitext
@@ -12870,6 +13285,7 @@ Nesting of <ruby>
 </p>
 !! end
 
+# Note that tidy doesn't handle this correctly.
 !! test
 Nesting of <bdo>
 !! wikitext
@@ -12911,6 +13327,8 @@ fixme: doBlockLevels won't wrap this in a paragraph because it contains a div
 !! html
 <a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link&lt;div style="display:none"&gt;" onmouseover="alert(document.cookie)" onfoo="&lt;/div&gt;</a>
 
+!! html+tidy
+<p><a href="http://example.com/images/3/3a/Foobar.jpg" class="internal" title="Foobar.jpg">Safe Link&lt;div style="display:none"&gt;" onmouseover="alert(document.cookie)" onfoo="&lt;/div&gt;</a></p>
 !! end
 
 !! test
@@ -14056,6 +14474,17 @@ http://<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
 </div>
 
 
+!! html+tidy
+<h2><span class="mw-headline" id="onmouseover.3D">onmouseover=</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: onmouseover=">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<p>http://</p>
+<div id="toc" class="toc">
+<div id="toctitle">
+<h2>Contents</h2>
+</div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#onmouseover.3D"><span class="tocnumber">1</span> <span class="toctext">onmouseover=</span></a></li>
+</ul>
+</div>
 !! end
 
 !! test
@@ -14069,6 +14498,13 @@ Fuzz testing: Parser14-table
 <tr><td></td></tr>
 </table>
 
+!! html+tidy
+<h2><span class="mw-headline" id="a">a</span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: a">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<table style="__TOC__">
+<tr>
+<td></td>
+</tr>
+</table>
 !! end
 
 # Known to produce bogus xml (extra </td>)
@@ -14090,6 +14526,15 @@ noxml
 </tr>
 </table>
 
+!! html+tidy
+<table>
+<tr>
+<th>https://</th>
+<th></th>
+<th></th>
+<th></th>
+</tr>
+</table>
 !! end
 
 !! test
@@ -14177,7 +14622,6 @@ Fuzz testing: Parser25 (bug 6055)
 
 !!test
 Fuzz testing: URL adjacent extension (with space, clean)
-!! options
 !! wikitext
 http://example.com <nowiki>junk</nowiki>
 !! html
@@ -14187,7 +14631,6 @@ http://example.com <nowiki>junk</nowiki>
 
 !!test
 Fuzz testing: URL adjacent extension (no space, dirty; nowiki)
-!! options
 !! wikitext
 http://example.com<nowiki>junk</nowiki>
 !! html
@@ -14197,12 +14640,16 @@ http://example.com<nowiki>junk</nowiki>
 
 !!test
 Fuzz testing: URL adjacent extension (no space, dirty; pre)
-!! options
 !! wikitext
 http://example.com<pre>junk</pre>
 !! html
 <a rel="nofollow" class="external free" href="http://example.com">http://example.com</a><pre>junk</pre>
 
+!! html+tidy
+<p><a rel="nofollow" class="external free" href="http://example.com">http://example.com</a></p>
+<pre>
+junk
+</pre>
 !!end
 
 !!test
@@ -15595,6 +16042,8 @@ parsoid=wt2html,wt2wt,html2html
 !! html/php
 <p>&#x4a;&#x61;&#x76;&#x61;&#x53;&#x63;&#114;&#x69;&#112;&#x74;
 </p>
+!! html/php+tidy
+<p>JavaScript</p>
 !! html/parsoid
 <p><span typeof="mw:Entity">J</span><span typeof="mw:Entity">a</span><span typeof="mw:Entity">v</span><span typeof="mw:Entity">a</span><span typeof="mw:Entity">S</span><span typeof="mw:Entity">c</span><span typeof="mw:Entity">r</span><span typeof="mw:Entity">i</span><span typeof="mw:Entity">p</span><span typeof="mw:Entity">t</span></p>
 !! end
@@ -15619,6 +16068,8 @@ parsoid=wt2html,wt2wt,html2html
 !! html/php
 <p>&#xee;&#xee;
 </p>
+!! html/php+tidy
+<p>îî</p>
 !! html/parsoid
 <p><span typeof="mw:Entity">î</span><span typeof="mw:Entity">î</span></p>
 !! end
@@ -15640,6 +16091,8 @@ ISBN  978-0-1234-56&#x20;789
 !! html
 <p><a href="/wiki/Special:BookSources/9780123456" class="internal mw-magiclink-isbn">ISBN 978-0-1234-56</a>&#x20;789
 </p>
+!! html+tidy
+<p><a href="/wiki/Special:BookSources/9780123456" class="internal mw-magiclink-isbn">ISBN 978-0-1234-56</a> 789</p>
 !! end
 
 !! test
@@ -15711,6 +16164,8 @@ RFC   983&#x20;987
 !! html
 <p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc983">RFC 983</a>&#x20;987
 </p>
+!! html+tidy
+<p><a class="external mw-magiclink-rfc" rel="nofollow" href="//tools.ietf.org/html/rfc983">RFC 983</a> 987</p>
 !! end
 
 !! test
@@ -16928,6 +17383,10 @@ Line two</blockquote>
 <blockquote>Line one
 Line two</blockquote>
 
+!! html+tidy
+<blockquote>
+<p>Line one Line two</p>
+</blockquote>
 !! end
 
 !! test
@@ -16943,6 +17402,10 @@ Line two</blockquote>
 </p>
 Line two</blockquote>
 
+!! html+tidy
+<blockquote>
+<p>Line one</p>
+Line two</blockquote>
 !! end
 
 !! test
@@ -16958,6 +17421,11 @@ Line two
 </p>
 </blockquote>
 
+!! html+tidy
+<blockquote>
+<p>Line one</p>
+<p>Line two</p>
+</blockquote>
 !! end
 
 !! test
@@ -16975,6 +17443,11 @@ Line two
 </p>
 </blockquote>
 
+!! html+tidy
+<blockquote>
+<p>Line one</p>
+<p>Line two</p>
+</blockquote>
 !! end
 
 !! test
@@ -17735,6 +18208,20 @@ __TOC__
 
 <h2><span class="mw-headline" id="Quote"><blockquote>Quote</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 
+!! html+tidy
+<div id="toc" class="toc">
+<div id="toctitle">
+<h2>Contents</h2>
+</div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#Quote"><span class="tocnumber">1</span> <span class="toctext">Quote</span></a></li>
+</ul>
+</div>
+<h2><span class="mw-headline" id="Quote"></span></h2>
+<blockquote>
+<p><span class="mw-headline" id="Quote">Quote</span></p>
+</blockquote>
+<p><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Main_Page&amp;action=edit&amp;section=1" title="Edit section: Quote">edit</a><span class="mw-editsection-bracket">]</span></span></p>
 !! end
 
 !! test
@@ -17777,6 +18264,22 @@ __TOC__
 <h2><span class="mw-headline" id="Foo_Bar"><i>Foo</i> <b>Bar</b></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 <h2><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i> <blockquote>Bar</blockquote></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 
+!! html+tidy
+<div id="toc" class="toc">
+<div id="toctitle">
+<h2>Contents</h2>
+</div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#Foo_Bar"><span class="tocnumber">1</span> <span class="toctext"><i>Foo</i> <b>Bar</b></span></a></li>
+<li class="toclevel-1 tocsection-2"><a href="#Foo_Bar_2"><span class="tocnumber">2</span> <span class="toctext"><i>Foo</i> Bar</span></a></li>
+</ul>
+</div>
+<h2><span class="mw-headline" id="Foo_Bar"><i>Foo</i> <b>Bar</b></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="Foo_Bar_2"><i>Foo</i></span></h2>
+<blockquote>
+<p><span class="mw-headline" id="Foo_Bar_2">Bar</span></p>
+</blockquote>
+<p><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=2" title="Edit section: Foo Bar">edit</a><span class="mw-editsection-bracket">]</span></span></p>
 !! end
 
 !! test
@@ -17959,7 +18462,7 @@ nowiki inside link inside heading (bug 18295)
 !! wikitext
 ==[[foo|x<nowiki>y</nowiki>z]]==
 !! html
-<h2><span class="mw-headline" id="xyz"><a href="/index.php?title=Foo&amp;action=edit&amp;redlink=1" class="new" title="Foo (page does not exist)">xyz</a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: xyz">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+<h2><span class="mw-headline" id="xyz"><a href="/wiki/Foo" title="Foo">xyz</a></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: xyz">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
 
 !! end
 
@@ -20159,6 +20662,13 @@ Indented block & table
  {|
  |foo
  |}
+!! html/php
+ <div>foo</div>
+<table>
+<tr>
+<td>foo
+</td></tr></table>
+
 !! html/parsoid
  <div data-parsoid='{"stx":"html"}'>foo</div>
  <table><tbody>
@@ -20173,6 +20683,13 @@ Indent and comment before table row
  <!--hi-->|-
  | there
 |}
+!! html/php
+<table>
+
+<tr>
+<td> there
+</td></tr></table>
+
 !! html/parsoid
 <table data-parsoid='{}'>
  <!--hi--><tbody data-parsoid='{}'><tr data-parsoid='{"startTagSrc":"|-","autoInsertedEnd":true}'>
index 0272c54..3c255b5 100644 (file)
@@ -22,7 +22,7 @@ class ImagePageTest extends MediaWikiMediaTestCase {
 
        /**
         * @dataProvider providerGetDisplayWidthHeight
-        * @param array $dimensions Array [maxWidth, maxHeight, width, height]
+        * @param array $dim Array [maxWidth, maxHeight, width, height]
         * @param array $expected Array [width, height] The width and height we expect to display at
         */
        function testGetDisplayWidthHeight( $dim, $expected ) {
index 1ac9b9d..19c0a7d 100644 (file)
@@ -39,8 +39,8 @@ class ApiModuleManagerTest extends MediaWikiTestCase {
                                'logout',
                                'action',
                                'ApiLogout',
-                               function( ApiMain $main, $action ) {
-                                               return new ApiLogout( $main, $action );
+                               function ( ApiMain $main, $action ) {
+                                       return new ApiLogout( $main, $action );
                                },
                        ),
                );
@@ -80,7 +80,7 @@ class ApiModuleManagerTest extends MediaWikiTestCase {
                                        ),
                                        'logout' => array(
                                                'class' => 'ApiLogout',
-                                               'factory' => function( ApiMain $main, $action ) {
+                                               'factory' => function ( ApiMain $main, $action ) {
                                                        return new ApiLogout( $main, $action );
                                                },
                                        ),
@@ -113,9 +113,9 @@ class ApiModuleManagerTest extends MediaWikiTestCase {
                        ),
                        'logout' => array(
                                'class' => 'ApiLogout',
-                               'factory' => function( ApiMain $main, $action ) {
-                                               return new ApiLogout( $main, $action );
-                                       },
+                               'factory' => function ( ApiMain $main, $action ) {
+                                       return new ApiLogout( $main, $action );
+                               },
                        ),
                );
 
index b556ef8..f633315 100644 (file)
@@ -133,7 +133,7 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
                        $session = $wgRequest->getSessionArray();
                }
 
-               if ( $session['wsToken'] ) {
+               if ( isset( $session['wsToken'] ) && $session['wsToken'] ) {
                        // add edit token to fake session
                        $session['wsEditToken'] = $session['wsToken'];
                        // add token to request parameters
@@ -141,7 +141,7 @@ abstract class ApiTestCase extends MediaWikiLangTestCase {
 
                        return $this->doApiRequest( $params, $session, false, $user );
                } else {
-                       throw new Exception( "request data not in right format" );
+                       throw new Exception( "Session token not available" );
                }
        }
 
index 6f4479b..d986e69 100644 (file)
@@ -37,7 +37,7 @@ abstract class ApiQueryContinueTestBase extends ApiQueryTestBase {
         * @param array $params Api parameters
         * @param int $expectedCount Max number of iterations
         * @param string $id Unit test id
-        * @param bool $useContinue True to use smart continue
+        * @param bool $continue True to use smart continue
         * @return Merged results data array
         */
        protected function checkC( $expected, $params, $expectedCount, $id, $continue = true ) {
index 7b686a3..bba22c7 100644 (file)
@@ -96,7 +96,7 @@ class ApiQueryTest extends ApiTestCase {
         * @param string $titlePart
         * @param int $namespace
         * @param string $expected
-        * @param string $description
+        * @param string $expectException
         * @dataProvider provideTestTitlePartToKey
         */
        function testTitlePartToKey( $titlePart, $namespace, $expected, $expectException ) {
index ec74574..acfdc0e 100644 (file)
@@ -27,7 +27,7 @@ class JSONContentTest extends MediaWikiLangTestCase {
         * @dataProvider provideDataToEncode
         */
        public function testBeautifyUsesFormatJson( $data ) {
-               $obj = new JSONContent( FormatJson::encode( $data) );
+               $obj = new JSONContent( FormatJson::encode( $data ) );
                $this->assertEquals( FormatJson::encode( $data, true ), $obj->beautifyJSON() );
        }
 
@@ -46,7 +46,7 @@ class JSONContentTest extends MediaWikiLangTestCase {
         */
        public function testPreSaveTransform( $data ) {
                $obj = new JSONContent( FormatJson::encode( $data ) );
-               $newObj = $obj->preSaveTransform( $this->getMockTitle(), $this->getMockUser() , $this->getMockParserOptions() );
+               $newObj = $obj->preSaveTransform( $this->getMockTitle(), $this->getMockUser(), $this->getMockParserOptions() );
                $this->assertTrue( $newObj->equals( new JSONContent( FormatJson::encode( $data, true ) ) ) );
        }
 
@@ -112,5 +112,4 @@ class JSONContentTest extends MediaWikiLangTestCase {
                        ),
                );
        }
-
-}
\ No newline at end of file
+}
index 9b6391c..5b2de15 100644 (file)
@@ -17,7 +17,7 @@ class XCFHandlerTest extends MediaWikiMediaTestCase {
        /**
         * @param string $filename
         * @param int $expectedWidth Width
-        * @param int $expectedHeigh Height
+        * @param int $expectedHeight Height
         * @dataProvider provideGetImageSize
         * @covers XCFHandler::getImageSize
         */
index 0499f88..4e8c11f 100644 (file)
@@ -36,6 +36,10 @@ class NewParserTest extends MediaWikiTestCase {
         * @var DjVuSupport
         */
        private $djVuSupport;
+       /**
+        * @var TidySupport
+        */
+       private $tidySupport;
 
        protected $file = false;
 
@@ -75,6 +79,7 @@ class NewParserTest extends MediaWikiTestCase {
                $tmpGlobals['wgExtensionAssetsPath'] = '/extensions';
                $tmpGlobals['wgStylePath'] = '/skins';
                $tmpGlobals['wgEnableUploads'] = true;
+               $tmpGlobals['wgUploadNavigationUrl'] = false;
                $tmpGlobals['wgThumbnailScriptPath'] = false;
                $tmpGlobals['wgLocalFileRepo'] = array(
                        'class' => 'LocalRepo',
@@ -95,8 +100,6 @@ class NewParserTest extends MediaWikiTestCase {
                $tmpGlobals['wgUseImageResize'] = true;
                $tmpGlobals['wgAllowExternalImages'] = true;
                $tmpGlobals['wgRawHtml'] = false;
-               $tmpGlobals['wgUseTidy'] = false;
-               $tmpGlobals['wgAlwaysUseTidy'] = false;
                $tmpGlobals['wgWellFormedXml'] = true;
                $tmpGlobals['wgAllowMicrodataAttributes'] = true;
                $tmpGlobals['wgExperimentalHtmlIds'] = false;
@@ -153,8 +156,19 @@ class NewParserTest extends MediaWikiTestCase {
                # see https://gerrit.wikimedia.org/r/111390
                $tmpGlobals['wgExtraInterlanguageLinkPrefixes'] = array( 'mul' );
 
-               //DjVu support
+               // DjVu support
                $this->djVuSupport = new DjVuSupport();
+               // Tidy support
+               $this->tidySupport = new TidySupport();
+               // We always set 'wgUseTidy' to false when parsing, but certain
+               // test-running modes still use tidy if available, so ensure
+               // that the tidy-related options are all set to their defaults.
+               $tmpGlobals['wgUseTidy'] = false;
+               $tmpGlobals['wgAlwaysUseTidy'] = false;
+               $tmpGlobals['wgDebugTidy'] = false;
+               $tmpGlobals['wgTidyConf'] = $IP . '/includes/tidy.conf';
+               $tmpGlobals['wgTidyOpts'] = '';
+               $tmpGlobals['wgTidyInternal'] = $this->tidySupport->isInternal();
 
                $this->setMwGlobals( $tmpGlobals );
 
@@ -735,6 +749,14 @@ class NewParserTest extends MediaWikiTestCase {
                        $output = $parser->parse( $input, $title, $options, true, true, 1337 );
                        $output->setTOCEnabled( !isset( $opts['notoc'] ) );
                        $out = $output->getText();
+                       if ( isset( $opts['tidy'] ) ) {
+                               if ( !$this->tidySupport->isEnabled() ) {
+                                       $this->markTestSkipped( "SKIPPED: tidy extension is not installed.\n" );
+                               } else {
+                                       $out = MWTidy::tidy( $out );
+                                       $out = preg_replace( '/\s+$/', '', $out);
+                               }
+                       }
 
                        if ( isset( $opts['showtitle'] ) ) {
                                if ( $output->getTitleText() ) {
@@ -745,21 +767,19 @@ class NewParserTest extends MediaWikiTestCase {
                        }
 
                        if ( isset( $opts['ill'] ) ) {
-                               $out = $this->tidy( implode( ' ', $output->getLanguageLinks() ) );
+                               $out = implode( ' ', $output->getLanguageLinks() );
                        } elseif ( isset( $opts['cat'] ) ) {
                                $outputPage = $context->getOutput();
                                $outputPage->addCategoryLinks( $output->getCategories() );
                                $cats = $outputPage->getCategoryLinks();
 
                                if ( isset( $cats['normal'] ) ) {
-                                       $out = $this->tidy( implode( ' ', $cats['normal'] ) );
+                                       $out = implode( ' ', $cats['normal'] );
                                } else {
                                        $out = '';
                                }
                        }
                        $parser->mPreprocessor = null;
-
-                       $result = $this->tidy( $result );
                }
 
                $this->teardownGlobals();
@@ -963,23 +983,6 @@ class NewParserTest extends MediaWikiTestCase {
 
        //Various "cleanup" functions
 
-       /**
-        * Run the "tidy" command on text if the $wgUseTidy
-        * global is true
-        *
-        * @param string $text The text to tidy
-        * @return string
-        */
-       protected function tidy( $text ) {
-               global $wgUseTidy;
-
-               if ( $wgUseTidy ) {
-                       $text = MWTidy::tidy( $text );
-               }
-
-               return $text;
-       }
-
        /**
         * Remove last character if it is a newline
         * @param string $s
index e98f0e8..038a0e1 100644 (file)
@@ -5,9 +5,9 @@ class ResourceLoaderModuleTest extends ResourceLoaderTestCase {
        protected function setUp() {
                parent::setUp();
 
-               $this->setMwGlobals( array(
-                       'wgValidSkinNames' => array( 'vector' => 'Vector' ),
-               );
+               // The return value of the closure shouldn't matter since this test should
+               // never call it
+               SkinFactory::getDefaultInstance()->register( 'vector', 'Vector', function(){});
        }
 
        /**
index 4497cba..7b7c7f8 100644 (file)
@@ -7,7 +7,7 @@ class SkinFactoryTest extends MediaWikiTestCase {
         */
        public function testRegister() {
                $factory = new SkinFactory();
-               $factory->register( 'fallback', 'Fallback', function() {
+               $factory->register( 'fallback', 'Fallback', function () {
                        return new SkinFallback();
                } );
                $this->assertTrue( true ); // No exception thrown
index dad30b7..45d5ea8 100644 (file)
@@ -30,7 +30,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         *
         * @param Page $page Page to add the revision to
         * @param string $text Revisions text
-        * @param string $text Revisions summare
+        * @param string $summary Revisions summare
         *
         * @throws MWException
         */
@@ -181,7 +181,7 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         * Asserts that the xml reader is at the final closing tag of an xml file and
         * closes the reader.
         *
-        * @param string $tag (optional) the name of the final tag
+        * @param string $name (optional) the name of the final tag
         *   (e.g.: "mediawiki" for </mediawiki>)
         */
        protected function assertDumpEnd( $name = "mediawiki" ) {
@@ -304,9 +304,9 @@ abstract class DumpTestCase extends MediaWikiLangTestCase {
         * @param string $text_sha1 The base36 SHA-1 of the revision's text
         * @param string|bool $text (optional) The revision's string, or false to check for a
         *            revision stub
+        * @param int|bool $parentid (optional) id of the parent revision
         * @param string $model The expected content model id (default: CONTENT_MODEL_WIKITEXT)
         * @param string $format The expected format model id (default: CONTENT_FORMAT_WIKITEXT)
-        * @param int|bool $parentid (optional) id of the parent revision
         */
        protected function assertRevision( $id, $summary, $text_id, $text_bytes,
                $text_sha1, $text = false, $parentid = false,
index 1ad4656..b2141d3 100644 (file)
@@ -100,7 +100,7 @@ class FetchTextTest extends MediaWikiTestCase {
         *
         * @param WikiPage $page The page to add the revision to
         * @param string $text The revisions text
-        * @param string $text The revisions summare
+        * @param string $summary The revisions summare
         *
         * @throws MWException
         */
index 2fd3ce9..92dad9f 100644 (file)
                );
                $table.tablesorter();
                assert.equal( $table.find( '#A2' ).prop( 'headerIndex' ),
-                       0,
+                       undefined,
                        'A2 should not be a sort header'
                );
                assert.equal( $table.find( '#C1' ).prop( 'headerIndex' ),
-                       1,
-                       'C1 should be a sort header, but will sort the wrong column'
+                       2,
+                       'C1 should be a sort header'
+               );
+       } );
+
+       // bug 53527
+       QUnit.test( 'td cells in thead should not be taken into account for longest row calculation', 2, function ( assert ) {
+               var $table = $(
+                       '<table class="sortable">' +
+                               '<thead>' +
+                               '<tr><th id="A1">A1</th><th>B1</th><td id="C1">C1</td></tr>' +
+                               '<tr><th id="A2">A2</th><th>B2</th><th id="C2">C2</th></tr>' +
+                               '</thead>' +
+                               '</table>'
+               );
+               $table.tablesorter();
+               assert.equal( $table.find( '#C2' ).prop( 'headerIndex' ),
+                       2,
+                       'C2 should be a sort header'
+               );
+               assert.equal( $table.find( '#C1' ).prop( 'headerIndex' ),
+                       undefined,
+                       'C1 should not be a sort header'
                );
        } );
 
index 717c5f3..6d94435 100644 (file)
@@ -364,6 +364,10 @@ class TestFileIterator implements Iterator {
        private $sectionData = array();
        private $lineNum;
        private $eof;
+       # Create a fake parser tests which never run anything unless
+       # asked to do so. This will avoid running hooks for a disabled test
+       private $delayedParserTest;
+       private $nextSubTest = 0;
 
        function __construct( $file, $parserTest ) {
                $this->file = $file;
@@ -374,6 +378,7 @@ class TestFileIterator implements Iterator {
                }
 
                $this->parserTest = $parserTest;
+               $this->delayedParserTest = new DelayedParserTest();
 
                $this->lineNum = $this->index = 0;
        }
@@ -412,12 +417,71 @@ class TestFileIterator implements Iterator {
                return $this->eof != true;
        }
 
+       function setupCurrentTest() {
+               // "input" and "result" are old section names allowed
+               // for backwards-compatibility.
+               $input = $this->checkSection( array( 'wikitext', 'input' ), false );
+               $result = $this->checkSection( array( 'html/php', 'html/*', 'html', 'result' ), false );
+               // some tests have "with tidy" and "without tidy" variants
+               $tidy = $this->checkSection( array( 'html/php+tidy', 'html+tidy'), false );
+               if ( $tidy != false ) {
+                       if ( $this->nextSubTest == 0 ) {
+                               if ( $result != false ) {
+                                       $this->nextSubTest = 1; // rerun non-tidy variant later
+                               }
+                               $result = $tidy;
+                       } else {
+                               $this->nextSubTest = 0; // go on to next test after this
+                               $tidy = false;
+                       }
+               }
+
+               if ( !isset( $this->sectionData['options'] ) ) {
+                       $this->sectionData['options'] = '';
+               }
+
+               if ( !isset( $this->sectionData['config'] ) ) {
+                       $this->sectionData['config'] = '';
+               }
+
+               $isDisabled = preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] ) && !$this->parserTest->runDisabled;
+               $isParsoidOnly = preg_match( '/\\bparsoid\\b/i', $this->sectionData['options'] ) && $result == 'html' && !$this->parserTest->runParsoid;
+               $isFiltered = !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] );
+               if ( $input == false || $result == false || $isDisabled || $isParsoidOnly || $isFiltered ) {
+                       # disabled test
+                       return false;
+               }
+
+               # We are really going to run the test, run pending hooks and hooks function
+               wfDebug( __METHOD__ . " unleashing delayed test for: {$this->sectionData['test']}" );
+               $hooksResult = $this->delayedParserTest->unleash( $this->parserTest );
+               if ( !$hooksResult ) {
+                       # Some hook reported an issue. Abort.
+                       throw new MWException( "Problem running hook" );
+               }
+
+               $this->test = array(
+                       'test' => ParserTest::chomp( $this->sectionData['test'] ),
+                       'input' => ParserTest::chomp( $this->sectionData[$input] ),
+                       'result' => ParserTest::chomp( $this->sectionData[$result] ),
+                       'options' => ParserTest::chomp( $this->sectionData['options'] ),
+                       'config' => ParserTest::chomp( $this->sectionData['config'] ),
+               );
+               if ( $tidy != false ) {
+                       $this->test['options'] .= " tidy";
+               }
+               return true;
+       }
+
        function readNextTest() {
-               $this->clearSection();
+               # Run additional subtests of previous test
+               while ( $this->nextSubTest > 0 )
+                       if ( $this->setupCurrentTest() )
+                               return true;
 
-               # Create a fake parser tests which never run anything unless
-               # asked to do so. This will avoid running hooks for a disabled test
-               $delayedParserTest = new DelayedParserTest();
+               $this->clearSection();
+               # Reset hooks for the delayed test object
+               $this->delayedParserTest->reset();
 
                while ( false !== ( $line = fgets( $this->fh ) ) ) {
                        $this->lineNum++;
@@ -446,7 +510,7 @@ class TestFileIterator implements Iterator {
                                                $line = trim( $line );
 
                                                if ( $line ) {
-                                                       $delayedParserTest->requireHook( $line );
+                                                       $this->delayedParserTest->requireHook( $line );
                                                }
                                        }
 
@@ -462,7 +526,7 @@ class TestFileIterator implements Iterator {
                                                $line = trim( $line );
 
                                                if ( $line ) {
-                                                       $delayedParserTest->requireFunctionHook( $line );
+                                                       $this->delayedParserTest->requireFunctionHook( $line );
                                                }
                                        }
 
@@ -489,52 +553,14 @@ class TestFileIterator implements Iterator {
 
                                if ( $this->section == 'end' ) {
                                        $this->checkSection( 'test' );
-                                       // "input" and "result" are old section names allowed
-                                       // for backwards-compatibility.
-                                       $input = $this->checkSection( array( 'wikitext', 'input' ), false );
-                                       $result = $this->checkSection( array( 'html/php', 'html/*', 'html', 'result' ), false );
-
-                                       if ( !isset( $this->sectionData['options'] ) ) {
-                                               $this->sectionData['options'] = '';
-                                       }
-
-                                       if ( !isset( $this->sectionData['config'] ) ) {
-                                               $this->sectionData['config'] = '';
-                                       }
-
-                                       if ( $input == false || $result == false ||
-                                               ( ( preg_match( '/\\bdisabled\\b/i', $this->sectionData['options'] )
-                                                       && !$this->parserTest->runDisabled )
-                                               || ( preg_match( '/\\bparsoid\\b/i', $this->sectionData['options'] )
-                                                       && $result != 'html/php' && !$this->parserTest->runParsoid )
-                                               || !preg_match( "/" . $this->parserTest->regex . "/i", $this->sectionData['test'] ) )
-                                       ) {
-                                               # disabled test
-                                               $this->clearSection();
-
-                                               # Forget any pending hooks call since test is disabled
-                                               $delayedParserTest->reset();
-
-                                               continue;
-                                       }
-
-                                       # We are really going to run the test, run pending hooks and hooks function
-                                       wfDebug( __METHOD__ . " unleashing delayed test for: {$this->sectionData['test']}" );
-                                       $hooksResult = $delayedParserTest->unleash( $this->parserTest );
-                                       if ( !$hooksResult ) {
-                                               # Some hook reported an issue. Abort.
-                                               return false;
-                                       }
-
-                                       $this->test = array(
-                                               'test' => ParserTest::chomp( $this->sectionData['test'] ),
-                                               'input' => ParserTest::chomp( $this->sectionData[$input] ),
-                                               'result' => ParserTest::chomp( $this->sectionData[$result] ),
-                                               'options' => ParserTest::chomp( $this->sectionData['options'] ),
-                                               'config' => ParserTest::chomp( $this->sectionData['config'] ),
-                                       );
-
-                                       return true;
+                                       do {
+                                               if ( $this->setupCurrentTest() )
+                                                       return true;
+                                       } while ( $this->nextSubTest > 0 );
+                                       # go on to next test (since this was disabled)
+                                       $this->clearSection();
+                                       $this->delayedParserTest->reset();
+                                       continue;
                                }
 
                                if ( isset( $this->sectionData[$this->section] ) ) {
@@ -570,7 +596,7 @@ class TestFileIterator implements Iterator {
         * Throw an exception if it is not set, referencing current section
         * and adding the current file name and line number
         *
-        * @param string|array $token Expected token(s) that should have been
+        * @param string|array $tokens Expected token(s) that should have been
         * mentioned before closing this section
         * @param bool $fatal True iff an exception should be thrown if
         * the section is not found.
@@ -702,7 +728,7 @@ class DelayedParserTest {
        /**
         * Similar to ParserTest object but does not run anything
         * Use unleash() to really execute the hook function
-        * @param string $fnHook
+        * @param string $hook
         */
        public function requireTransparentHook( $hook ) {
                $this->transparentHooks[] = $hook;
@@ -732,7 +758,7 @@ class DjVuSupport {
        }
 
        /**
-        * Returns if the DjVu tools are usable
+        * Returns true if the DjVu tools are usable
         *
         * @return bool
         */
@@ -745,3 +771,43 @@ class DjVuSupport {
                        && is_executable( $wgDjvuTxt );
        }
 }
+
+/**
+ * Initialize and detect the tidy support
+ */
+class TidySupport {
+       private $internalTidy;
+       private $externalTidy;
+
+       /**
+        * Determine if there is a usable tidy.
+        */
+       public function __construct() {
+               global $wgTidyBin;
+
+               $this->internalTidy = extension_loaded( 'tidy' ) &&
+                       class_exists( 'tidy' );
+
+               $this->externalTidy = is_executable( $wgTidyBin ) ||
+                       Installer::locateExecutableInDefaultPaths( array( $wgTidyBin ) )
+                       !== false;
+       }
+
+       /**
+        * Returns true if we should use internal tidy.
+        *
+        * @return bool
+        */
+       public function isInternal() {
+               return $this->internalTidy;
+       }
+
+       /**
+        * Returns true if tidy is usable
+        *
+        * @return bool
+        */
+       public function isEnabled() {
+               return $this->internalTidy || $this->externalTidy;
+       }
+}
index efaa65b..d8ed246 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -553,7 +553,7 @@ function wfExtractThumbRequestInfo( $thumbRel ) {
  * file handler.
  *
  * @param File $file File object for file in question
- * @param array $param Array of parameters so far
+ * @param array $params Array of parameters so far
  * @return array Parameters array with more parameters
  */
 function wfExtractThumbParams( $file, $params ) {