Merge "Don't print mediawiki.notification messages"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 20 Feb 2014 12:07:31 +0000 (12:07 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 20 Feb 2014 12:07:31 +0000 (12:07 +0000)
208 files changed:
.jshintignore
RELEASE-NOTES-1.23
docs/hooks.txt
includes/Article.php
includes/AutoLoader.php
includes/DefaultSettings.php
includes/OutputPage.php
includes/Preferences.php
includes/Setup.php
includes/Title.php
includes/WikiPage.php
includes/actions/InfoAction.php
includes/db/Database.php
includes/db/DatabaseMssql.php
includes/db/DatabaseOracle.php
includes/db/DatabaseSqlite.php
includes/db/DatabaseUtility.php
includes/filebackend/FileBackend.php
includes/filebackend/FileBackendMultiWrite.php
includes/filebackend/FileBackendStore.php
includes/filebackend/SwiftFileBackend.php
includes/htmlform/HTMLForm.php
includes/htmlform/HTMLFormField.php
includes/htmlform/HTMLMultiSelectField.php
includes/htmlform/HTMLRadioField.php
includes/htmlform/HTMLSelectAndOtherField.php
includes/htmlform/HTMLSelectField.php
includes/htmlform/HTMLSelectOrOtherField.php
includes/installer/Installer.i18n.php
includes/installer/Installer.php
includes/installer/MssqlInstaller.php [new file with mode: 0644]
includes/installer/MssqlUpdater.php [new file with mode: 0644]
includes/media/Bitmap.php
includes/parser/ParserOutput.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderFileModule.php
includes/specials/SpecialProtectedpages.php
includes/specials/SpecialWhatlinkshere.php
languages/messages/MessagesAng.php
languages/messages/MessagesAr.php
languages/messages/MessagesAst.php
languages/messages/MessagesBe_tarask.php
languages/messages/MessagesBn.php
languages/messages/MessagesBr.php
languages/messages/MessagesCe.php
languages/messages/MessagesCs.php
languages/messages/MessagesCy.php
languages/messages/MessagesDe.php
languages/messages/MessagesDiq.php
languages/messages/MessagesDsb.php
languages/messages/MessagesEgl.php
languages/messages/MessagesEl.php
languages/messages/MessagesEn.php
languages/messages/MessagesEo.php
languages/messages/MessagesEs.php
languages/messages/MessagesEt.php
languages/messages/MessagesEu.php
languages/messages/MessagesFa.php
languages/messages/MessagesFi.php
languages/messages/MessagesFr.php
languages/messages/MessagesFrr.php
languages/messages/MessagesHe.php
languages/messages/MessagesHi.php
languages/messages/MessagesHr.php
languages/messages/MessagesHsb.php
languages/messages/MessagesHu.php
languages/messages/MessagesHy.php
languages/messages/MessagesId.php
languages/messages/MessagesIlo.php
languages/messages/MessagesIs.php
languages/messages/MessagesIt.php
languages/messages/MessagesJa.php
languages/messages/MessagesKiu.php
languages/messages/MessagesKm.php
languages/messages/MessagesKo.php
languages/messages/MessagesKsh.php
languages/messages/MessagesLb.php
languages/messages/MessagesMk.php
languages/messages/MessagesMl.php
languages/messages/MessagesMn.php
languages/messages/MessagesMr.php
languages/messages/MessagesNb.php
languages/messages/MessagesNl.php
languages/messages/MessagesPl.php
languages/messages/MessagesPms.php
languages/messages/MessagesPt.php
languages/messages/MessagesPt_br.php
languages/messages/MessagesQqq.php
languages/messages/MessagesQu.php
languages/messages/MessagesRo.php
languages/messages/MessagesRu.php
languages/messages/MessagesSh.php
languages/messages/MessagesSl.php
languages/messages/MessagesSr_ec.php
languages/messages/MessagesSr_el.php
languages/messages/MessagesSv.php
languages/messages/MessagesTe.php
languages/messages/MessagesTr.php
languages/messages/MessagesUg_arab.php
languages/messages/MessagesUk.php
languages/messages/MessagesVi.php
languages/messages/MessagesWar.php
languages/messages/MessagesYue.php
languages/messages/MessagesZh_hans.php
languages/messages/MessagesZh_hant.php
languages/utils/CLDRPluralRuleEvaluator.php
maintenance/jsduck/categories.json
maintenance/jsduck/config.json
maintenance/language/messageTypes.inc
maintenance/language/messages.inc
maintenance/mssql/tables.sql
resources/Resources.php
resources/jquery.tipsy/jquery.tipsy.js
resources/jquery/jquery.ba-throttle-debounce.js [new file with mode: 0644]
resources/mediawiki.api/mediawiki.api.js
resources/mediawiki.less/mediawiki.mixins.less
resources/mediawiki.less/mediawiki.mixins.rotation.less [new file with mode: 0644]
resources/mediawiki.page/mediawiki.page.patrol.ajax.js
resources/mediawiki.page/mediawiki.page.watch.ajax.js
resources/mediawiki.special/mediawiki.special.css
resources/mediawiki/mediawiki.jqueryMsg.js
resources/mediawiki/mediawiki.jqueryMsg.peg
resources/mediawiki/mediawiki.js
resources/mediawiki/mediawiki.log.js
resources/mediawiki/mediawiki.notification.js
resources/mediawiki/mediawiki.searchSuggest.js
resources/moment/LICENSE [new file with mode: 0644]
resources/moment/lang/ar-ma.js [new file with mode: 0644]
resources/moment/lang/ar.js [new file with mode: 0644]
resources/moment/lang/bg.js [new file with mode: 0644]
resources/moment/lang/br.js [new file with mode: 0644]
resources/moment/lang/bs.js [new file with mode: 0644]
resources/moment/lang/ca.js [new file with mode: 0644]
resources/moment/lang/cs.js [new file with mode: 0644]
resources/moment/lang/cv.js [new file with mode: 0644]
resources/moment/lang/cy.js [new file with mode: 0644]
resources/moment/lang/da.js [new file with mode: 0644]
resources/moment/lang/de.js [new file with mode: 0644]
resources/moment/lang/el.js [new file with mode: 0644]
resources/moment/lang/en-au.js [new file with mode: 0644]
resources/moment/lang/en-ca.js [new file with mode: 0644]
resources/moment/lang/en-gb.js [new file with mode: 0644]
resources/moment/lang/eo.js [new file with mode: 0644]
resources/moment/lang/es.js [new file with mode: 0644]
resources/moment/lang/et.js [new file with mode: 0644]
resources/moment/lang/eu.js [new file with mode: 0644]
resources/moment/lang/fa.js [new file with mode: 0644]
resources/moment/lang/fi.js [new file with mode: 0644]
resources/moment/lang/fo.js [new file with mode: 0644]
resources/moment/lang/fr-ca.js [new file with mode: 0644]
resources/moment/lang/fr.js [new file with mode: 0644]
resources/moment/lang/gl.js [new file with mode: 0644]
resources/moment/lang/he.js [new file with mode: 0644]
resources/moment/lang/hi.js [new file with mode: 0644]
resources/moment/lang/hr.js [new file with mode: 0644]
resources/moment/lang/hu.js [new file with mode: 0644]
resources/moment/lang/hy-am.js [new file with mode: 0644]
resources/moment/lang/id.js [new file with mode: 0644]
resources/moment/lang/is.js [new file with mode: 0644]
resources/moment/lang/it.js [new file with mode: 0644]
resources/moment/lang/ja.js [new file with mode: 0644]
resources/moment/lang/ka.js [new file with mode: 0644]
resources/moment/lang/ko.js [new file with mode: 0644]
resources/moment/lang/lb.js [new file with mode: 0644]
resources/moment/lang/lt.js [new file with mode: 0644]
resources/moment/lang/lv.js [new file with mode: 0644]
resources/moment/lang/mk.js [new file with mode: 0644]
resources/moment/lang/ml.js [new file with mode: 0644]
resources/moment/lang/mr.js [new file with mode: 0644]
resources/moment/lang/ms-my.js [new file with mode: 0644]
resources/moment/lang/nb.js [new file with mode: 0644]
resources/moment/lang/ne.js [new file with mode: 0644]
resources/moment/lang/nl.js [new file with mode: 0644]
resources/moment/lang/nn.js [new file with mode: 0644]
resources/moment/lang/pl.js [new file with mode: 0644]
resources/moment/lang/pt-br.js [new file with mode: 0644]
resources/moment/lang/pt.js [new file with mode: 0644]
resources/moment/lang/ro.js [new file with mode: 0644]
resources/moment/lang/rs.js [new file with mode: 0644]
resources/moment/lang/ru.js [new file with mode: 0644]
resources/moment/lang/sk.js [new file with mode: 0644]
resources/moment/lang/sl.js [new file with mode: 0644]
resources/moment/lang/sq.js [new file with mode: 0644]
resources/moment/lang/sv.js [new file with mode: 0644]
resources/moment/lang/ta.js [new file with mode: 0644]
resources/moment/lang/th.js [new file with mode: 0644]
resources/moment/lang/tl-ph.js [new file with mode: 0644]
resources/moment/lang/tr.js [new file with mode: 0644]
resources/moment/lang/tzm-la.js [new file with mode: 0644]
resources/moment/lang/tzm.js [new file with mode: 0644]
resources/moment/lang/uk.js [new file with mode: 0644]
resources/moment/lang/uz.js [new file with mode: 0644]
resources/moment/lang/vn.js [new file with mode: 0644]
resources/moment/lang/zh-cn.js [new file with mode: 0644]
resources/moment/lang/zh-tw.js [new file with mode: 0644]
resources/moment/moment.js [new file with mode: 0644]
resources/oojs-ui/i18n/km.json [new file with mode: 0644]
resources/oojs-ui/oojs-ui.js
resources/oojs-ui/oojs-ui.svg.css
resources/oojs/oojs.js
skins/CologneBlue.php
skins/Vector.php
skins/vector/components/watchstar.less
skins/vector/images/document-icon.svg
skins/vector/images/news-icon.svg
tests/phpunit/includes/WikiPageTest.php
tests/qunit/data/testrunner.js
tests/qunit/suites/resources/mediawiki/mediawiki.jqueryMsg.test.js

index ebc7312..0e3c679 100644 (file)
@@ -11,6 +11,7 @@ extensions/
 node_modules/
 resources/jquery/jquery.appear.js
 resources/jquery/jquery.async.js
+resources/jquery/jquery.ba-throttle-debounce.js
 resources/jquery/jquery.cookie.js
 resources/jquery/jquery.cycle.all.js
 resources/jquery/jquery.farbtastic.js
@@ -31,6 +32,7 @@ resources/mediawiki.libs/
 resources/oojs/
 resources/oojs-ui/
 resources/sinonjs/
+resources/moment/
 
 # github.com/jshint/jshint/issues/729
 tests/qunit/suites/resources/mediawiki/mediawiki.jscompat.test.js
index 16bdf1e..64c2b3b 100644 (file)
@@ -28,12 +28,16 @@ production.
   and talk pages are now watched by them by default.
 * $wgLBFactoryConf: Class names have had underscores removed. The configuration
   should be updated if LBFactory_Simple or LBFactory_Multi is configured.
-* $wgPasswordSenderName has been deprecated. To set a custom mailer name,
-  the system message 'emailsender' should be modified (default: "{{SITENAME}}").
+* $wgPasswordSenderName has been removed and is no longer functional. To set a
+  custom mailer name, the system message 'emailsender' should be modified
+  (default: "{{SITENAME}}").
 * $wgDBAhandler was removed as the only class using it was also removed
 * The 'max threads' setting was removed from $wgDBservers.
 * Support for AdminSettings.php has been completely removed. All configuration
   belongs in LocalSettings.php.
+* $wgSkipSkin, which has been replaceable by $wgSkipSkins since 2005 (r9249), is
+  now formally deprecated.
+* Removed deprecated $wgDisabledActions as it is hardly used anywhere.
 
 === New features in 1.23 ===
 * ResourceLoader can utilize the Web Storage API to cache modules client-side.
@@ -88,6 +92,19 @@ production.
   links.
 * Added MessageCache::get hook as a new way to customize messages across
   multiple sites.
+* Added jquery.throttle-debounce ResourceLoader module to limit the number of
+  callbacks for frequently occurring events.
+* Special:ProtectedPages shows now a table. The timestamp, the reason and
+  the protecting user is also shown.
+* Added experimental support for using Microsoft SQL Server as the database
+  backend.
+** Added new Microsoft SQL Server-specific configuration variable
+   $wgDBWindowsAuthentication, which makes the web server authenticate against
+   the database server using Integrated Windows Authentication instead of
+   $wgDBuser/$wgDBpassword.
+* HTMLForm 'select', 'selectandother', 'selectorother', 'multiselect', and
+  'radio' fields can now use message keys as labels via the 'options-messages'
+  parameter, which overrides the 'options' parameter.
 
 === Bug fixes in 1.23 ===
 * (bug 41759) The "updated since last visit" markers (on history pages, recent
@@ -223,6 +240,10 @@ changes to languages because of Bugzilla reports.
 * Thumbnails that keep failing to render in thumb.php will be rate-limited
   againt further render attempts for 1 hour. $wgAttemptFailureEpoch can be
   altered to reset all rate-limited thumbnails at once.
+* (bug 56572) Builds of the OOjs and OOjs UI libraries are now available.
+* mw.loader.go and mw.loader.version have been removed.
+* (bug 52815) Preference "Enable simplified search bar (Vector skin only)"
+  was removed.
 
 ==== Removed classes ====
 * FakeMemCachedClient (deprecated in 1.18)
@@ -343,7 +364,7 @@ MediaWiki 1.23 requires PHP 5.3.2 or later.
 
 MySQL is the recommended DBMS. PostgreSQL or SQLite can also be used, but
 support for them is somewhat less mature. There is experimental support for
-Oracle.
+Oracle and Microsoft SQL Server.
 
 The supported versions are:
 
@@ -351,6 +372,7 @@ The supported versions are:
 * PostgreSQL 8.3 or later
 * SQLite 3.3.7 or later
 * Oracle 9.0.1 or later
+* Microsoft SQL Server 2005 (9.00.1399)
 
 == Upgrading ==
 
index 627fcab..9268f83 100644 (file)
@@ -2539,6 +2539,7 @@ $nt: new title
 $user: user who did the move
 $pageid: database ID of the page that's been moved
 $redirid: database ID of the created redirect
+$reason: reason for the move
 
 'TitleReadWhitelist': Called at the end of read permissions checks, just before
 adding the default error message if nothing allows the user to read the page. If
index a5d4d5b..b132ca9 100644 (file)
@@ -611,6 +611,7 @@ class Article implements Page {
                                        if ( !$this->mPage->exists() ) {
                                                wfDebug( __METHOD__ . ": showing missing article\n" );
                                                $this->showMissingArticle();
+                                               $this->mPage->doViewUpdates( $user );
                                                wfProfileOut( __METHOD__ );
                                                return;
                                        }
index 61e0941..54635e9 100644 (file)
@@ -474,7 +474,8 @@ $wgAutoloadLocalClasses = array(
        'LoadMonitorMySQL' => 'includes/db/LoadMonitor.php',
        'LoadMonitorNull' => 'includes/db/LoadMonitor.php',
        'MssqlField' => 'includes/db/DatabaseMssql.php',
-       'MssqlResult' => 'includes/db/DatabaseMssql.php',
+       'MssqlBlob' => 'includes/db/DatabaseMssql.php',
+       'MssqlResultWrapper' => 'includes/db/DatabaseMssql.php',
        'MySQLField' => 'includes/db/DatabaseMysqlBase.php',
        'MySQLMasterPos' => 'includes/db/DatabaseMysqlBase.php',
        'ORAField' => 'includes/db/DatabaseOracle.php',
@@ -611,6 +612,8 @@ $wgAutoloadLocalClasses = array(
        'InstallDocFormatter' => 'includes/installer/InstallDocFormatter.php',
        'Installer' => 'includes/installer/Installer.php',
        'LocalSettingsGenerator' => 'includes/installer/LocalSettingsGenerator.php',
+       'MssqlInstaller' => 'includes/installer/MssqlInstaller.php',
+       'MssqlUpdater' => 'includes/installer/MssqlUpdater.php',
        'MysqlInstaller' => 'includes/installer/MysqlInstaller.php',
        'MysqlUpdater' => 'includes/installer/MysqlUpdater.php',
        'OracleInstaller' => 'includes/installer/OracleInstaller.php',
index dd76a04..b3e04d0 100644 (file)
@@ -868,6 +868,13 @@ $wgContentHandlers = array(
        CONTENT_MODEL_TEXT => 'TextContentHandler',
 );
 
+/**
+ * Whether to enable server-side image thumbnailing. If false, images will
+ * always be sent to the client in full resolution, with appropriate width= and
+ * height= attributes on the <img> tag for the client to do its own scaling.
+ */
+$wgUseImageResize = true;
+
 /**
  * Resizing can be done using PHP's internal image libraries or using
  * ImageMagick or another third-party converter, e.g. GraphicMagick.
@@ -883,11 +890,6 @@ $wgUseImageMagick = false;
  */
 $wgImageMagickConvertCommand = '/usr/bin/convert';
 
-/**
- * The identify command shipped with ImageMagick
- */
-$wgImageMagickIdentifyCommand = '/usr/bin/identify';
-
 /**
  * Sharpening parameter to ImageMagick
  */
@@ -1066,11 +1068,6 @@ $wgGenerateThumbnailOnParse = true;
  */
 $wgShowArchiveThumbnails = true;
 
-/**
- * Obsolete, always true, kept for compatibility with extensions
- */
-$wgUseImageResize = true;
-
 /**
  * If set to true, images that contain certain the exif orientation tag will
  * be rotated accordingly. If set to null, try to auto-detect whether a scaler
@@ -1585,7 +1582,7 @@ $wgSQLMode = '';
 /**
  * Mediawiki schema
  */
-$wgDBmwschema = 'mediawiki';
+$wgDBmwschema = null;
 
 /**
  * To override default SQLite data directory ($docroot/../data)
@@ -1805,6 +1802,11 @@ $wgSlaveLagWarning = 10;
  */
 $wgSlaveLagCritical = 30;
 
+/**
+ * Use Windows Authentication instead of $wgDBuser / $wgDBpassword for MS SQL Server
+ */
+$wgDBWindowsAuthentication = false;
+
 /**@}*/ # End of DB settings }
 
 /************************************************************************//**
@@ -2908,6 +2910,8 @@ $wgDefaultSkin = 'vector';
  * Specify the name of a skin that should not be presented in the list of
  * available skins.  Use for blacklisting a skin which you do not want to
  * remove from the .../skins/ directory
+ *
+ * @deprecated since 1.23; use $wgSkipSkins instead
  */
 $wgSkipSkin = '';
 
@@ -4025,7 +4029,6 @@ $wgDefaultUserOptions = array(
        'underline' => 2,
        'uselivepreview' => 0,
        'usenewrc' => 0,
-       'vector-simplesearch' => 1,
        'watchcreations' => 1,
        'watchdefault' => 1,
        'watchdeletion' => 0,
@@ -6479,12 +6482,6 @@ $wgActions = array(
        'watch' => true,
 );
 
-/**
- * Array of disabled article actions, e.g. view, edit, delete, etc.
- * @deprecated since 1.18; just set $wgActions['action'] = false instead
- */
-$wgDisabledActions = array();
-
 /** @} */ # end actions }
 
 /*************************************************************************//**
index 2b1d4a0..efcd838 100644 (file)
@@ -1574,6 +1574,7 @@ class OutputPage extends ContextSource {
                $this->addModuleScripts( $parserOutput->getModuleScripts() );
                $this->addModuleStyles( $parserOutput->getModuleStyles() );
                $this->addModuleMessages( $parserOutput->getModuleMessages() );
+               $this->addJsConfigVars( $parserOutput->getJsConfigVars() );
 
                // Template versioning...
                foreach ( (array)$parserOutput->getTemplateIds() as $ns => $dbks ) {
@@ -2945,6 +2946,16 @@ $templates
                return $html;
        }
 
+       /**
+        * Get the javascript config vars to include on this page
+        *
+        * @return Array of javascript config vars
+        * @since 1.23
+        */
+       public function getJsConfigVars() {
+               return $this->mJsConfigVars;
+       }
+
        /**
         * Add one or more variables to be set in mw.config in JavaScript.
         *
@@ -3077,7 +3088,7 @@ $templates
                wfRunHooks( 'MakeGlobalVariablesScript', array( &$vars, $this ) );
 
                // Merge in variables from addJsConfigVars last
-               return array_merge( $vars, $this->mJsConfigVars );
+               return array_merge( $vars, $this->getJsConfigVars() );
        }
 
        /**
index c85a00f..9a16383 100644 (file)
@@ -1030,15 +1030,7 @@ class Preferences {
         * @param $defaultPreferences Array
         */
        static function searchPreferences( $user, IContextSource $context, &$defaultPreferences ) {
-               global $wgContLang, $wgVectorUseSimpleSearch;
-
-               if ( $wgVectorUseSimpleSearch ) {
-                       $defaultPreferences['vector-simplesearch'] = array(
-                               'type' => 'toggle',
-                               'label-message' => 'vector-simplesearch-preference',
-                               'section' => 'searchoptions/displaysearchoptions',
-                       );
-               }
+               global $wgContLang;
 
                $defaultPreferences['searcheverything'] = array(
                        'type' => 'toggle',
index 40b3395..0ae6e9b 100644 (file)
@@ -341,11 +341,6 @@ if ( !$wgEnotifMinorEdits ) {
        $wgHiddenPrefs[] = 'enotifminoredits';
 }
 
-# $wgDisabledActions is deprecated as of 1.18
-foreach ( $wgDisabledActions as $action ) {
-       $wgActions[$action] = false;
-}
-
 # We always output HTML5 since 1.22, overriding these is no longer supported
 # we set them here for extensions that depend on its value.
 $wgHtml5 = true;
index dc9822a..a705aaa 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /**
- * Representation a title within %MediaWiki.
+ * Representation of a title within %MediaWiki.
  *
  * See title.txt
  *
@@ -1500,9 +1500,7 @@ class Title {
         * Get a real URL referring to this title, with interwiki link and
         * fragment
         *
-        * See getLocalURL for the arguments.
-        *
-        * @see self::getLocalURL
+        * @see self::getLocalURL for the arguments.
         * @see wfExpandUrl
         * @param $query
         * @param $query2 bool
@@ -1528,8 +1526,12 @@ class Title {
        }
 
        /**
-        * Get a URL with no fragment or server name.  If this page is generated
-        * with action=render, $wgServer is prepended.
+        * Get a URL with no fragment or server name (relative URL) from a Title object.
+        * If this page is generated with action=render, however,
+        * $wgServer is prepended to make an absolute URL.
+        *
+        * @see self::getFullURL to always get an absolute URL.
+        * @see self::newFromText to produce a Title object.
         *
         * @param string|array $query an optional query string,
         *   not used for interwiki links. Can be specified as an associative array as well,
@@ -1542,7 +1544,7 @@ class Title {
         *   The second parameter is deprecated since 1.19. Pass it as a key,value
         *   pair in the first parameter array instead.
         *
-        * @return String the URL
+        * @return String of the URL.
         */
        public function getLocalURL( $query = '', $query2 = false ) {
                global $wgArticlePath, $wgScript, $wgServer, $wgRequest;
@@ -1630,12 +1632,10 @@ class Title {
         * The result obviously should not be URL-escaped, but does need to be
         * HTML-escaped if it's being output in HTML.
         *
-        * See getLocalURL for the arguments.
-        *
         * @param $query
         * @param $query2 bool
         * @param $proto Protocol to use; setting this will cause a full URL to be used
-        * @see self::getLocalURL
+        * @see self::getLocalURL for the arguments.
         * @return String the URL
         */
        public function getLinkURL( $query = '', $query2 = false, $proto = PROTO_RELATIVE ) {
@@ -1655,9 +1655,7 @@ class Title {
         * Get an HTML-escaped version of the URL form, suitable for
         * using in a link, without a server name or fragment
         *
-        * See getLocalURL for the arguments.
-        *
-        * @see self::getLocalURL
+        * @see self::getLocalURL for the arguments.
         * @param $query string
         * @param $query2 bool|string
         * @return String the URL
@@ -1672,9 +1670,7 @@ class Title {
         * Get an HTML-escaped version of the URL form, suitable for
         * using in a link, including the server name and fragment
         *
-        * See getLocalURL for the arguments.
-        *
-        * @see self::getLocalURL
+        * @see self::getLocalURL for the arguments.
         * @return String the URL
         * @deprecated since 1.19
         */
@@ -1692,9 +1688,7 @@ class Title {
         * if $wgInternalServer is not set. If the server variable used is
         * protocol-relative, the URL will be expanded to http://
         *
-        * See getLocalURL for the arguments.
-        *
-        * @see self::getLocalURL
+        * @see self::getLocalURL for the arguments.
         * @return String the URL
         */
        public function getInternalURL( $query = '', $query2 = false ) {
@@ -1713,9 +1707,7 @@ class Title {
         *
         * NOTE: Unlike getInternalURL(), the canonical URL includes the fragment
         *
-        * See getLocalURL for the arguments.
-        *
-        * @see self::getLocalURL
+        * @see self::getLocalURL for the arguments.
         * @return string The URL
         * @since 1.18
         */
@@ -1729,9 +1721,7 @@ class Title {
        /**
         * HTML-escaped version of getCanonicalURL()
         *
-        * See getLocalURL for the arguments.
-        *
-        * @see self::getLocalURL
+        * @see self::getLocalURL for the arguments.
         * @since 1.18
         * @return string
         * @deprecated since 1.19
@@ -3876,7 +3866,20 @@ class Title {
                                $comment .= wfMessage( 'colon-separator' )->inContentLanguage()->text() . $reason;
                        }
                        // @todo FIXME: $params?
-                       $log->addEntry( 'move_prot', $nt, $comment, array( $this->getPrefixedText() ), $wgUser );
+                       $logId = $log->addEntry( 'move_prot', $nt, $comment, array( $this->getPrefixedText() ), $wgUser );
+
+                       // reread inserted pr_ids for log relation
+                       $insertedPrIds = $dbw->select(
+                               'page_restrictions',
+                               'pr_id',
+                               array( 'pr_page' => $redirid ),
+                               __METHOD__
+                       );
+                       $logRelationsValues = array();
+                       foreach ( $insertedPrIds as $prid ) {
+                               $logRelationsValues[] = $prid->pr_id;
+                       }
+                       $log->addRelations( 'pr_id', $logRelationsValues, $logId );
                }
 
                # Update watchlists
@@ -3891,7 +3894,7 @@ class Title {
 
                $dbw->commit( __METHOD__ );
 
-               wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) );
+               wfRunHooks( 'TitleMoveComplete', array( &$this, &$nt, &$wgUser, $pageid, $redirid, $reason ) );
                return true;
        }
 
index 69c37ce..3de0475 100644 (file)
@@ -1173,7 +1173,7 @@ class WikiPage implements Page, IDBAccessObject {
        }
 
        /**
-        * Do standard deferred updates after page view
+        * Do standard deferred updates after page view (existing or missing page)
         * @param User $user The relevant user
         * @param int $oldid The revision id being viewed. If not given or 0, latest revision is assumed.
         */
@@ -2355,6 +2355,9 @@ class WikiPage implements Page, IDBAccessObject {
                // Truncate for whole multibyte characters
                $reason = $wgContLang->truncate( $reason, 255 );
 
+               $logRelationsValues = array();
+               $logRelationsField = null;
+
                if ( $id ) { // Protection of existing page
                        if ( !wfRunHooks( 'ArticleProtect', array( &$this, &$user, $limit, $reason ) ) ) {
                                return Status::newGood();
@@ -2389,11 +2392,24 @@ class WikiPage implements Page, IDBAccessObject {
                                return Status::newFatal( 'no-null-revision', $this->mTitle->getPrefixedText() );
                        }
 
+                       $logRelationsField = 'pr_id';
+
                        // Update restrictions table
                        foreach ( $limit as $action => $restrictions ) {
+                               $dbw->delete(
+                                       'page_restrictions',
+                                       array(
+                                               'pr_page' => $id,
+                                               'pr_type' => $action
+                                       ),
+                                       __METHOD__
+                               );
                                if ( $restrictions != '' ) {
-                                       $dbw->replace( 'page_restrictions', array( array( 'pr_page', 'pr_type' ) ),
-                                               array( 'pr_page' => $id,
+                                       $dbw->insert(
+                                               'page_restrictions',
+                                               array(
+                                                       'pr_id' => $dbw->nextSequenceValue( 'page_restrictions_pr_id_seq' ),
+                                                       'pr_page' => $id,
                                                        'pr_type' => $action,
                                                        'pr_level' => $restrictions,
                                                        'pr_cascade' => ( $cascade && $action == 'edit' ) ? 1 : 0,
@@ -2401,9 +2417,7 @@ class WikiPage implements Page, IDBAccessObject {
                                                ),
                                                __METHOD__
                                        );
-                               } else {
-                                       $dbw->delete( 'page_restrictions', array( 'pr_page' => $id,
-                                               'pr_type' => $action ), __METHOD__ );
+                                       $logRelationsValues[] = $dbw->insertId();
                                }
                        }
 
@@ -2456,7 +2470,10 @@ class WikiPage implements Page, IDBAccessObject {
 
                // Update the protection log
                $log = new LogPage( 'protect' );
-               $log->addEntry( $logAction, $this->mTitle, $reason, $params, $user );
+               $logId = $log->addEntry( $logAction, $this->mTitle, $reason, $params, $user );
+               if ( $logRelationsField !== null && count( $logRelationsValues ) ) {
+                       $log->addRelations( $logRelationsField, $logRelationsValues, $logId );
+               }
 
                return Status::newGood();
        }
@@ -2974,6 +2991,16 @@ class WikiPage implements Page, IDBAccessObject {
                        return $status->getErrorsArray();
                }
 
+               // raise error, when the edit is an edit without a new version
+               if ( empty( $status->value['revision'] ) ) {
+                       $resultDetails = array( 'current' => $current );
+                       return array( array( 'alreadyrolled',
+                                       htmlspecialchars( $this->mTitle->getPrefixedText() ),
+                                       htmlspecialchars( $fromP ),
+                                       htmlspecialchars( $current->getUserText() )
+                       ) );
+               }
+
                $set = array();
                if ( $bot && $guser->isAllowed( 'markbotedits' ) ) {
                        // Mark all reverted edits as bot
@@ -2995,11 +3022,7 @@ class WikiPage implements Page, IDBAccessObject {
                        );
                }
 
-               if ( !empty( $status->value['revision'] ) ) {
-                       $revId = $status->value['revision']->getId();
-               } else {
-                       $revId = false;
-               }
+               $revId = $status->value['revision']->getId();
 
                wfRunHooks( 'ArticleRollbackComplete', array( $this, $guser, $target, $current ) );
 
index 918fc9e..63f3151 100644 (file)
@@ -289,6 +289,9 @@ class InfoAction extends FormlessAction {
                if ( isset( $pageProperties['noindex'] ) ) {
                        $pOutput->setIndexPolicy( 'noindex' );
                }
+               if ( isset( $pageProperties['index'] ) ) {
+                       $pOutput->setIndexPolicy( 'index' );
+               }
 
                // Use robot policy logic
                $policy = $this->page->getRobotPolicy( 'view', $pOutput );
index c6f2611..21c868e 100644 (file)
@@ -245,6 +245,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
        protected $mTrxPreCommitCallbacks = array();
 
        protected $mTablePrefix;
+       protected $mSchema;
        protected $mFlags;
        protected $mForeign;
        protected $mErrorCount = 0;
@@ -428,6 +429,15 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                return wfSetVar( $this->mTablePrefix, $prefix );
        }
 
+       /**
+        * Get/set the db schema.
+        * @param string $schema The database schema to set, or omitted to leave it unchanged.
+        * @return string The previous db schema.
+        */
+       public function dbSchema( $schema = null ) {
+               return wfSetVar( $this->mSchema, $schema );
+       }
+
        /**
         * Set the filehandle to copy write statements to.
         *
@@ -711,7 +721,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         * @param array $params Parameters passed from DatabaseBase::factory()
         */
        function __construct( $params = null ) {
-               global $wgDBprefix, $wgCommandLineMode, $wgDebugDBTransactions;
+               global $wgDBprefix, $wgDBmwschema, $wgCommandLineMode, $wgDebugDBTransactions;
 
                $this->mTrxAtomicLevels = new SplStack;
 
@@ -722,6 +732,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                        $dbName = $params['dbname'];
                        $flags = $params['flags'];
                        $tablePrefix = $params['tablePrefix'];
+                       $schema = $params['schema'];
                        $foreign = $params['foreign'];
                } else { // legacy calling pattern
                        wfDeprecated( __METHOD__ . " method called without parameter array.", "1.23" );
@@ -732,6 +743,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                        $dbName = isset( $args[3] ) ? $args[3] : false;
                        $flags = isset( $args[4] ) ? $args[4] : 0;
                        $tablePrefix = isset( $args[5] ) ? $args[5] : 'get from global';
+                       $schema = 'get from global';
                        $foreign = isset( $args[6] ) ? $args[6] : false;
                }
 
@@ -757,6 +769,13 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                        $this->mTablePrefix = $tablePrefix;
                }
 
+               /** Get the database schema*/
+               if ( $schema == 'get from global' ) {
+                       $this->mSchema = $wgDBmwschema;
+               } else {
+                       $this->mSchema = $schema;
+               }
+
                $this->mForeign = $foreign;
 
                if ( $user ) {
@@ -792,7 +811,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         *
         * @param string $dbType A possible DB type
         * @param array $p An array of options to pass to the constructor.
-        *    Valid options are: host, user, password, dbname, flags, tablePrefix, driver
+        *    Valid options are: host, user, password, dbname, flags, tablePrefix, schema, driver
         * @throws MWException If the database driver or extension cannot be found
         * @return DatabaseBase|null DatabaseBase subclass or null
         */
@@ -832,6 +851,18 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                                " no viable database extension found for type '$dbType'" );
                }
 
+               // Determine schema defaults. Currently Microsoft SQL Server uses $wgDBmwschema,
+               // and everything else doesn't use a schema (e.g. null)
+               // Although postgres and oracle support schemas, we don't use them (yet)
+               // to maintain backwards compatibility
+               $defaultSchemas = array(
+                       'mysql' => null,
+                       'postgres' => null,
+                       'sqlite' => null,
+                       'oracle' => null,
+                       'mssql' => 'get from global',
+               );
+
                $class = 'Database' . ucfirst( $driver );
                if ( class_exists( $class ) && is_subclass_of( $class, 'DatabaseBase' ) ) {
                        $params = array(
@@ -841,6 +872,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                                'dbname' => isset( $p['dbname'] ) ? $p['dbname'] : false,
                                'flags' => isset( $p['flags'] ) ? $p['flags'] : 0,
                                'tablePrefix' => isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : 'get from global',
+                               'schema' => isset( $p['schema'] ) ? $p['schema'] : $defaultSchemas[$dbType],
                                'foreign' => isset( $p['foreign'] ) ? $p['foreign'] : false
                        );
 
@@ -2162,7 +2194,7 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         * @return string Full database name
         */
        public function tableName( $name, $format = 'quoted' ) {
-               global $wgSharedDB, $wgSharedPrefix, $wgSharedTables;
+               global $wgSharedDB, $wgSharedPrefix, $wgSharedTables, $wgSharedSchema;
                # Skip the entire process when we have a string quoted on both ends.
                # Note that we check the end so that we will still quote any use of
                # use of `database`.table. But won't break things if someone wants
@@ -2186,10 +2218,17 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                # We reverse the explode so that database.table and table both output
                # the correct table.
                $dbDetails = explode( '.', $name, 2 );
-               if ( count( $dbDetails ) == 2 ) {
+               if ( count( $dbDetails ) == 3 ) {
+                       list( $database, $schema, $table ) = $dbDetails;
+                       # We don't want any prefix added in this case
+                       $prefix = '';
+               } elseif ( count( $dbDetails ) == 2 ) {
                        list( $database, $table ) = $dbDetails;
                        # We don't want any prefix added in this case
+                       # In dbs that support it, $database may actually be the schema
+                       # but that doesn't affect any of the functionality here
                        $prefix = '';
+                       $schema = null;
                } else {
                        list( $table ) = $dbDetails;
                        if ( $wgSharedDB !== null # We have a shared database
@@ -2198,19 +2237,30 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                                && in_array( $table, $wgSharedTables ) # A shared table is selected
                        ) {
                                $database = $wgSharedDB;
+                               $schema = $wgSharedSchema === null ? $this->mSchema : $wgSharedSchema;
                                $prefix = $wgSharedPrefix === null ? $this->mTablePrefix : $wgSharedPrefix;
                        } else {
                                $database = null;
+                               $schema = $this->mSchema; # Default schema
                                $prefix = $this->mTablePrefix; # Default prefix
                        }
                }
 
                # Quote $table and apply the prefix if not quoted.
+               # $tableName might be empty if this is called from Database::replaceVars()
                $tableName = "{$prefix}{$table}";
-               if ( $format == 'quoted' && !$this->isQuotedIdentifier( $tableName ) ) {
+               if ( $format == 'quoted' && !$this->isQuotedIdentifier( $tableName ) && $tableName !== '' ) {
                        $tableName = $this->addIdentifierQuotes( $tableName );
                }
 
+               # Quote $schema and merge it with the table name if needed
+               if ( $schema !== null ) {
+                       if ( $format == 'quoted' && !$this->isQuotedIdentifier( $schema ) ) {
+                               $schema = $this->addIdentifierQuotes( $schema );
+                       }
+                       $tableName = $schema . '.' . $tableName;
+               }
+
                # Quote $database and merge it with the table name if needed
                if ( $database !== null ) {
                        if ( $format == 'quoted' && !$this->isQuotedIdentifier( $database ) ) {
index 8826683..163554b 100644 (file)
  * @author Joel Penner <a-joelpe at microsoft dot com>
  * @author Chris Pucci <a-cpucci at microsoft dot com>
  * @author Ryan Biesemeyer <v-ryanbi at microsoft dot com>
+ * @author Ryan Schmidt <skizzerz at gmail dot com>
  */
 
 /**
  * @ingroup Database
  */
 class DatabaseMssql extends DatabaseBase {
-       /** @var resource */
+       protected $mInsertId = null;
        protected $mLastResult = null;
-
-       /** @var int The number of rows affected as an integer */
        protected $mAffectedRows = null;
+       protected $mSubqueryId = 0;
+       protected $mScrollableCursor = true;
+       protected $mPrepareStatements = true;
+       protected $mBinaryColumnCache = null;
+       protected $mBitColumnCache = null;
+       protected $mIgnoreDupKeyErrors = false;
 
-       /**
-        * @var int Post number for database
-        * @todo Unused and can be removed?
-        */
        protected $mPort;
 
-       /** @var int */
-       private $mInsertId = null;
-
-       function cascadingDeletes() {
+       public function cascadingDeletes() {
                return true;
        }
 
-       function cleanupTriggers() {
-               return true;
+       public function cleanupTriggers() {
+               return false;
        }
 
-       function strictIPs() {
-               return true;
+       public function strictIPs() {
+               return false;
        }
 
-       function realTimestamps() {
-               return true;
+       public function realTimestamps() {
+               return false;
        }
 
-       function implicitGroupby() {
+       public function implicitGroupby() {
                return false;
        }
 
-       function implicitOrderby() {
+       public function implicitOrderby() {
                return false;
        }
 
-       function functionalIndexes() {
+       public function functionalIndexes() {
                return true;
        }
 
-       function unionSupportsOrderAndLimit() {
+       public function unionSupportsOrderAndLimit() {
                return false;
        }
 
@@ -84,16 +82,17 @@ class DatabaseMssql extends DatabaseBase {
         * @throws DBConnectionError
         * @return bool|DatabaseBase|null
         */
-       function open( $server, $user, $password, $dbName ) {
+       public function open( $server, $user, $password, $dbName ) {
                # Test for driver support, to avoid suppressed fatal error
                if ( !function_exists( 'sqlsrv_connect' ) ) {
                        throw new DBConnectionError(
                                $this,
-                               "MS Sql Server Native (sqlsrv) functions missing. You can download " .
-                                       "the driver from: http://go.microsoft.com/fwlink/?LinkId=123470\n" );
+                               "Microsoft SQL Server Native (sqlsrv) functions missing.
+                               You can download the driver from: http://go.microsoft.com/fwlink/?LinkId=123470\n"
+                       );
                }
 
-               global $wgDBport;
+               global $wgDBport, $wgDBWindowsAuthentication;
 
                # e.g. the class is being loaded
                if ( !strlen( $user ) ) {
@@ -113,36 +112,19 @@ class DatabaseMssql extends DatabaseBase {
                        $connectionInfo['Database'] = $dbName;
                }
 
-               // Start NT Auth Hack
-               // Quick and dirty work around to provide NT Auth designation support.
-               // Current solution requires installer to know to input 'ntauth' for
-               // both username and password to trigger connection via NT Auth. Ugly,
-               // ugly, ugly!
-               // @todo Make this better and add NT Auth choice to MW installer when
-               // SQL Server option is chosen.
-               $ntAuthUserTest = strtolower( $user );
-               $ntAuthPassTest = strtolower( $password );
-
                // Decide which auth scenerio to use
-               if ( $ntAuthPassTest == 'ntauth' && $ntAuthUserTest == 'ntauth' ) {
-                       // Don't add credentials to $connectionInfo
-               } else {
+               // if we are using Windows auth, don't add credentials to $connectionInfo
+               if ( !$wgDBWindowsAuthentication ) {
                        $connectionInfo['UID'] = $user;
                        $connectionInfo['PWD'] = $password;
                }
-               // End NT Auth Hack
 
                wfSuppressWarnings();
                $this->mConn = sqlsrv_connect( $server, $connectionInfo );
                wfRestoreWarnings();
 
                if ( $this->mConn === false ) {
-                       wfDebug( "DB connection error\n" );
-                       wfDebug( "Server: $server, Database: $dbName, User: $user, Password: " .
-                               substr( $password, 0, 3 ) . "...\n" );
-                       wfDebug( $this->lastError() . "\n" );
-
-                       return false;
+                       throw new DBConnectionError( $this, $this->lastError() );
                }
 
                $this->mOpened = true;
@@ -159,13 +141,34 @@ class DatabaseMssql extends DatabaseBase {
                return sqlsrv_close( $this->mConn );
        }
 
+       /**
+        * @param bool|MssqlResultWrapper|resource $result
+        * @return bool|MssqlResultWrapper
+        */
+       public function resultObject( $result ) {
+               if ( empty( $result ) ) {
+                       return false;
+               } elseif ( $result instanceof MssqlResultWrapper ) {
+                       return $result;
+               } elseif ( $result === true ) {
+                       // Successful write query
+                       return $result;
+               } else {
+                       return new MssqlResultWrapper( $this, $result );
+               }
+       }
+
        /**
         * @param string $sql
         * @return bool|MssqlResult
         * @throws DBUnexpectedError
         */
        protected function doQuery( $sql ) {
-               wfDebug( "SQL: [$sql]\n" );
+               global $wgDebugDumpSql;
+               if ( $wgDebugDumpSql ) {
+                       wfDebug( "SQL: [$sql]\n" );
+               }
+               $this->offset = 0;
 
                // several extensions seem to think that all databases support limits
                // via LIMIT N after the WHERE clause well, MSSQL uses SELECT TOP N,
@@ -184,161 +187,180 @@ class DatabaseMssql extends DatabaseBase {
                }
 
                // perform query
-               $stmt = sqlsrv_query( $this->mConn, $sql );
-               if ( $stmt == false ) {
-                       $message = "A database error has occurred. Did you forget " .
-                               "to run maintenance/update.php after upgrading?  See: " .
-                               "http://www.mediawiki.org/wiki/Manual:Upgrading#Run_the_update_script\n" .
-                               "Query: " . htmlentities( $sql ) . "\n" .
-                               "Function: " . __METHOD__ . "\n";
-                       // process each error (our driver will give us an array of errors unlike other providers)
-                       foreach ( sqlsrv_errors() as $error ) {
-                               $message .= $message . "ERROR[" . $error['code'] . "] " . $error['message'] . "\n";
-                       }
 
-                       throw new DBUnexpectedError( $this, $message );
+               // SQLSRV_CURSOR_STATIC is slower than SQLSRV_CURSOR_CLIENT_BUFFERED (one of the two is
+               // needed if we want to be able to seek around the result set), however CLIENT_BUFFERED
+               // has a bug in the sqlsrv driver where wchar_t types (such as nvarchar) that are empty
+               // strings make php throw a fatal error "Severe error translating Unicode"
+               if ( $this->mScrollableCursor ) {
+                       $scrollArr = array( 'Scrollable' => SQLSRV_CURSOR_STATIC );
+               } else {
+                       $scrollArr = array();
                }
-               // remember number of rows affected
-               $this->mAffectedRows = sqlsrv_rows_affected( $stmt );
 
-               // if it is a SELECT statement, or an insert with a request to output
-               // something we want to return a row.
-               if ( ( preg_match( '#\bSELECT\s#i', $sql ) ) ||
-                       ( preg_match( '#\bINSERT\s#i', $sql ) && preg_match( '#\bOUTPUT\s+INSERTED\b#i', $sql ) )
-               ) {
-                       // this is essentially a rowset, but Mediawiki calls these 'result'
-                       // the rowset owns freeing the statement
-                       $res = new MssqlResult( $stmt );
+               if ( $this->mPrepareStatements ) {
+                       // we do prepare + execute so we can get its field metadata for later usage if desired
+                       $stmt = sqlsrv_prepare( $this->mConn, $sql, array(), $scrollArr );
+                       $success = sqlsrv_execute( $stmt );
                } else {
-                       // otherwise we simply return it was successful, failure throws an exception
-                       $res = true;
+                       $stmt = sqlsrv_query( $this->mConn, $sql, array(), $scrollArr );
+                       $success = (bool)$stmt;
                }
 
-               return $res;
-       }
+               if ( $this->mIgnoreDupKeyErrors ) {
+                       // ignore duplicate key errors, but nothing else
+                       // this emulates INSERT IGNORE in MySQL
+                       if ( $success === false ) {
+                               $errors = sqlsrv_errors( SQLSRV_ERR_ERRORS );
+                               $success = true;
+
+                               foreach ( $errors as $err ) {
+                                       if ( $err['SQLSTATE'] == '23000' && $err['code'] == '2601' ) {
+                                               continue; // duplicate key error
+                                       } elseif ( $err['SQLSTATE'] == '01000' && $err['code'] == '3621' ) {
+                                               continue; // generic "the statement has been terminated" error
+                                       }
 
-       /**
-        * @param mixed|ResultWrapper $res
-        */
-       function freeResult( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
+                                       $success = false; // getting here means we got an error we weren't expecting
+                                       break;
+                               }
+
+                               if ( $success ) {
+                                       $this->mAffectedRows = 0;
+                                       return true;
+                               }
+                       }
+               }
+
+               if ( $success === false ) {
+                       return false;
                }
-               $res->free();
+               // remember number of rows affected
+               $this->mAffectedRows = sqlsrv_rows_affected( $stmt );
+
+               return $stmt;
        }
 
-       /**
-        * @param ResultWrapper|stdClass $res
-        * @return stdClass
-        */
-       function fetchObject( $res ) {
+       public function freeResult( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
-               $row = $res->fetch( 'OBJECT' );
 
-               return $row;
+               sqlsrv_free_stmt( $res );
        }
 
        /**
-        * @return string
+        * @param MssqlResultWrapper $res
+        * @return stdClass
         */
-       function getErrors() {
-               $strRet = '';
-               $retErrors = sqlsrv_errors( SQLSRV_ERR_ALL );
-               if ( $retErrors != null ) {
-                       foreach ( $retErrors as $arrError ) {
-                               $strRet .= "SQLState: " . $arrError['SQLSTATE'] . "\n";
-                               $strRet .= "Error Code: " . $arrError['code'] . "\n";
-                               $strRet .= "Message: " . $arrError['message'] . "\n";
-                       }
-               } else {
-                       $strRet = "No errors found";
-               }
-
-               return $strRet;
+       public function fetchObject( $res ) {
+               // $res is expected to be an instance of MssqlResultWrapper here
+               return $res->fetchObject();
        }
 
        /**
-        * @param resource $res
-        * @return Blob
+        * @param MssqlResultWrapper $res
+        * @return array
         */
-       function fetchRow( $res ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-               $row = $res->fetch( SQLSRV_FETCH_BOTH );
-
-               return $row;
+       public function fetchRow( $res ) {
+               return $res->fetchRow();
        }
 
        /**
         * @param mixed $res
         * @return int
         */
-       function numRows( $res ) {
+       public function numRows( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
 
-               return ( $res ) ? $res->numrows() : 0;
+               return sqlsrv_num_rows( $res );
        }
 
-       function numFields( $res ) {
+       /**
+        * @param mixed $res
+        * @return int
+        */
+       public function numFields( $res ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
 
-               return ( $res ) ? $res->numfields() : 0;
+               return sqlsrv_num_fields( $res );
        }
 
-       function fieldName( $res, $n ) {
+       /**
+        * @param mixed $res
+        * @param int $n
+        * @return int
+        */
+       public function fieldName( $res, $n ) {
                if ( $res instanceof ResultWrapper ) {
                        $res = $res->result;
                }
 
-               return ( $res ) ? $res->fieldname( $n ) : 0;
+               $metadata = sqlsrv_field_metadata( $res );
+               return $metadata[$n]['Name'];
        }
 
        /**
         * This must be called after nextSequenceVal
         * @return int|null
         */
-       function insertId() {
+       public function insertId() {
                return $this->mInsertId;
        }
 
        /**
-        * @param mixed $res
+        * @param MssqlResultWrapper $res
         * @param int $row
         * @return bool
         */
-       function dataSeek( $res, $row ) {
-               if ( $res instanceof ResultWrapper ) {
-                       $res = $res->result;
-               }
-
-               return ( $res ) ? $res->seek( $row ) : false;
+       public function dataSeek( $res, $row ) {
+               return $res->seek( $row );
        }
 
-       function lastError() {
-               if ( $this->mConn ) {
-                       return $this->getErrors();
+       /**
+        * @return string
+        */
+       public function lastError() {
+               $strRet = '';
+               $retErrors = sqlsrv_errors( SQLSRV_ERR_ALL );
+               if ( $retErrors != null ) {
+                       foreach ( $retErrors as $arrError ) {
+                               $strRet .= $this->formatError( $arrError ) . "\n";
+                       }
                } else {
-                       return "No database connection";
+                       $strRet = "No errors found";
                }
+
+               return $strRet;
+       }
+
+       /**
+        * @return string
+        */
+       private function formatError( $err ) {
+               return '[SQLSTATE ' . $err['SQLSTATE'] . '][Error Code ' . $err['code'] . ']' . $err['message'];
        }
 
-       function lastErrno() {
+       /**
+        * @return string
+        */
+       public function lastErrno() {
                $err = sqlsrv_errors( SQLSRV_ERR_ALL );
-               if ( $err[0] ) {
+               if ( $err !== null && isset( $err[0] ) ) {
                        return $err[0]['code'];
                } else {
                        return 0;
                }
        }
 
-       function affectedRows() {
+       /**
+        * @return int
+        */
+       public function affectedRows() {
                return $this->mAffectedRows;
        }
 
@@ -357,14 +379,40 @@ class DatabaseMssql extends DatabaseBase {
         * @return mixed Database result resource (feed to Database::fetchObject
         *   or whatever), or false on failure
         */
-       function select( $table, $vars, $conds = '', $fname = __METHOD__,
+       public function select( $table, $vars, $conds = '', $fname = __METHOD__,
                $options = array(), $join_conds = array()
        ) {
                $sql = $this->selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );
                if ( isset( $options['EXPLAIN'] ) ) {
-                       sqlsrv_query( $this->mConn, "SET SHOWPLAN_ALL ON;" );
-                       $ret = $this->query( $sql, $fname );
-                       sqlsrv_query( $this->mConn, "SET SHOWPLAN_ALL OFF;" );
+                       try {
+                               $this->mScrollableCursor = false;
+                               $this->mPrepareStatements = false;
+                               $this->query( "SET SHOWPLAN_ALL ON" );
+                               $ret = $this->query( $sql, $fname );
+                               $this->query( "SET SHOWPLAN_ALL OFF" );
+                       } catch ( DBQueryError $dqe ) {
+                               if ( isset( $options['FOR COUNT'] ) ) {
+                                       // likely don't have privs for SHOWPLAN, so run a select count instead
+                                       $this->query( "SET SHOWPLAN_ALL OFF" );
+                                       unset( $options['EXPLAIN'] );
+                                       $ret = $this->select(
+                                               $table,
+                                               'COUNT(*) AS EstimateRows',
+                                               $conds,
+                                               $fname,
+                                               $options,
+                                               $join_conds
+                                       );
+                               } else {
+                                       // someone actually wanted the query plan instead of an est row count
+                                       // let them know of the error
+                                       $this->mScrollableCursor = true;
+                                       $this->mPrepareStatements = true;
+                                       throw $dqe;
+                               }
+                       }
+                       $this->mScrollableCursor = true;
+                       $this->mPrepareStatements = true;
 
                        return $ret;
                }
@@ -385,14 +433,60 @@ class DatabaseMssql extends DatabaseBase {
         *    (e.g. array( 'page' => array('LEFT JOIN','page_latest=rev_id') )
         * @return string The SQL text
         */
-       function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__,
+       public function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__,
                $options = array(), $join_conds = array()
        ) {
                if ( isset( $options['EXPLAIN'] ) ) {
                        unset( $options['EXPLAIN'] );
                }
 
-               return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );
+               $sql = parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );
+
+               // try to rewrite aggregations of bit columns (currently MAX and MIN)
+               if ( strpos( $sql, 'MAX(' ) !== false || strpos( $sql, 'MIN(' ) !== false ) {
+                       $bitColumns = array();
+                       if ( is_array( $table ) ) {
+                               foreach ( $table as $t ) {
+                                       $bitColumns += $this->getBitColumns( $this->tableName( $t ) );
+                               }
+                       } else {
+                               $bitColumns = $this->getBitColumns( $this->tableName( $table ) );
+                       }
+
+                       foreach ( $bitColumns as $col => $info ) {
+                               $replace = array(
+                                       "MAX({$col})" => "MAX(CAST({$col} AS tinyint))",
+                                       "MIN({$col})" => "MIN(CAST({$col} AS tinyint))",
+                               );
+                               $sql = str_replace( array_keys( $replace ), array_values( $replace ), $sql );
+                       }
+               }
+
+               return $sql;
+       }
+
+       public function deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds,
+               $fname = __METHOD__
+       ) {
+               $this->mScrollableCursor = false;
+               try {
+                       parent::deleteJoin( $delTable, $joinTable, $delVar, $joinVar, $conds, $fname );
+               } catch( Exception $e ) {
+                       $this->mScrollableCursor = true;
+                       throw $e;
+               }
+               $this->mScrollableCursor = true;
+       }
+
+       public function delete( $table, $conds, $fname = __METHOD__ ) {
+               $this->mScrollableCursor = false;
+               try {
+                       parent::delete( $table, $conds, $fname );
+               } catch( Exception $e ) {
+                       $this->mScrollableCursor = true;
+                       throw $e;
+               }
+               $this->mScrollableCursor = true;
        }
 
        /**
@@ -408,16 +502,18 @@ class DatabaseMssql extends DatabaseBase {
         * @param array $options
         * @return int
         */
-       function estimateRowCount( $table, $vars = '*', $conds = '',
+       public function estimateRowCount( $table, $vars = '*', $conds = '',
                $fname = __METHOD__, $options = array()
        ) {
                // http://msdn2.microsoft.com/en-us/library/aa259203.aspx
                $options['EXPLAIN'] = true;
+               $options['FOR COUNT'] = true;
                $res = $this->select( $table, $vars, $conds, $fname, $options );
 
                $rows = -1;
                if ( $res ) {
                        $row = $this->fetchRow( $res );
+
                        if ( isset( $row['EstimateRows'] ) ) {
                                $rows = $row['EstimateRows'];
                        }
@@ -434,7 +530,7 @@ class DatabaseMssql extends DatabaseBase {
         * @param string $fname
         * @return array|bool|null
         */
-       function indexInfo( $table, $index, $fname = __METHOD__ ) {
+       public function indexInfo( $table, $index, $fname = __METHOD__ ) {
                # This does not return the same info as MYSQL would, but that's OK
                # because MediaWiki never uses the returned value except to check for
                # the existance of indexes.
@@ -481,7 +577,7 @@ class DatabaseMssql extends DatabaseBase {
         * @throws DBQueryError
         * @return bool
         */
-       function insert( $table, $arrToInsert, $fname = __METHOD__, $options = array() ) {
+       public function insert( $table, $arrToInsert, $fname = __METHOD__, $options = array() ) {
                # No rows to insert, easy just return now
                if ( !count( $arrToInsert ) ) {
                        return true;
@@ -497,21 +593,24 @@ class DatabaseMssql extends DatabaseBase {
                        $arrToInsert = array( 0 => $arrToInsert ); // make everything multi row compatible
                }
 
-               $allOk = true;
-
                // We know the table we're inserting into, get its identity column
                $identity = null;
-               // strip matching square brackets from table name
-               $tableRaw = preg_replace( '#\[([^\]]*)\]#', '$1', $table );
+               // strip matching square brackets and the db/schema from table name
+               $tableRawArr = explode( '.', preg_replace( '#\[([^\]]*)\]#', '$1', $table ) );
+               $tableRaw = array_pop( $tableRawArr );
                $res = $this->doQuery(
                        "SELECT NAME AS idColumn FROM SYS.IDENTITY_COLUMNS " .
                                "WHERE OBJECT_NAME(OBJECT_ID)='{$tableRaw}'"
                );
-               if ( $res && $res->numrows() ) {
+               if ( $res && sqlsrv_has_rows( $res ) ) {
                        // There is an identity for this table.
-                       $identity = array_pop( $res->fetch( SQLSRV_FETCH_ASSOC ) );
+                       $identityArr = sqlsrv_fetch_array( $res, SQLSRV_FETCH_ASSOC );
+                       $identity = array_pop( $identityArr );
                }
-               unset( $res );
+               sqlsrv_free_stmt( $res );
+
+               // Determine binary/varbinary fields so we can encode data as a hex string like 0xABCDEF
+               $binaryColumns = $this->getBinaryColumns( $table );
 
                foreach ( $arrToInsert as $a ) {
                        // start out with empty identity column, this is so we can return
@@ -526,11 +625,13 @@ class DatabaseMssql extends DatabaseBase {
                                foreach ( $a as $k => $v ) {
                                        if ( $k == $identity ) {
                                                if ( !is_null( $v ) ) {
-                                                       // there is a value being passed to us, we need to turn on and off inserted identity
+                                                       // there is a value being passed to us,
+                                                       // we need to turn on and off inserted identity
                                                        $sqlPre = "SET IDENTITY_INSERT $table ON;";
                                                        $sqlPost = ";SET IDENTITY_INSERT $table OFF;";
                                                } else {
-                                                       // we can't insert NULL into an identity column, so remove the column from the insert.
+                                                       // we can't insert NULL into an identity column,
+                                                       // so remove the column from the insert.
                                                        unset( $a[$k] );
                                                }
                                        }
@@ -545,21 +646,9 @@ class DatabaseMssql extends DatabaseBase {
                        // INSERT IGNORE is not supported by SQL Server
                        // remove IGNORE from options list and set ignore flag to true
                        $ignoreClause = false;
-                       foreach ( $options as $k => $v ) {
-                               if ( strtoupper( $v ) == "IGNORE" ) {
-                                       unset( $options[$k] );
-                                       $ignoreClause = true;
-                               }
-                       }
-
-                       // translate MySQL INSERT IGNORE to something SQL Server can use
-                       // example:
-                       // MySQL: INSERT IGNORE INTO user_groups (ug_user,ug_group) VALUES ('1','sysop')
-                       // MSSQL: IF NOT EXISTS (SELECT * FROM user_groups WHERE ug_user = '1')
-                       //        INSERT INTO user_groups (ug_user,ug_group) VALUES ('1','sysop')
-                       if ( $ignoreClause ) {
-                               $prival = $a[$keys[0]];
-                               $sqlPre .= "IF NOT EXISTS (SELECT * FROM $table WHERE $keys[0] = '$prival')";
+                       if ( in_array( 'IGNORE', $options ) ) {
+                               $options = array_diff( $options, array( 'IGNORE' ) );
+                               $this->mIgnoreDupKeyErrors = true;
                        }
 
                        // Build the actual query
@@ -567,48 +656,49 @@ class DatabaseMssql extends DatabaseBase {
                                " INTO $table (" . implode( ',', $keys ) . ") $identityClause VALUES (";
 
                        $first = true;
-                       foreach ( $a as $value ) {
+                       foreach ( $a as $key => $value ) {
+                               if ( isset( $binaryColumns[$key] ) ) {
+                                       $value = new MssqlBlob( $value );
+                               }
                                if ( $first ) {
                                        $first = false;
                                } else {
                                        $sql .= ',';
                                }
-                               if ( is_string( $value ) ) {
-                                       $sql .= $this->addQuotes( $value );
-                               } elseif ( is_null( $value ) ) {
+                               if ( is_null( $value ) ) {
                                        $sql .= 'null';
                                } elseif ( is_array( $value ) || is_object( $value ) ) {
-                                       if ( is_object( $value ) && strtolower( get_class( $value ) ) == 'blob' ) {
+                                       if ( is_object( $value ) && $value instanceof Blob ) {
                                                $sql .= $this->addQuotes( $value );
                                        } else {
                                                $sql .= $this->addQuotes( serialize( $value ) );
                                        }
                                } else {
-                                       $sql .= $value;
+                                       $sql .= $this->addQuotes( $value );
                                }
                        }
                        $sql .= ')' . $sqlPost;
 
                        // Run the query
-                       $ret = sqlsrv_query( $this->mConn, $sql );
-
-                       if ( $ret === false ) {
-                               throw new DBQueryError( $this, $this->getErrors(), $this->lastErrno(), $sql, $fname );
-                       } elseif ( $ret != null ) {
-                               // remember number of rows affected
-                               $this->mAffectedRows = sqlsrv_rows_affected( $ret );
-                               if ( !is_null( $identity ) ) {
-                                       // then we want to get the identity column value we were assigned and save it off
-                                       $row = sqlsrv_fetch_object( $ret );
-                                       $this->mInsertId = $row->$identity;
-                               }
-                               sqlsrv_free_stmt( $ret );
-                               continue;
+                       $this->mScrollableCursor = false;
+                       try {
+                               $ret = $this->query( $sql );
+                       } catch ( Exception $e ) {
+                               $this->mScrollableCursor = true;
+                               $this->mIgnoreDupKeyErrors = false;
+                               throw $e;
+                       }
+                       $this->mScrollableCursor = true;
+                       $this->mIgnoreDupKeyErrors = false;
+
+                       if ( !is_null( $identity ) ) {
+                               // then we want to get the identity column value we were assigned and save it off
+                               $row = $ret->fetchObject();
+                               $this->mInsertId = $row->$identity;
                        }
-                       $allOk = false;
                }
 
-               return $allOk;
+               return $ret;
        }
 
        /**
@@ -626,69 +716,154 @@ class DatabaseMssql extends DatabaseBase {
         * @throws DBQueryError
         * @return null|ResultWrapper
         */
-       function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
-               $insertOptions = array(), $selectOptions = array() ) {
-               $ret = parent::insertSelect(
-                       $destTable,
-                       $srcTable,
-                       $varMap,
-                       $conds,
-                       $fname,
-                       $insertOptions,
-                       $selectOptions
-               );
-
-               if ( $ret === false ) {
-                       throw new DBQueryError( $this, $this->getErrors(), $this->lastErrno(), /*$sql*/ '', $fname );
-               } elseif ( $ret != null ) {
-                       // remember number of rows affected
-                       // @todo FIXME: $ret type does not appear to be a resource
-                       $this->mAffectedRows = sqlsrv_rows_affected( $ret );
-
-                       return $ret;
+       public function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
+               $insertOptions = array(), $selectOptions = array()
+       ) {
+               $this->mScrollableCursor = false;
+               try {
+                       $ret = parent::insertSelect(
+                               $destTable,
+                               $srcTable,
+                               $varMap,
+                               $conds,
+                               $fname,
+                               $insertOptions,
+                               $selectOptions
+                       );
+               } catch( Exception $e ) {
+                       $this->mScrollableCursor = true;
+                       throw $e;
                }
+               $this->mScrollableCursor = true;
 
-               return null;
+               return $ret;
        }
 
        /**
-        * Return the next in a sequence, save the value for retrieval via insertId()
-        * @param string $seqName
-        * @return int|null
+        * UPDATE wrapper. Takes a condition array and a SET array.
+        *
+        * @param string $table name of the table to UPDATE. This will be passed through
+        *                DatabaseBase::tableName().
+        *
+        * @param array $values An array of values to SET. For each array element,
+        *                the key gives the field name, and the value gives the data
+        *                to set that field to. The data will be quoted by
+        *                DatabaseBase::addQuotes().
+        *
+        * @param array $conds An array of conditions (WHERE). See
+        *                DatabaseBase::select() for the details of the format of
+        *                condition arrays. Use '*' to update all rows.
+        *
+        * @param string $fname The function name of the caller (from __METHOD__),
+        *                for logging and profiling.
+        *
+        * @param array $options An array of UPDATE options, can be:
+        *                   - IGNORE: Ignore unique key conflicts
+        *                   - LOW_PRIORITY: MySQL-specific, see MySQL manual.
+        * @return bool
         */
-       function nextSequenceValue( $seqName ) {
-               if ( !$this->tableExists( 'sequence_' . $seqName ) ) {
-                       sqlsrv_query(
-                               $this->mConn,
-                               "CREATE TABLE [sequence_$seqName] (id INT NOT NULL IDENTITY PRIMARY KEY, junk varchar(10) NULL)"
-                       );
-               }
-               sqlsrv_query( $this->mConn, "INSERT INTO [sequence_$seqName] (junk) VALUES ('')" );
-               $ret = sqlsrv_query( $this->mConn, "SELECT TOP 1 id FROM [sequence_$seqName] ORDER BY id DESC" );
-               // KEEP ASSOC THERE, weird weird bug dealing with the return value if you don't
-               $row = sqlsrv_fetch_array( $ret, SQLSRV_FETCH_ASSOC );
+       function update( $table, $values, $conds, $fname = __METHOD__, $options = array() ) {
+               $table = $this->tableName( $table );
+               $binaryColumns = $this->getBinaryColumns( $table );
 
-               sqlsrv_free_stmt( $ret );
-               $this->mInsertId = $row['id'];
+               $opts = $this->makeUpdateOptions( $options );
+               $sql = "UPDATE $opts $table SET " . $this->makeList( $values, LIST_SET, $binaryColumns );
 
-               return $row['id'];
+               if ( $conds !== array() && $conds !== '*' ) {
+                       $sql .= " WHERE " . $this->makeList( $conds, LIST_AND, $binaryColumns );
+               }
+
+               $this->mScrollableCursor = false;
+               try {
+                       $ret = $this->query( $sql );
+               } catch ( Exception $e ) {
+                       $this->mScrollableCursor = true;
+                       throw $e;
+               }
+               $this->mScrollableCursor = true;
+               return true;
        }
 
        /**
-        * Return the current value of a sequence. Assumes it has ben nextval'ed in this session.
-        * @param string $seqName
-        * @return int|null
+        * Makes an encoded list of strings from an array
+        * @param array $a containing the data
+        * @param int $mode Constant
+        *      - LIST_COMMA:          comma separated, no field names
+        *      - LIST_AND:            ANDed WHERE clause (without the WHERE). See
+        *        the documentation for $conds in DatabaseBase::select().
+        *      - LIST_OR:             ORed WHERE clause (without the WHERE)
+        *      - LIST_SET:            comma separated with field names, like a SET clause
+        *      - LIST_NAMES:          comma separated field names
+        * @param array $binaryColumns Contains a list of column names that are binary types
+        *      This is a custom parameter only present for MS SQL.
+        *
+        * @throws MWException|DBUnexpectedError
+        * @return string
         */
-       function currentSequenceValue( $seqName ) {
-               $ret = sqlsrv_query( $this->mConn, "SELECT TOP 1 id FROM [sequence_$seqName] ORDER BY id DESC" );
-               if ( $ret !== false ) {
-                       $row = sqlsrv_fetch_array( $ret );
-                       sqlsrv_free_stmt( $ret );
+       public function makeList( $a, $mode = LIST_COMMA, $binaryColumns = array() ) {
+               if ( !is_array( $a ) ) {
+                       throw new DBUnexpectedError( $this,
+                               'DatabaseBase::makeList called with incorrect parameters' );
+               }
 
-                       return $row['id'];
-               } else {
-                       return $this->nextSequenceValue( $seqName );
+               $first = true;
+               $list = '';
+
+               foreach ( $a as $field => $value ) {
+                       if ( $mode != LIST_NAMES && isset( $binaryColumns[$field] ) ) {
+                               if ( is_array( $value ) ) {
+                                       foreach ( $value as &$v ) {
+                                               $v = new MssqlBlob( $v );
+                                       }
+                               } else {
+                                       $value = new MssqlBlob( $value );
+                               }
+                       }
+
+                       if ( !$first ) {
+                               if ( $mode == LIST_AND ) {
+                                       $list .= ' AND ';
+                               } elseif ( $mode == LIST_OR ) {
+                                       $list .= ' OR ';
+                               } else {
+                                       $list .= ',';
+                               }
+                       } else {
+                               $first = false;
+                       }
+
+                       if ( ( $mode == LIST_AND || $mode == LIST_OR ) && is_numeric( $field ) ) {
+                               $list .= "($value)";
+                       } elseif ( ( $mode == LIST_SET ) && is_numeric( $field ) ) {
+                               $list .= "$value";
+                       } elseif ( ( $mode == LIST_AND || $mode == LIST_OR ) && is_array( $value ) ) {
+                               if ( count( $value ) == 0 ) {
+                                       throw new MWException( __METHOD__ . ": empty input for field $field" );
+                               } elseif ( count( $value ) == 1 ) {
+                                       // Special-case single values, as IN isn't terribly efficient
+                                       // Don't necessarily assume the single key is 0; we don't
+                                       // enforce linear numeric ordering on other arrays here.
+                                       $value = array_values( $value );
+                                       $list .= $field . " = " . $this->addQuotes( $value[0] );
+                               } else {
+                                       $list .= $field . " IN (" . $this->makeList( $value ) . ") ";
+                               }
+                       } elseif ( $value === null ) {
+                               if ( $mode == LIST_AND || $mode == LIST_OR ) {
+                                       $list .= "$field IS ";
+                               } elseif ( $mode == LIST_SET ) {
+                                       $list .= "$field = ";
+                               }
+                               $list .= 'NULL';
+                       } else {
+                               if ( $mode == LIST_AND || $mode == LIST_OR || $mode == LIST_SET ) {
+                                       $list .= "$field = ";
+                               }
+                               $list .= $mode == LIST_NAMES ? $value : $this->addQuotes( $value );
+                       }
                }
+
+               return $list;
        }
 
        /**
@@ -696,7 +871,7 @@ class DatabaseMssql extends DatabaseBase {
         * @param string $field
         * @return int Returns the size of a text field, or -1 for "unlimited"
         */
-       function textFieldSize( $table, $field ) {
+       public function textFieldSize( $table, $field ) {
                $table = $this->tableName( $table );
                $sql = "SELECT CHARACTER_MAXIMUM_LENGTH,DATA_TYPE FROM INFORMATION_SCHEMA.Columns
                        WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$field'";
@@ -719,21 +894,46 @@ class DatabaseMssql extends DatabaseBase {
         * @param bool|int $offset The SQL offset (default false)
         * @return array|string
         */
-       function limitResult( $sql, $limit, $offset = false ) {
+       public function limitResult( $sql, $limit, $offset = false ) {
                if ( $offset === false || $offset == 0 ) {
                        if ( strpos( $sql, "SELECT" ) === false ) {
                                return "TOP {$limit} " . $sql;
                        } else {
-                               return preg_replace( '/\bSELECT(\s*DISTINCT)?\b/Dsi', 'SELECT$1 TOP ' . $limit, $sql, 1 );
+                               return preg_replace( '/\bSELECT(\s+DISTINCT)?\b/Dsi',
+                                       'SELECT$1 TOP ' . $limit, $sql, 1 );
                        }
                } else {
-                       $sql = '
-                               SELECT * FROM (
-                                       SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3 FROM (
-                                               SELECT 1 AS line2, sub1.* FROM (' . $sql . ') AS sub1
-                                       ) as sub2
-                               ) AS sub3
-                               WHERE line3 BETWEEN ' . ( $offset + 1 ) . ' AND ' . ( $offset + $limit );
+                       // This one is fun, we need to pull out the select list as well as any ORDER BY clause
+                       $select = $orderby = array();
+                       $s1 = preg_match( '#SELECT\s+(.+?)\s+FROM#Dis', $sql, $select );
+                       $s2 = preg_match( '#(ORDER BY\s+.+?)(\s*FOR XML .*)?$#Dis', $sql, $orderby );
+                       $overOrder = $postOrder = '';
+                       $first = $offset + 1;
+                       $last = $offset + $limit;
+                       $sub1 = 'sub_' . $this->mSubqueryId;
+                       $sub2 = 'sub_' . ($this->mSubqueryId + 1);
+                       $this->mSubqueryId += 2;
+                       if ( !$s1 ) {
+                               // wat
+                               throw new DBUnexpectedError( $this, "Attempting to LIMIT a non-SELECT query\n" );
+                       }
+                       if ( !$s2 ) {
+                               // no ORDER BY
+                               $overOrder = 'ORDER BY 1';
+                       } else {
+                               if ( !isset( $orderby[2] ) || !$orderby[2] ) {
+                                       // don't need to strip it out if we're using a FOR XML clause
+                                       $sql = str_replace( $orderby[1], '', $sql );
+                               }
+                               $overOrder = $orderby[1];
+                               $postOrder = ' ' . $overOrder;
+                       }
+                       $sql = "SELECT {$select[1]}
+                                       FROM (
+                                               SELECT ROW_NUMBER() OVER({$overOrder}) AS rowNumber, *
+                                               FROM ({$sql}) {$sub1}
+                                       ) {$sub2}
+                                       WHERE rowNumber BETWEEN {$first} AND {$last}{$postOrder}";
 
                        return $sql;
                }
@@ -749,7 +949,7 @@ class DatabaseMssql extends DatabaseBase {
         * @param string $sql
         * @return array|mixed|string
         */
-       function LimitToTopN( $sql ) {
+       public function LimitToTopN( $sql ) {
                // Matches: LIMIT {[offset,] row_count | row_count OFFSET offset}
                $pattern = '/\bLIMIT\s+((([0-9]+)\s*,\s*)?([0-9]+)(\s+OFFSET\s+([0-9]+))?)/i';
                if ( preg_match( $pattern, $sql, $matches ) ) {
@@ -769,16 +969,6 @@ class DatabaseMssql extends DatabaseBase {
                return $sql;
        }
 
-       /**
-        * Timestamp in ISO 8601 format with no timezone: 1986-02-09T20:00:00Z
-        *
-        * @param int $ts Timestamp
-        * @return bool|string The same date in ISO 8601 format with no timezone or false
-        */
-       function timestamp( $ts = 0 ) {
-               return wfTimestamp( TS_ISO_8601, $ts );
-       }
-
        /**
         * @return string Wikitext of a link to the server software's web site
         */
@@ -789,7 +979,7 @@ class DatabaseMssql extends DatabaseBase {
        /**
         * @return string Version information from the database
         */
-       function getServerVersion() {
+       public function getServerVersion() {
                $server_info = sqlsrv_server_info( $this->mConn );
                $version = 'Error';
                if ( isset( $server_info['SQLServerVersion'] ) ) {
@@ -805,11 +995,11 @@ class DatabaseMssql extends DatabaseBase {
         * @param bool $schema
         * @return bool
         */
-       function tableExists( $table, $fname = __METHOD__, $schema = false ) {
+       public function tableExists( $table, $fname = __METHOD__, $schema = false ) {
                $res = sqlsrv_query( $this->mConn, "SELECT * FROM information_schema.tables
                        WHERE table_type='BASE TABLE' AND table_name = '$table'" );
                if ( $res === false ) {
-                       print "Error in tableExists query: " . $this->getErrors();
+                       print "Error in tableExists query: " . $this->lastError();
 
                        return false;
                }
@@ -827,12 +1017,12 @@ class DatabaseMssql extends DatabaseBase {
         * @param string $fname
         * @return bool
         */
-       function fieldExists( $table, $field, $fname = __METHOD__ ) {
+       public function fieldExists( $table, $field, $fname = __METHOD__ ) {
                $table = $this->tableName( $table );
                $res = sqlsrv_query( $this->mConn, "SELECT DATA_TYPE FROM INFORMATION_SCHEMA.Columns
                        WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$field'" );
                if ( $res === false ) {
-                       print "Error in fieldExists query: " . $this->getErrors();
+                       print "Error in fieldExists query: " . $this->lastError();
 
                        return false;
                }
@@ -843,12 +1033,12 @@ class DatabaseMssql extends DatabaseBase {
                }
        }
 
-       function fieldInfo( $table, $field ) {
+       public function fieldInfo( $table, $field ) {
                $table = $this->tableName( $table );
                $res = sqlsrv_query( $this->mConn, "SELECT * FROM INFORMATION_SCHEMA.Columns
                        WHERE TABLE_NAME = '$table' AND COLUMN_NAME = '$field'" );
                if ( $res === false ) {
-                       print "Error in fieldInfo query: " . $this->getErrors();
+                       print "Error in fieldInfo query: " . $this->lastError();
 
                        return false;
                }
@@ -900,150 +1090,74 @@ class DatabaseMssql extends DatabaseBase {
                if ( strlen( $identifier ) > 128 ) {
                        throw new MWException( "The identifier '$identifier' is too long (max. 128)" );
                }
-               if ( ( strpos( $identifier, '[' ) !== false ) || ( strpos( $identifier, ']' ) !== false ) ) {
+               if ( ( strpos( $identifier, '[' ) !== false )
+                       || ( strpos( $identifier, ']' ) !== false )
+               ) {
                        // It may be allowed if you quoted with double quotation marks, but
                        // that would break if QUOTED_IDENTIFIER is OFF
-                       throw new MWException( "You can't use square brackers in the identifier '$identifier'" );
+                       throw new MWException( "Square brackets are not allowed in '$identifier'" );
                }
 
                return "[$identifier]";
        }
 
        /**
-        * Initial setup.
-        * Precondition: This object is connected as the superuser.
-        * Creates the database, schema, user and login.
+        * @param string $s
+        * @return string
         */
-       function initial_setup( $dbName, $newUser, $loginPassword ) {
-               $dbName = $this->escapeIdentifier( $dbName );
-
-               // It is not clear what can be used as a login,
-               // From http://msdn.microsoft.com/en-us/library/ms173463.aspx
-               // a sysname may be the same as an identifier.
-               $newUser = $this->escapeIdentifier( $newUser );
-               $loginPassword = $this->addQuotes( $loginPassword );
-
-               $this->doQuery( "CREATE DATABASE $dbName;" );
-               $this->doQuery( "USE $dbName;" );
-               $this->doQuery( "CREATE SCHEMA $dbName;" );
-               $this->doQuery( "
-                                               CREATE
-                                                       LOGIN $newUser
-                                               WITH
-                                                       PASSWORD=$loginPassword
-                                               ;
-                                       " );
-               $this->doQuery( "
-                                               CREATE
-                                                       USER $newUser
-                                               FOR
-                                                       LOGIN $newUser
-                                               WITH
-                                                       DEFAULT_SCHEMA=$dbName
-                                               ;
-                                       " );
-               $this->doQuery( "
-                                               GRANT
-                                                       BACKUP DATABASE,
-                                                       BACKUP LOG,
-                                                       CREATE DEFAULT,
-                                                       CREATE FUNCTION,
-                                                       CREATE PROCEDURE,
-                                                       CREATE RULE,
-                                                       CREATE TABLE,
-                                                       CREATE VIEW,
-                                                       CREATE FULLTEXT CATALOG
-                                               ON
-                                                       DATABASE::$dbName
-                                               TO $newUser
-                                               ;
-                                       " );
-               $this->doQuery( "
-                                               GRANT
-                                                       CONTROL
-                                               ON
-                                                       SCHEMA::$dbName
-                                               TO $newUser
-                                               ;
-                                       " );
-       }
-
-       function encodeBlob( $b ) {
-               // we can't have zero's and such, this is a simple encoding to make sure we don't barf
-               return base64_encode( $b );
-       }
-
-       function decodeBlob( $b ) {
-               // we can't have zero's and such, this is a simple encoding to make sure we don't barf
-               return base64_decode( $b );
+       public function strencode( $s ) { # Should not be called by us
+               return str_replace( "'", "''", $s );
        }
 
        /**
-        * @param array $tables
-        * @param array $use_index
-        * @param array $join_conds
+        * @param string $s
         * @return string
         */
-       protected function tableNamesWithUseIndexOrJOIN( $tables, $use_index = array(),
-               $join_conds = array()
-       ) {
-               $ret = array();
-               $retJOIN = array();
-               $use_index_safe = is_array( $use_index ) ? $use_index : array();
-               $join_conds_safe = is_array( $join_conds ) ? $join_conds : array();
-               foreach ( $tables as $table ) {
-                       // Is there a JOIN and INDEX clause for this table?
-                       if ( isset( $join_conds_safe[$table] ) && isset( $use_index_safe[$table] ) ) {
-                               $tableClause = $join_conds_safe[$table][0] . ' ' . $this->tableName( $table );
-                               $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$table] ) );
-                               $tableClause .= ' ON (' . $this->makeList( (array)$join_conds_safe[$table][1], LIST_AND ) . ')';
-                               $retJOIN[] = $tableClause;
-                       // Is there an INDEX clause?
-                       } elseif ( isset( $use_index_safe[$table] ) ) {
-                               $tableClause = $this->tableName( $table );
-                               $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$table] ) );
-                               $ret[] = $tableClause;
-                       // Is there a JOIN clause?
-                       } elseif ( isset( $join_conds_safe[$table] ) ) {
-                               $tableClause = $join_conds_safe[$table][0] . ' ' . $this->tableName( $table );
-                               $tableClause .= ' ON (' . $this->makeList( (array)$join_conds_safe[$table][1], LIST_AND ) . ')';
-                               $retJOIN[] = $tableClause;
-                       } else {
-                               $tableClause = $this->tableName( $table );
-                               $ret[] = $tableClause;
-                       }
-               }
-               // We can't separate explicit JOIN clauses with ',', use ' ' for those
-               $straightJoins = !empty( $ret ) ? implode( ',', $ret ) : "";
-               $otherJoins = !empty( $retJOIN ) ? implode( ' ', $retJOIN ) : "";
-
-               // Compile our final table clause
-               return implode( ' ', array( $straightJoins, $otherJoins ) );
-       }
-
-       function strencode( $s ) { # Should not be called by us
-               return str_replace( "'", "''", $s );
-       }
-
-       function addQuotes( $s ) {
-               if ( $s instanceof Blob ) {
-                       return "'" . $s->fetch( $s ) . "'";
+       public function addQuotes( $s ) {
+               if ( $s instanceof MssqlBlob ) {
+                       return $s->fetch();
+               } elseif ( $s instanceof Blob ) {
+                       // this shouldn't really ever be called, but it's here if needed
+                       // (and will quite possibly make the SQL error out)
+                       $blob = new MssqlBlob( $s->fetch() );
+                       return $blob->fetch();
                } else {
+                       if ( is_bool( $s ) ) {
+                               $s = $s ? 1 : 0;
+                       }
                        return parent::addQuotes( $s );
                }
        }
 
+       /**
+        * @param string $s
+        * @return string
+        */
        public function addIdentifierQuotes( $s ) {
                // http://msdn.microsoft.com/en-us/library/aa223962.aspx
                return '[' . $s . ']';
        }
 
+       /**
+        * @param string $name
+        * @return bool
+        */
        public function isQuotedIdentifier( $name ) {
-               return $name[0] == '[' && substr( $name, -1, 1 ) == ']';
+               return strlen( $name ) && $name[0] == '[' && substr( $name, -1, 1 ) == ']';
        }
 
-       function selectDB( $db ) {
-               return ( $this->query( "SET DATABASE $db" ) !== false );
+       /**
+        * @param string $db
+        * @return bool
+        */
+       public function selectDB( $db ) {
+               try {
+                       $this->mDBname = $db;
+                       $this->query( "USE $db" );
+                       return true;
+               } catch ( Exception $e ) {
+                       return false;
+               }
        }
 
        /**
@@ -1051,7 +1165,7 @@ class DatabaseMssql extends DatabaseBase {
         *   an SQL query, valid keys are listed in the function.
         * @return array
         */
-       function makeSelectOptions( $options ) {
+       public function makeSelectOptions( $options ) {
                $tailOpts = '';
                $startOpts = '';
 
@@ -1066,10 +1180,15 @@ class DatabaseMssql extends DatabaseBase {
 
                $tailOpts .= $this->makeOrderBy( $options );
 
-               if ( isset( $noKeyOptions['DISTINCT'] ) && isset( $noKeyOptions['DISTINCTROW'] ) ) {
+               if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) {
                        $startOpts .= 'DISTINCT';
                }
 
+               if ( isset( $noKeyOptions['FOR XML'] ) ) {
+                       // used in group concat field emulation
+                       $tailOpts .= " FOR XML PATH('')";
+               }
+
                // we want this to be compatible with the output of parent::makeSelectOptions()
                return array( $startOpts, '', $tailOpts, '' );
        }
@@ -1078,25 +1197,158 @@ class DatabaseMssql extends DatabaseBase {
         * Get the type of the DBMS, as it appears in $wgDBtype.
         * @return string
         */
-       function getType() {
+       public function getType() {
                return 'mssql';
        }
 
-       function buildConcat( $stringList ) {
+       /**
+        * @param array $stringList
+        * @return string
+        */
+       public function buildConcat( $stringList ) {
                return implode( ' + ', $stringList );
        }
 
+       /**
+        * Build a GROUP_CONCAT or equivalent statement for a query.
+        * MS SQL doesn't have GROUP_CONCAT so we emulate it with other stuff (and boy is it nasty)
+        *
+        * This is useful for combining a field for several rows into a single string.
+        * NULL values will not appear in the output, duplicated values will appear,
+        * and the resulting delimiter-separated values have no defined sort order.
+        * Code using the results may need to use the PHP unique() or sort() methods.
+        *
+        * @param string $delim Glue to bind the results together
+        * @param string|array $table Table name
+        * @param string $field Field name
+        * @param string|array $conds Conditions
+        * @param string|array $join_conds Join conditions
+        * @return String SQL text
+        * @since 1.23
+        */
+       public function buildGroupConcatField( $delim, $table, $field, $conds = '',
+               $join_conds = array()
+       ) {
+               $gcsq = 'gcsq_' . $this->mSubqueryId;
+               $this->mSubqueryId++;
+
+               $delimLen = strlen( $delim );
+               $fld = "{$field} + {$this->addQuotes( $delim )}";
+               $sql = "(SELECT LEFT({$field}, LEN({$field}) - {$delimLen}) FROM ("
+                       . $this->selectSQLText( $table, $fld, $conds, null, array( 'FOR XML' ), $join_conds )
+                       . ") {$gcsq} ({$field}))";
+
+               return $sql;
+       }
+
+       /**
+        * @return string
+        */
        public function getSearchEngine() {
                return "SearchMssql";
        }
 
        /**
-        * Since MSSQL doesn't recognize the infinity keyword, set date manually.
-        * @todo Remove magic date
+        * Returns an associative array for fields that are of type varbinary, binary, or image
+        * $table can be either a raw table name or passed through tableName() first
+        * @param string $table
+        * @return array
+        */
+       private function getBinaryColumns( $table ) {
+               $tableRawArr = explode( '.', preg_replace( '#\[([^\]]*)\]#', '$1', $table ) );
+               $tableRaw = array_pop( $tableRawArr );
+
+               if ( $this->mBinaryColumnCache === null ) {
+                       $this->populateColumnCaches();
+               }
+
+               return isset( $this->mBinaryColumnCache[$tableRaw] )
+                       ? $this->mBinaryColumnCache[$tableRaw]
+                       : array();
+       }
+
+       /**
+        * @param string $table
+        * @return array
+        */
+       private function getBitColumns( $table ) {
+               $tableRawArr = explode( '.', preg_replace( '#\[([^\]]*)\]#', '$1', $table ) );
+               $tableRaw = array_pop( $tableRawArr );
+
+               if ( $this->mBitColumnCache === null ) {
+                       $this->populateColumnCaches();
+               }
+
+               return isset( $this->mBitColumnCache[$tableRaw] )
+                       ? $this->mBitColumnCache[$tableRaw]
+                       : array();
+       }
+
+       /**
+        * @void
+        */
+       private function populateColumnCaches() {
+               $res = $this->select( 'INFORMATION_SCHEMA.COLUMNS', '*',
+                       array(
+                               'TABLE_CATALOG' => $this->mDBname,
+                               'TABLE_SCHEMA' => $this->mSchema,
+                               'DATA_TYPE' => array( 'varbinary', 'binary', 'image', 'bit' )
+                       ) );
+
+               $this->mBinaryColumnCache = array();
+               $this->mBitColumnCache = array();
+               foreach ( $res as $row ) {
+                       if ( $row->DATA_TYPE == 'bit' ) {
+                               $this->mBitColumnCache[$row->TABLE_NAME][$row->COLUMN_NAME] = $row;
+                       } else {
+                               $this->mBinaryColumnCache[$row->TABLE_NAME][$row->COLUMN_NAME] = $row;
+                       }
+               }
+       }
+
+       /**
+        * @param string $name
+        * @param string $format
         * @return string
         */
-       public function getInfinity() {
-               return '3000-01-31 00:00:00.000';
+       function tableName( $name, $format = 'quoted' ) {
+               # Replace reserved words with better ones
+               switch ( $name ) {
+                       case 'user':
+                               return $this->realTableName( 'mwuser', $format );
+                       default:
+                               return $this->realTableName( $name, $format );
+               }
+       }
+
+       /**
+        * call this instead of tableName() in the updater when renaming tables
+        * @param string $name
+        * @param string $format
+        * @return string
+        */
+       function realTableName( $name, $format = 'quoted' ) {
+               return parent::tableName( $name, $format );
+       }
+
+       /**
+        * Called in the installer and updater.
+        * Probably doesn't need to be called anywhere else in the codebase.
+        * @param bool|null $value
+        * @return bool|null
+        */
+       public function prepareStatements( $value = null ) {
+               return wfSetVar( $this->mPrepareStatements, $value );
+       }
+
+       /**
+        * Called in the installer and updater.
+        * Probably doesn't need to be called anywhere else in the codebase.
+        * @param bool|null $value
+        * @return bool|null
+        */
+       public function scrollableCursor( $value = null ) {
+               return wfSetVar( $this->mScrollableCursor, $value );
        }
 } // end DatabaseMssql class
 
@@ -1142,232 +1394,104 @@ class MssqlField implements Field {
        }
 }
 
-/**
- * The MSSQL PHP driver doesn't support sqlsrv_num_rows, so we recall all rows
- * into an array and maintain our own cursor index into that array... This is
- * similar to the way the Oracle driver handles this same issue
- *
- * @ingroup Database
- */
-class MssqlResult {
-       /** @var int */
-       private $mCursor;
-
-       /** @var array */
-       private $mRows;
-
-       /** @var bool|int */
-       private $mNumFields;
-
-       /** @var array|bool */
-       private $mFieldMeta;
+class MssqlBlob extends Blob {
+       public function __construct( $data ) {
+               if ( $data instanceof MssqlBlob ) {
+                       return $data;
+               } elseif ( $data instanceof Blob ) {
+                       $this->mData = $data->fetch();
+               } elseif ( is_array( $data ) && is_object( $data ) ) {
+                       $this->mData = serialize( $data );
+               } else {
+                       $this->mData = $data;
+               }
+       }
 
        /**
-        * @param bool|resource $queryresult
+        * Returns an unquoted hex representation of a binary string
+        * for insertion into varbinary-type fields
+        * @return string
         */
-       public function __construct( $queryresult = false ) {
-               $this->mCursor = 0;
-               $this->mRows = array();
-               $this->mNumFields = sqlsrv_num_fields( $queryresult );
-               $this->mFieldMeta = sqlsrv_field_metadata( $queryresult );
-
-               $rows = sqlsrv_fetch_array( $queryresult, SQLSRV_FETCH_ASSOC );
-
-               foreach ( $rows as $row ) {
-                       if ( $row !== null ) {
-                               foreach ( $row as $k => $v ) {
-                                       if ( is_object( $v ) && method_exists( $v, 'format' ) ) { // DateTime Object
-                                               $row[$k] = $v->format( "Y-m-d\TH:i:s\Z" );
-                                       }
-                               }
-                               $this->mRows[] = $row; // read results into memory, cursors are not supported
-                       }
+       public function fetch() {
+               if ( $this->mData === null ) {
+                       return 'null';
                }
-               $this->mRowCount = count( $this->mRows );
-               sqlsrv_free_stmt( $queryresult );
+
+               $ret = '0x';
+               for ( $i = 0; $i < strlen( $this->mData ); $i++ ) {
+                       $ret .= bin2hex( pack( 'C', ord( $this->mData[$i] ) ) );
+               }
+
+               return $ret;
        }
+}
+
+class MssqlResultWrapper extends ResultWrapper {
+       private $mSeekTo = null;
 
        /**
-        * @param array $array
-        * @param stdClass $obj
-        * @return stdClass
+        * @return stdClass|bool
         */
-       private function array_to_obj( $array, &$obj ) {
-               foreach ( $array as $key => $value ) {
-                       if ( is_array( $value ) ) {
-                               $obj->$key = new stdClass();
-                               $this->array_to_obj( $value, $obj->$key );
-                       } else {
-                               if ( !empty( $key ) ) {
-                                       $obj->$key = $value;
-                               }
-                       }
-               }
+       public function fetchObject() {
+               $res = $this->result;
 
-               return $obj;
-       }
+               if ( $this->mSeekTo !== null ) {
+                       $result = sqlsrv_fetch_object( $res, 'stdClass', array(),
+                               SQLSRV_SCROLL_ABSOLUTE, $this->mSeekTo );
+                       $this->mSeekTo = null;
+               } else {
+                       $result = sqlsrv_fetch_object( $res );
+               }
 
-       public function fetch( $mode = SQLSRV_FETCH_BOTH, $object_class = 'stdClass' ) {
-               if ( $this->mCursor >= $this->mRowCount || $this->mRowCount == 0 ) {
+               // MediaWiki expects us to return boolean false when there are no more rows instead of null
+               if ( $result === null ) {
                        return false;
                }
-               $arrNum = array();
-               if ( $mode == SQLSRV_FETCH_NUMERIC || $mode == SQLSRV_FETCH_BOTH ) {
-                       foreach ( $this->mRows[$this->mCursor] as $value ) {
-                               $arrNum[] = $value;
-                       }
-               }
-               switch ( $mode ) {
-                       case SQLSRV_FETCH_ASSOC:
-                               $ret = $this->mRows[$this->mCursor];
-                               break;
-                       case SQLSRV_FETCH_NUMERIC:
-                               $ret = $arrNum;
-                               break;
-                       case 'OBJECT':
-                               $o = new $object_class;
-                               $ret = $this->array_to_obj( $this->mRows[$this->mCursor], $o );
-                               break;
-                       case SQLSRV_FETCH_BOTH:
-                       default:
-                               $ret = $this->mRows[$this->mCursor] + $arrNum;
-                               break;
-               }
-
-               $this->mCursor++;
 
-               return $ret;
+               return $result;
        }
 
-       public function get( $pos, $fld ) {
-               return $this->mRows[$pos][$fld];
-       }
+       /**
+        * @return array|bool
+        */
+       public function fetchRow() {
+               $res = $this->result;
 
-       public function numrows() {
-               return $this->mRowCount;
-       }
+               if ( $this->mSeekTo !== null ) {
+                       $result = sqlsrv_fetch_array( $res, SQLSRV_FETCH_BOTH,
+                               SQLSRV_SCROLL_ABSOLUTE, $this->mSeekTo );
+                       $this->mSeekTo = null;
+               } else {
+                       $result = sqlsrv_fetch_array( $res );
+               }
 
-       public function seek( $iRow ) {
-               $this->mCursor = min( $iRow, $this->mRowCount );
-       }
+               // MediaWiki expects us to return boolean false when there are no more rows instead of null
+               if ( $result === null ) {
+                       return false;
+               }
 
-       public function numfields() {
-               return $this->mNumFields;
+               return $result;
        }
 
-       public function fieldname( $nr ) {
-               $arrKeys = array_keys( $this->mRows[0] );
+       /**
+        * @param int $row
+        * @return bool
+        */
+       public function seek( $row ) {
+               $res = $this->result;
 
-               return $arrKeys[$nr];
-       }
+               // check bounds
+               $numRows = $this->db->numRows( $res );
+               $row = intval( $row );
 
-       public function fieldtype( $nr ) {
-               $i = 0;
-               $intType = -1;
-               foreach ( $this->mFieldMeta as $meta ) {
-                       if ( $nr == $i ) {
-                               $intType = $meta['Type'];
-                               break;
-                       }
-                       $i++;
-               }
-               // http://msdn.microsoft.com/en-us/library/cc296183.aspx contains type table
-               switch ( $intType ) {
-                       case SQLSRV_SQLTYPE_BIGINT:
-                               $strType = 'bigint';
-                               break;
-                       case SQLSRV_SQLTYPE_BINARY:
-                               $strType = 'binary';
-                               break;
-                       case SQLSRV_SQLTYPE_BIT:
-                               $strType = 'bit';
-                               break;
-                       case SQLSRV_SQLTYPE_CHAR:
-                               $strType = 'char';
-                               break;
-                       case SQLSRV_SQLTYPE_DATETIME:
-                               $strType = 'datetime';
-                               break;
-                       case SQLSRV_SQLTYPE_DECIMAL: // ($precision, $scale)
-                               $strType = 'decimal';
-                               break;
-                       case SQLSRV_SQLTYPE_FLOAT:
-                               $strType = 'float';
-                               break;
-                       case SQLSRV_SQLTYPE_IMAGE:
-                               $strType = 'image';
-                               break;
-                       case SQLSRV_SQLTYPE_INT:
-                               $strType = 'int';
-                               break;
-                       case SQLSRV_SQLTYPE_MONEY:
-                               $strType = 'money';
-                               break;
-                       case SQLSRV_SQLTYPE_NCHAR: // ($charCount):
-                               $strType = 'nchar';
-                               break;
-                       case SQLSRV_SQLTYPE_NUMERIC: // ($precision, $scale):
-                               $strType = 'numeric';
-                               break;
-                       case SQLSRV_SQLTYPE_NVARCHAR: // ($charCount)
-                               $strType = 'nvarchar';
-                               break;
-                       // case SQLSRV_SQLTYPE_NVARCHAR('max'):
-                       //       $strType = 'nvarchar(MAX)';
-                       //       break;
-                       case SQLSRV_SQLTYPE_NTEXT:
-                               $strType = 'ntext';
-                               break;
-                       case SQLSRV_SQLTYPE_REAL:
-                               $strType = 'real';
-                               break;
-                       case SQLSRV_SQLTYPE_SMALLDATETIME:
-                               $strType = 'smalldatetime';
-                               break;
-                       case SQLSRV_SQLTYPE_SMALLINT:
-                               $strType = 'smallint';
-                               break;
-                       case SQLSRV_SQLTYPE_SMALLMONEY:
-                               $strType = 'smallmoney';
-                               break;
-                       case SQLSRV_SQLTYPE_TEXT:
-                               $strType = 'text';
-                               break;
-                       case SQLSRV_SQLTYPE_TIMESTAMP:
-                               $strType = 'timestamp';
-                               break;
-                       case SQLSRV_SQLTYPE_TINYINT:
-                               $strType = 'tinyint';
-                               break;
-                       case SQLSRV_SQLTYPE_UNIQUEIDENTIFIER:
-                               $strType = 'uniqueidentifier';
-                               break;
-                       case SQLSRV_SQLTYPE_UDT:
-                               $strType = 'UDT';
-                               break;
-                       case SQLSRV_SQLTYPE_VARBINARY: // ($byteCount)
-                               $strType = 'varbinary';
-                               break;
-                       // case SQLSRV_SQLTYPE_VARBINARY('max'):
-                       //       $strType = 'varbinary(MAX)';
-                       //       break;
-                       case SQLSRV_SQLTYPE_VARCHAR: // ($charCount)
-                               $strType = 'varchar';
-                               break;
-                       // case SQLSRV_SQLTYPE_VARCHAR('max'):
-                       //       $strType = 'varchar(MAX)';
-                       //       break;
-                       case SQLSRV_SQLTYPE_XML:
-                               $strType = 'xml';
-                               break;
-                       default:
-                               $strType = $intType;
+               if ( $numRows === 0 ) {
+                       return false;
+               } elseif ( $row < 0 || $row > $numRows - 1 ) {
+                       return false;
                }
 
-               return $strType;
-       }
-
-       public function free() {
-               unset( $this->mRows );
+               // Unlike MySQL, the seek actually happens on the next access
+               $this->mSeekTo = $row;
+               return true;
        }
 }
index d304444..f8751a0 100644 (file)
@@ -220,6 +220,7 @@ class DatabaseOracle extends DatabaseBase {
                                'dbname' => isset( $args[3] ) ? $args[3] : false,
                                'flags' => isset( $args[4] ) ? $args[4] : 0,
                                'tablePrefix' => isset( $args[5] ) ? $args[5] : 'get from global',
+                               'schema' => 'get from global',
                                'foreign' => isset( $args[6] ) ? $args[6] : false
                        );
                }
index 2e23d73..0fa29a1 100644 (file)
@@ -57,6 +57,7 @@ class DatabaseSqlite extends DatabaseBase {
                                'dbname' => isset( $args[3] ) ? $args[3] : false,
                                'flags' => isset( $args[4] ) ? $args[4] : 0,
                                'tablePrefix' => isset( $args[5] ) ? $args[5] : 'get from global',
+                               'schema' => 'get from global',
                                'foreign' => isset( $args[6] ) ? $args[6] : false
                        );
                }
index 87687db..36d218a 100644 (file)
@@ -52,7 +52,7 @@ class DBObject {
  */
 class Blob {
        /** @var string */
-       private $mData;
+       protected $mData;
 
        function __construct( $data ) {
                $this->mData = $data;
index 00a4d5e..716ab6e 100644 (file)
@@ -1189,9 +1189,11 @@ abstract class FileBackend {
        }
 
        /**
-        * Preload persistent file stat and property cache into in-process cache.
+        * Preload persistent file stat cache and property cache into in-process cache.
         * This should be used when stat calls will be made on a known list of a many files.
         *
+        * @see FileBackend::getFileStat()
+        *
         * @param array $paths Storage paths
         */
        public function preloadCache( array $paths ) {
@@ -1201,11 +1203,27 @@ abstract class FileBackend {
         * Invalidate any in-process file stat and property cache.
         * If $paths is given, then only the cache for those files will be cleared.
         *
+        * @see FileBackend::getFileStat()
+        *
         * @param array $paths Storage paths (optional)
         */
        public function clearCache( array $paths = null ) {
        }
 
+       /**
+        * Preload file stat information (concurrently if possible) into in-process cache.
+        * This should be used when stat calls will be made on a known list of a many files.
+        *
+        * @see FileBackend::getFileStat()
+        *
+        * @param array $params Parameters include:
+        *   - srcs        : list of source storage paths
+        *   - latest      : use the latest available data
+        * @since 1.23
+        */
+       public function preloadFileStat( array $params ) {
+       }
+
        /**
         * Lock the files at the given storage paths in the backend.
         * This will either lock all the files or none (on failure).
index 81d088e..f00ef65 100644 (file)
@@ -662,6 +662,10 @@ class FileBackendMultiWrite extends FileBackend {
                }
        }
 
+       public function preloadFileStat( array $params ) {
+               $this->backends[$this->masterIndex]->preloadFileStat( $params );
+       }
+
        public function getScopedLocksForOps( array $ops, Status $status ) {
                $realOps = $this->substOpBatchPaths( $ops, $this->backends[$this->masterIndex] );
                $fileOps = $this->backends[$this->masterIndex]->getOperationsInternal( $realOps );
index 50371f8..9a2ebb7 100644 (file)
@@ -1095,9 +1095,16 @@ abstract class FileBackendStore extends FileBackend {
                        $this->clearCache();
                }
 
-               // Load from the persistent file and container caches
-               $this->primeFileCache( $performOps );
-               $this->primeContainerCache( $performOps );
+               // Build the list of paths involved
+               $paths = array();
+               foreach ( $performOps as $op ) {
+                       $paths = array_merge( $paths, $op->storagePathsRead() );
+                       $paths = array_merge( $paths, $op->storagePathsChanged() );
+               }
+               // Load from the persistent container caches
+               $this->primeContainerCache( $paths );
+               // Get the latest stat info for all the files (having locked them)
+               $this->preloadFileStat( array( 'srcs' => $paths, 'latest' => true ) );
 
                // Actually attempt the operation batch...
                $opts = $this->setConcurrencyFlags( $opts );
@@ -1272,6 +1279,63 @@ abstract class FileBackendStore extends FileBackend {
        protected function doClearCache( array $paths = null ) {
        }
 
+       final public function preloadFileStat( array $params ) {
+               $section = new ProfileSection( __METHOD__ . "-{$this->name}" );
+
+               $params['concurrency'] = ( $this->parallelize !== 'off' ) ? $this->concurrency : 1;
+               $stats = $this->doGetFileStatMulti( $params );
+               if ( $stats === null ) {
+                       return; // not supported
+               }
+
+               $latest = !empty( $params['latest'] ); // use latest data?
+               foreach ( $stats as $path => $stat ) {
+                       $path = FileBackend::normalizeStoragePath( $path );
+                       if ( $path === null ) {
+                               continue; // this shouldn't happen
+                       }
+                       if ( is_array( $stat ) ) { // file exists
+                               $stat['latest'] = $latest;
+                               $this->cheapCache->set( $path, 'stat', $stat );
+                               $this->setFileCache( $path, $stat ); // update persistent cache
+                               if ( isset( $stat['sha1'] ) ) { // some backends store SHA-1 as metadata
+                                       $this->cheapCache->set( $path, 'sha1',
+                                               array( 'hash' => $stat['sha1'], 'latest' => $latest ) );
+                               }
+                               if ( isset( $stat['xattr'] ) ) { // some backends store headers/metadata
+                                       $stat['xattr'] = self::normalizeXAttributes( $stat['xattr'] );
+                                       $this->cheapCache->set( $path, 'xattr',
+                                               array( 'map' => $stat['xattr'], 'latest' => $latest ) );
+                               }
+                       } elseif ( $stat === false ) { // file does not exist
+                               $this->cheapCache->set( $path, 'stat',
+                                       $latest ? 'NOT_EXIST_LATEST' : 'NOT_EXIST' );
+                               $this->cheapCache->set( $path, 'xattr',
+                                       array( 'map' => false, 'latest' => $latest ) );
+                               $this->cheapCache->set( $path, 'sha1',
+                                       array( 'hash' => false, 'latest' => $latest ) );
+                               wfDebug( __METHOD__ . ": File $path does not exist.\n" );
+                       } else { // an error occurred
+                               wfDebug( __METHOD__ . ": Could not stat file $path.\n" );
+                       }
+               }
+       }
+
+       /**
+        * Get file stat information (concurrently if possible) for several files
+        *
+        * @see FileBackend::getFileStat()
+        *
+        * @param array $params Parameters include:
+        *   - srcs        : list of source storage paths
+        *   - latest      : use the latest available data
+        * @return array|null Map of storage paths to array|bool|null (returns null if not supported)
+        * @since 1.23
+        */
+       protected function doGetFileStatMulti( array $params ) {
+               return null; // not supported
+       }
+
        /**
         * Is this a key/value store where directories are just virtual?
         * Virtual directories exists in so much as files exists that are
@@ -1528,7 +1592,7 @@ abstract class FileBackendStore extends FileBackend {
 
        /**
         * Do a batch lookup from cache for container stats for all containers
-        * used in a list of container names, storage paths, or FileOp objects.
+        * used in a list of container names or storage paths objects.
         * This loads the persistent cache values into the process cache.
         *
         * @param array $items
@@ -1540,10 +1604,7 @@ abstract class FileBackendStore extends FileBackend {
                $contNames = array(); // (cache key => resolved container name)
                // Get all the paths/containers from the items...
                foreach ( $items as $item ) {
-                       if ( $item instanceof FileOp ) {
-                               $paths = array_merge( $paths, $item->storagePathsRead() );
-                               $paths = array_merge( $paths, $item->storagePathsChanged() );
-                       } elseif ( self::isStoragePath( $item ) ) {
+                       if ( self::isStoragePath( $item ) ) {
                                $paths[] = $item;
                        } elseif ( is_string( $item ) ) { // full container name
                                $contNames[$this->containerCacheKey( $item )] = $item;
@@ -1629,7 +1690,7 @@ abstract class FileBackendStore extends FileBackend {
         * used in a list of storage paths or FileOp objects.
         * This loads the persistent cache values into the process cache.
         *
-        * @param array $items List of storage paths or FileOps
+        * @param array $items List of storage paths
         */
        final protected function primeFileCache( array $items ) {
                $section = new ProfileSection( __METHOD__ . "-{$this->name}" );
@@ -1638,10 +1699,7 @@ abstract class FileBackendStore extends FileBackend {
                $pathNames = array(); // (cache key => storage path)
                // Get all the paths/containers from the items...
                foreach ( $items as $item ) {
-                       if ( $item instanceof FileOp ) {
-                               $paths = array_merge( $paths, $item->storagePathsRead() );
-                               $paths = array_merge( $paths, $item->storagePathsChanged() );
-                       } elseif ( self::isStoragePath( $item ) ) {
+                       if ( self::isStoragePath( $item ) ) {
                                $paths[] = FileBackend::normalizeStoragePath( $item );
                        }
                }
index caf15aa..dea1666 100644 (file)
@@ -617,59 +617,10 @@ class SwiftFileBackend extends FileBackendStore {
        }
 
        protected function doGetFileStat( array $params ) {
-               list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $params['src'] );
-               if ( $srcRel === null ) {
-                       return false; // invalid storage path
-               }
-
-               $auth = $this->getAuthentication();
-               if ( !$auth ) {
-                       return null;
-               }
+               $params['concurrency'] = 1;
+               $stats = $this->doGetFileStatMulti( array( 'srcs' => array( $params['src'] ) ) + $params );
 
-               // (a) Check the container
-               $cstat = $this->getContainerStat( $srcCont, true );
-               if ( $cstat === false ) {
-                       return false; // ok, nothing to do
-               } elseif ( !is_array( $cstat ) ) {
-                       return null;
-               }
-
-               // (b) Check the file
-               list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
-                       'method' => 'HEAD',
-                       'url' => $this->storageUrl( $auth, $srcCont, $srcRel ),
-                       'headers' => $this->authTokenHeaders( $auth ) + $this->headersFromParams( $params )
-               ) );
-               if ( $rcode === 200 || $rcode === 204 ) {
-                       // Update the object if it is missing some headers
-                       $rhdrs = $this->addMissingMetadata( $rhdrs, $params['src'] );
-                       // Fetch all of the custom metadata headers
-                       $metadata = array();
-                       foreach ( $rhdrs as $name => $value ) {
-                               if ( strpos( $name, 'x-object-meta-' ) === 0 ) {
-                                       $metadata[substr( $name, strlen( 'x-object-meta-' ) )] = $value;
-                               }
-                       }
-                       // Fetch all of the custom raw HTTP headers
-                       $headers = $this->sanitizeHdrs( array( 'headers' => $rhdrs ) );
-                       $stat = array(
-                               // Convert various random Swift dates to TS_MW
-                               'mtime' => $this->convertSwiftDate( $rhdrs['last-modified'], TS_MW ),
-                               // Empty objects actually return no content-length header in Ceph
-                               'size' => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
-                               'sha1' => $rhdrs['x-object-meta-sha1base36'],
-                               'md5' => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
-                               'xattr' => array( 'metadata' => $metadata, 'headers' => $headers )
-                       );
-               } elseif ( $rcode === 404 ) {
-                       $stat = false;
-               } else {
-                       $stat = null;
-                       $this->onError( null, __METHOD__, $params, $rerr, $rcode, $rdesc );
-               }
-
-               return $stat;
+               return reset( $stats );
        }
 
        /**
@@ -704,7 +655,7 @@ class SwiftFileBackend extends FileBackendStore {
                        return $objHdrs; // nothing to do
                }
 
-               $section = new ProfileSection( __METHOD__ );
+               $section = new ProfileSection( __METHOD__ . '-' . $this->name );
                trigger_error( "$path was not stored with SHA-1 metadata.", E_USER_WARNING );
 
                $auth = $this->getAuthentication();
@@ -975,9 +926,10 @@ class SwiftFileBackend extends FileBackendStore {
                                }
                                $stat = array(
                                        // Convert various random Swift dates to TS_MW
-                                       'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
-                                       'size' => (int)$object->bytes,
-                                       'md5' => ctype_xdigit( $object->hash ) ? $object->hash : null,
+                                       'mtime'  => $this->convertSwiftDate( $object->last_modified, TS_MW ),
+                                       'size'   => (int)$object->bytes,
+                                       // Note: manifiest ETags are not an MD5 of the file
+                                       'md5'    => ctype_xdigit( $object->hash ) ? $object->hash : null,
                                        'latest' => false // eventually consistent
                                );
                                $names[] = array( $object->name, $stat );
@@ -1306,6 +1258,8 @@ class SwiftFileBackend extends FileBackendStore {
         * @return array|bool|null False on 404, null on failure
         */
        protected function getContainerStat( $container, $bypassCache = false ) {
+               $section = new ProfileSection( __METHOD__ . '-' . $this->name );
+
                if ( $bypassCache ) { // purge cache
                        $this->containerStatCache->clear( $container );
                } elseif ( !$this->containerStatCache->has( $container, 'stat' ) ) {
@@ -1317,11 +1271,13 @@ class SwiftFileBackend extends FileBackendStore {
                                return null;
                        }
 
+                       wfProfileIn( __METHOD__. "-{$this->name}-miss" );
                        list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $this->http->run( array(
                                'method' => 'HEAD',
                                'url' => $this->storageUrl( $auth, $container ),
                                'headers' => $this->authTokenHeaders( $auth )
                        ) );
+                       wfProfileOut( __METHOD__ . "-{$this->name}-miss" );
 
                        if ( $rcode === 204 ) {
                                $stat = array(
@@ -1332,6 +1288,7 @@ class SwiftFileBackend extends FileBackendStore {
                                        return $stat;
                                } else {
                                        $this->containerStatCache->set( $container, 'stat', $stat ); // cache it
+                                       $this->setContainerCache( $container, $stat ); // update persistent cache
                                }
                        } elseif ( $rcode === 404 ) {
                                return false;
@@ -1496,6 +1453,82 @@ class SwiftFileBackend extends FileBackendStore {
                }
        }
 
+       protected function doGetFileStatMulti( array $params ) {
+               $stats = array();
+
+               $auth = $this->getAuthentication();
+
+               $reqs = array();
+               foreach ( $params['srcs'] as $path ) {
+                       list( $srcCont, $srcRel ) = $this->resolveStoragePathReal( $path );
+                       if ( $srcRel === null ) {
+                               $stats[$path] = false;
+                               continue; // invalid storage path
+                       } elseif ( !$auth ) {
+                               $stats[$path] = null;
+                               continue;
+                       }
+
+                       // (a) Check the container
+                       $cstat = $this->getContainerStat( $srcCont, true );
+                       if ( $cstat === false ) {
+                               $stats[$path] = false;
+                               continue; // ok, nothing to do
+                       } elseif ( !is_array( $cstat ) ) {
+                               $stats[$path] = null;
+                               continue;
+                       }
+
+                       $reqs[$path] = array(
+                               'method'  => 'HEAD',
+                               'url'     => $this->storageUrl( $auth, $srcCont, $srcRel ),
+                               'headers' => $this->authTokenHeaders( $auth ) + $this->headersFromParams( $params )
+                       );
+               }
+
+               $opts = array( 'maxConnsPerHost' => $params['concurrency'] );
+               $reqs = $this->http->runMulti( $reqs, $opts );
+
+               foreach ( $params['srcs'] as $path ) {
+                       if ( array_key_exists( $path, $stats ) ) {
+                               continue; // some sort of failure above
+                       }
+                       // (b) Check the file
+                       list( $rcode, $rdesc, $rhdrs, $rbody, $rerr ) = $reqs[$path]['response'];
+                       if ( $rcode === 200 || $rcode === 204 ) {
+                               // Update the object if it is missing some headers
+                               $rhdrs = $this->addMissingMetadata( $rhdrs, $path );
+                               // Fetch all of the custom metadata headers
+                               $metadata = array();
+                               foreach ( $rhdrs as $name => $value ) {
+                                       if ( strpos( $name, 'x-object-meta-' ) === 0 ) {
+                                               $metadata[substr( $name, strlen( 'x-object-meta-' ) )] = $value;
+                                       }
+                               }
+                               // Fetch all of the custom raw HTTP headers
+                               $headers = $this->sanitizeHdrs( array( 'headers' => $rhdrs ) );
+                               $stat = array(
+                                       // Convert various random Swift dates to TS_MW
+                                       'mtime' => $this->convertSwiftDate( $rhdrs['last-modified'], TS_MW ),
+                                       // Empty objects actually return no content-length header in Ceph
+                                       'size'  => isset( $rhdrs['content-length'] ) ? (int)$rhdrs['content-length'] : 0,
+                                       'sha1'  => $rhdrs[ 'x-object-meta-sha1base36'],
+                                       // Note: manifiest ETags are not an MD5 of the file
+                                       'md5'   => ctype_xdigit( $rhdrs['etag'] ) ? $rhdrs['etag'] : null,
+                                       'xattr' => array( 'metadata' => $metadata, 'headers' => $headers )
+                               );
+                       } elseif ( $rcode === 404 ) {
+                               $stat = false;
+                       } else {
+                               $stat = null;
+                               $this->onError( null, __METHOD__, $params, $rerr, $rcode, $rdesc );
+                       }
+                       $stats[$path] = $stat;
+               }
+
+               return $stats;
+       }
+
        /**
         * @return array|null Credential map
         */
index 422fa8a..3e2a09e 100644 (file)
  *    'default'             -- default value when the form is displayed
  *    'id'                  -- HTML id attribute
  *    'cssclass'            -- CSS class
- *    'options'             -- varies according to the specific object.
+ *    'options'             -- associative array mapping labels to values.
+ *                             Some field types support multi-level arrays.
+ *    'options-messages'    -- associative array mapping message keys to values.
+ *                             Some field types support multi-level arrays.
+ *    'options-message'     -- message key to be parsed to extract the list of
+ *                             options (like 'ipbreason-dropdown').
  *    'label-message'       -- message key for a message to use as the label.
  *                             can be an array of msg key and then parameters to
  *                             the message.
@@ -306,15 +311,22 @@ class HTMLForm extends ContextSource {
        }
 
        /**
-        * Initialise a new Object for the field
+        * Get the HTMLFormField subclass for this descriptor.
+        *
+        * The descriptor can be passed either 'class' which is the name of
+        * a HTMLFormField subclass, or a shorter 'type' which is an alias.
+        * This makes sure the 'class' is always set, and also is returned by
+        * this function for ease.
         *
-        * @param $fieldname string
-        * @param string $descriptor input Descriptor, as described above
+        * @since 1.23
+        *
+        * @param string $fieldname Name of the field
+        * @param array $descriptor Input Descriptor, as described above
         *
         * @throws MWException
-        * @return HTMLFormField subclass
+        * @return string Name of a HTMLFormField subclass
         */
-       static function loadInputFromParameters( $fieldname, $descriptor ) {
+       public static function getClassFromDescriptor( $fieldname, &$descriptor ) {
                if ( isset( $descriptor['class'] ) ) {
                        $class = $descriptor['class'];
                } elseif ( isset( $descriptor['type'] ) ) {
@@ -325,8 +337,22 @@ class HTMLForm extends ContextSource {
                }
 
                if ( !$class ) {
-                       throw new MWException( "Descriptor with no class: " . print_r( $descriptor, true ) );
+                       throw new MWException( "Descriptor with no class for $fieldname: " . print_r( $descriptor, true ) );
                }
+               return $class;
+       }
+
+       /**
+        * Initialise a new Object for the field
+        *
+        * @param string $fieldname Name of the field
+        * @param array $descriptor Input Descriptor, as described above
+        *
+        * @throws MWException
+        * @return HTMLFormField subclass
+        */
+       public static function loadInputFromParameters( $fieldname, $descriptor ) {
+               $class = self::getClassFromDescriptor( $fieldname, $descriptor );
 
                $descriptor['fieldname'] = $fieldname;
 
index dcdba1e..27d9594 100644 (file)
@@ -14,6 +14,8 @@ abstract class HTMLFormField {
        protected $mID;
        protected $mClass = '';
        protected $mDefault;
+       protected $mOptions = false;
+       protected $mOptionsLabelsNotFromMessage = false;
 
        /**
         * @var bool If true will generate an empty div element with no label
@@ -508,6 +510,88 @@ abstract class HTMLFormField {
                return $ret;
        }
 
+       /**
+        * Given an array of msg-key => value mappings, returns an array with keys
+        * being the message texts. It also forces values to strings.
+        *
+        * @param array $options
+        * @return array
+        */
+       private function lookupOptionsKeys( $options ) {
+               $ret = array();
+               foreach ( $options as $key => $value ) {
+                       $key = $this->msg( $key )->plain();
+                       $ret[$key] = is_array( $value )
+                               ? $this->lookupOptionsKeys($field, $value)
+                               : strval( $value );
+               }
+               return $ret;
+       }
+
+       /**
+        * Recursively forces values in an array to strings, because issues arise
+        * with integer 0 as a value.
+        *
+        * @param array $array
+        * @return array
+        */
+       static function forceToStringRecursive( $array ) {
+               if ( is_array( $array ) ) {
+                       return array_map( array( __CLASS__, 'forceToStringRecursive' ), $array );
+               } else {
+                       return strval( $array );
+               }
+       }
+
+       /**
+        * Fetch the array of options from the field's parameters. In order, this
+        * checks 'options-messages', 'options', then 'options-message'.
+        *
+        * @return array|null Options array
+        */
+       public function getOptions() {
+               if ( $this->mOptions === false ) {
+                       if ( array_key_exists( 'options-messages', $this->mParams ) ) {
+                               $this->mOptions = $this->lookupOptionsKeys( $this->mParams['options-messages'] );
+                       } elseif ( array_key_exists( 'options', $this->mParams ) ) {
+                               $this->mOptionsLabelsNotFromMessage = true;
+                               $this->mOptions = self::forceToStringRecursive( $this->mParams['options'] );
+                       } elseif ( array_key_exists( 'options-message', $this->mParams ) ) {
+                               /** @todo This is copied from Xml::listDropDown(), deprecate/avoid duplication? */
+                               $message = $this->msg( $this->mParams['options-message'] )->plain();
+
+                               $optgroup = false;
+                               $this->mOptions = array();
+                               foreach ( explode( "\n", $message ) as $option ) {
+                                       $value = trim( $option );
+                                       if ( $value == '' ) {
+                                               continue;
+                                       } elseif ( substr( $value, 0, 1 ) == '*' && substr( $value, 1, 1 ) != '*' ) {
+                                               # A new group is starting...
+                                               $value = trim( substr( $value, 1 ) );
+                                               $optgroup = $value;
+                                       } elseif ( substr( $value, 0, 2 ) == '**' ) {
+                                               # groupmember
+                                               $opt = trim( substr( $value, 2 ) );
+                                               if ( $optgroup === false ) {
+                                                       $this->mOptions[$opt] = $opt;
+                                               } else {
+                                                       $this->mOptions[$optgroup][$opt] = $opt;
+                                               }
+                                       } else {
+                                               # groupless reason list
+                                               $optgroup = false;
+                                               $this->mOptions[$option] = $option;
+                                       }
+                               }
+                       } else {
+                               $this->mOptions = null;
+                       }
+               }
+
+               return $this->mOptions;
+       }
+
        /**
         * flatten an array of options to a single array, for instance,
         * a set of "<options>" inside "<optgroups>".
index 09576d4..2944c24 100644 (file)
@@ -17,7 +17,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
 
                # If all options are valid, array_intersect of the valid options
                # and the provided options will return the provided options.
-               $validOptions = HTMLFormField::flattenOptions( $this->mParams['options'] );
+               $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
 
                $validValues = array_intersect( $value, $validOptions );
                if ( count( $validValues ) == count( $value ) ) {
@@ -28,7 +28,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
        }
 
        function getInputHTML( $value ) {
-               $html = $this->formatOptions( $this->mParams['options'], $value );
+               $html = $this->formatOptions( $this->getOptions(), $value );
 
                return $html;
        }
@@ -37,6 +37,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                $html = '';
 
                $attribs = $this->getAttributes( array( 'disabled', 'tabindex' ) );
+               $elementFunc = array( 'Html', $this->mOptionsLabelsNotFromMessage ? 'rawElement' : 'element' );
 
                foreach ( $options as $label => $info ) {
                        if ( is_array( $info ) ) {
@@ -50,7 +51,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
                                        in_array( $info, $value, true ),
                                        $attribs + $thisAttribs
                                );
-                               $checkbox .= '&#160;' . Html::rawElement(
+                               $checkbox .= '&#160;' . call_user_func( $elementFunc,
                                        'label',
                                        array( 'for' => "{$this->mID}-$info" ),
                                        $label
@@ -102,7 +103,7 @@ class HTMLMultiSelectField extends HTMLFormField implements HTMLNestedFilterable
        }
 
        function filterDataForSubmit( $data ) {
-               $options = HTMLFormField::flattenOptions( $this->mParams['options'] );
+               $options = HTMLFormField::flattenOptions( $this->getOptions() );
 
                $res = array();
                foreach ( $options as $opt ) {
index f206ed6..aa0ea5d 100644 (file)
@@ -15,7 +15,7 @@ class HTMLRadioField extends HTMLFormField {
                        return false;
                }
 
-               $validOptions = HTMLFormField::flattenOptions( $this->mParams['options'] );
+               $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
 
                if ( in_array( $value, $validOptions ) ) {
                        return true;
@@ -33,7 +33,7 @@ class HTMLRadioField extends HTMLFormField {
         * @return String
         */
        function getInputHTML( $value ) {
-               $html = $this->formatOptions( $this->mParams['options'], $value );
+               $html = $this->formatOptions( $this->getOptions(), $value );
 
                return $html;
        }
@@ -42,6 +42,7 @@ class HTMLRadioField extends HTMLFormField {
                $html = '';
 
                $attribs = $this->getAttributes( array( 'disabled', 'tabindex' ) );
+               $elementFunc = array( 'Html', $this->mOptionsLabelsNotFromMessage ? 'rawElement' : 'element' );
 
                # @todo Should this produce an unordered list perhaps?
                foreach ( $options as $label => $info ) {
@@ -51,7 +52,7 @@ class HTMLRadioField extends HTMLFormField {
                        } else {
                                $id = Sanitizer::escapeId( $this->mID . "-$info" );
                                $radio = Xml::radio( $this->mName, $info, $info == $value, $attribs + array( 'id' => $id ) );
-                               $radio .= '&#160;' . Html::rawElement( 'label', array( 'for' => $id ), $label );
+                               $radio .= '&#160;' . call_user_func( $elementFunc, 'label', array( 'for' => $id ), $label );
 
                                $html .= ' ' . Html::rawElement(
                                        'div',
index 044670d..2e91a23 100644 (file)
@@ -19,63 +19,17 @@ class HTMLSelectAndOtherField extends HTMLSelectField {
                        $params['other'] = null;
                }
 
-               if ( array_key_exists( 'options', $params ) ) {
-                       # Options array already specified
-               } elseif ( array_key_exists( 'options-message', $params ) ) {
-                       # Generate options array from a system message
-                       $params['options'] =
-                               self::parseMessage( wfMessage( $params['options-message'] )->inContentLanguage()->plain(),
-                                       $params['other'] );
-               } else {
-                       # Sulk
-                       throw new MWException( 'HTMLSelectAndOtherField called without any options' );
-               }
-               $this->mFlatOptions = self::flattenOptions( $params['options'] );
-
                parent::__construct( $params );
-       }
 
-       /**
-        * Build a drop-down box from a textual list.
-        *
-        * @param string $string message text
-        * @param string $otherName name of "other reason" option
-        *
-        * @return Array
-        * @todo This is copied from Xml::listDropDown(), deprecate/avoid duplication?
-        */
-       public static function parseMessage( $string, $otherName = null ) {
-               if ( $otherName === null ) {
-                       $otherName = wfMessage( 'htmlform-selectorother-other' )->plain();
+               if ( $this->getOptions() === null ) {
+                       # Sulk
+                       throw new MWException( 'HTMLSelectAndOtherField called without any options' );
                }
-
-               $optgroup = false;
-               $options = array( $otherName => 'other' );
-
-               foreach ( explode( "\n", $string ) as $option ) {
-                       $value = trim( $option );
-                       if ( $value == '' ) {
-                               continue;
-                       } elseif ( substr( $value, 0, 1 ) == '*' && substr( $value, 1, 1 ) != '*' ) {
-                               # A new group is starting...
-                               $value = trim( substr( $value, 1 ) );
-                               $optgroup = $value;
-                       } elseif ( substr( $value, 0, 2 ) == '**' ) {
-                               # groupmember
-                               $opt = trim( substr( $value, 2 ) );
-                               if ( $optgroup === false ) {
-                                       $options[$opt] = $opt;
-                               } else {
-                                       $options[$optgroup][$opt] = $opt;
-                               }
-                       } else {
-                               # groupless reason list
-                               $optgroup = false;
-                               $options[$option] = $option;
-                       }
+               if ( !in_array( 'other', $this->mOptions, true ) ) {
+                       $this->mOptions[$params['other']] = 'other';
                }
+               $this->mFlatOptions = self::flattenOptions( $this->getOptions() );
 
-               return $options;
        }
 
        function getInputHTML( $value ) {
index 9d719f6..0437480 100644 (file)
@@ -11,7 +11,7 @@ class HTMLSelectField extends HTMLFormField {
                        return $p;
                }
 
-               $validOptions = HTMLFormField::flattenOptions( $this->mParams['options'] );
+               $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
 
                if ( in_array( $value, $validOptions ) ) {
                        return true;
@@ -23,16 +23,6 @@ class HTMLSelectField extends HTMLFormField {
        function getInputHTML( $value ) {
                $select = new XmlSelect( $this->mName, $this->mID, strval( $value ) );
 
-               # If one of the options' 'name' is int(0), it is automatically selected.
-               # because PHP sucks and thinks int(0) == 'some string'.
-               # Working around this by forcing all of them to strings.
-               foreach ( $this->mParams['options'] as &$opt ) {
-                       if ( is_int( $opt ) ) {
-                               $opt = strval( $opt );
-                       }
-               }
-               unset( $opt ); # PHP keeps $opt around as a reference, which is a bit scary
-
                if ( !empty( $this->mParams['disabled'] ) ) {
                        $select->setAttribute( 'disabled', 'disabled' );
                }
@@ -45,7 +35,7 @@ class HTMLSelectField extends HTMLFormField {
                        $select->setAttribute( 'class', $this->mClass );
                }
 
-               $select->addOptions( $this->mParams['options'] );
+               $select->addOptions( $this->getOptions() );
 
                return $select->getHTML();
        }
index 08be435..045b8df 100644 (file)
@@ -5,38 +5,29 @@
  */
 class HTMLSelectOrOtherField extends HTMLTextField {
        function __construct( $params ) {
-               if ( !in_array( 'other', $params['options'], true ) ) {
+               parent::__construct( $params );
+               $this->getOptions();
+               if ( !in_array( 'other', $this->mOptions, true ) ) {
                        $msg =
                                isset( $params['other'] )
                                        ? $params['other']
                                        : wfMessage( 'htmlform-selectorother-other' )->text();
-                       $params['options'][$msg] = 'other';
+                       $this->mOptions[$msg] = 'other';
                }
 
-               parent::__construct( $params );
-       }
-
-       static function forceToStringRecursive( $array ) {
-               if ( is_array( $array ) ) {
-                       return array_map( array( __CLASS__, 'forceToStringRecursive' ), $array );
-               } else {
-                       return strval( $array );
-               }
        }
 
        function getInputHTML( $value ) {
                $valInSelect = false;
 
                if ( $value !== false ) {
-                       $valInSelect = in_array( $value, HTMLFormField::flattenOptions( $this->mParams['options'] ) );
+                       $valInSelect = in_array( $value, HTMLFormField::flattenOptions( $this->getOptions() ) );
                }
 
                $selected = $valInSelect ? $value : 'other';
 
-               $opts = self::forceToStringRecursive( $this->mParams['options'] );
-
                $select = new XmlSelect( $this->mName, $this->mID, $selected );
-               $select->addOptions( $opts );
+               $select->addOptions( $this->getOptions() );
 
                $select->setAttribute( 'class', 'mw-htmlform-select-or-other' );
 
index 3b3205f..9f39a87 100644 (file)
@@ -241,6 +241,7 @@ Consider putting the database somewhere else altogether, for example in <code>/v
        'config-type-postgres'            => 'PostgreSQL',
        'config-type-sqlite'              => 'SQLite',
        'config-type-oracle'              => 'Oracle',
+       'config-type-mssql'               => 'Microsoft SQL Server',
        'config-support-info'             => 'MediaWiki supports the following database systems:
 
 $1
@@ -250,10 +251,12 @@ If you do not see the database system you are trying to use listed below, then f
        'config-dbsupport-postgres'       => '* [{{int:version-db-postgres-url}} PostgreSQL] is a popular open source database system as an alternative to MySQL. There may be some minor outstanding bugs, and it is not recommended for use in a production environment. ([http://www.php.net/manual/en/pgsql.installation.php How to compile PHP with PostgreSQL support])',
        'config-dbsupport-sqlite'         => '* [{{int:version-db-sqlite-url}} SQLite] is a lightweight database system that is very well supported. ([http://www.php.net/manual/en/pdo.installation.php How to compile PHP with SQLite support], uses PDO)',
        'config-dbsupport-oracle'         => '* [{{int:version-db-oracle-url}} Oracle] is a commercial enterprise database. ([http://www.php.net/manual/en/oci8.installation.php How to compile PHP with OCI8 support])',
+       'config-dbsupport-mssql'          => '* [{{int:version-db-mssql-url}} Microsoft SQL Server] is a commercial enterprise database for Windows. ([http://www.php.net/manual/en/sqlsrv.installation.php How to compile PHP with SQLSRV support])',
        'config-header-mysql'             => 'MySQL settings',
        'config-header-postgres'          => 'PostgreSQL settings',
        'config-header-sqlite'            => 'SQLite settings',
        'config-header-oracle'            => 'Oracle settings',
+       'config-header-mssql'             => 'Microsoft SQL Server settings',
        'config-invalid-db-type'          => 'Invalid database type',
        'config-missing-db-name'          => 'You must enter a value for "Database name"',
        'config-missing-db-host'          => 'You must enter a value for "Database host"',
@@ -272,6 +275,7 @@ Use only ASCII letters (a-z, A-Z), numbers (0-9) and underscores (_).',
        'config-db-sys-create-oracle' => 'Installer only supports using a SYSDBA account for creating a new account.',
        'config-db-sys-user-exists-oracle' => 'User account "$1" already exists. SYSDBA can only be used for creating of a new account!',
        'config-postgres-old'             => 'PostgreSQL $1 or later is required. You have $2.',
+       'config-mssql-old'                => 'Microsoft SQL Server $1 or later is required. You have $2.',
        'config-sqlite-name-help'         => 'Choose a name that identifies your wiki.
 Do not use spaces or hyphens.
 This will be used for the SQLite data file name.',
@@ -352,6 +356,13 @@ This is more efficient than MySQL's UTF-8 mode, and allows you to use the full r
 
 In <strong>UTF-8 mode</strong>, MySQL will know what character set your data is in, and can present and convert it appropriately, but it will not let you store characters above the [//en.wikipedia.org/wiki/Mapping_of_Unicode_character_planes Basic Multilingual Plane].",
 
+       'config-mssql-auth'               => 'Authentication type:',
+       'config-mssql-install-auth'       => 'Select the authentication type that will be used to connect to the database during the installation process.
+If you select "Windows Authentication", the credentials of whatever user the webserver is running as will be used.',
+       'config-mssql-web-auth'           => 'Select the authentication type that the web server will use to connect to the database server, during ordinary operation of the wiki.
+If you select "Windows Authentication", the credentials of whatever user the webserver is running as will be used.',
+       'config-mssql-sqlauth'            => 'SQL Server Authentication',
+       'config-mssql-windowsauth'        => 'Windows Authentication',
        'config-site-name'                => 'Name of wiki:',
        'config-site-name-help'           => "This will appear in the title bar of the browser and in various other places.",
        'config-site-name-blank'          => 'Enter a site name.',
@@ -705,6 +716,8 @@ Used in help box.',
        'config-type-postgres' => '{{optional}}',
        'config-type-sqlite' => '{{optional}}',
        'config-type-oracle' => '{{optional}}',
+       'config-type-mssql' => '{{optional}}',
+       'config-header-mssql' => 'Used as a section heading on the installer form, inside of a fieldset',
        'config-support-info' => 'Parameters:
 * $1 - a list of DBMSs that MediaWiki supports, composed with config-dbsupport-* messages.',
        'config-support-mysql' => 'Parameters:
@@ -723,6 +736,8 @@ Used in help box.',
 * $1 - database server name
 See also:
 * {{msg-mw|Config-db-host-oracle-help}}',
+       'config-support-mssql' => 'Parameters:
+* $1 - a link to the Microsoft SQL Server home page, the anchor text of which is "Microsoft SQL Server".',
        'config-invalid-db-name' => 'Used as error message. Parameters:
 * $1 - database name
 See also:
@@ -740,6 +755,9 @@ If you\'re translating this message to a right-to-left language, consider writin
        'config-postgres-old' => 'Used as error message. Used as warning. Parameters:
 * $1 - minimum version
 * $2 - the version of PostgreSQL that has been installed',
+       'config-mssql-old' => 'Used as an error message. Parameters:
+* $1 - minimum version
+* $2 - the version of Microsoft SQL Server that has been installed',
        'config-sqlite-parent-unwritable-group' => 'Used as SQLite error message. Parameters:
 * $1 - data directory
 * $2 - "dirname" part of $1
@@ -762,6 +780,11 @@ See also:
 * $1 - filename',
        'config-sqlite-cant-create-db' => 'Used as SQLite error message. Parameters:
 * $1 - filename',
+       'config-mssql-auth' => 'radio button label',
+       'config-mssql-install-auth' => 'Used as the help text for the "Authentication type" radio button when typing in database settings for installation',
+       'config-mssql-web-auth' => 'Used as the help text for the "Authentication type" radio button when typing in database settings for normal wiki usage',
+       'config-mssql-sqlauth' => 'Radio button',
+       'config-mssql-windowsauth' => 'Radio button. The official term is "Integrated Windows Authentication" but Microsoft itself uses "Windows Authentication" elsewhere in Microsoft SQL Server as a synonym.',
        'config-can-upgrade' => 'Parameters:
 * $1 - Version or Revision indicator.',
        'config-upgrade-done' => 'Used as success message. Parameters:
@@ -4894,7 +4917,7 @@ Instalación anulada.',
        'config-using531' => 'MediaWiki no puede utilizarse con PHP $1 debido a un error con los parámetros de referencia para <code>__call()</code> .
 Actualice el sistema a PHP 5.3.2 o superior, o vuelva a la versión PHP 5.3.0 para resolver este problema.
 Instalación anulada.',
-       'config-suhosin-max-value-length' => 'Suhosin está instalado y limita el parámetro <code>length</code> GET a $1 bytes. 
+       'config-suhosin-max-value-length' => 'Suhosin está instalado y limita el parámetro <code>length</code> GET a $1 bytes.
 El componente ResourceLoader (gestor de recursos) de MediaWiki trabajará en este límite, pero eso perjudicará el rendimiento.
 Si es posible, deberías establecer <code>suhosin.get.max_value_length</code> en el valor 1024 o superior en <code>php.ini</code> y establecer <code>$wgResourceLoaderMaxQueryLength</code> en el mismo valor en <code>php.ini</code>.',
        'config-db-type' => 'Tipo de base de datos',
@@ -4932,7 +4955,7 @@ Esta no es la contraseña para la cuenta de MediaWiki; esta es la contraseña pa
        'config-db-wiki-help' => 'Introduce el nombre de usuario y la contraseña que serán usados para acceder a la base de datos durante la operación normal del wiki.
 Si esta cuenta no existe y la cuenta de instalación tiene suficientes privilegios, se creará esta cuenta de usuario con los privilegios mínimos necesarios para la operación normal del wiki.',
        'config-db-prefix' => 'Prefijo para las tablas de la base de datos:',
-       'config-db-prefix-help' => 'Si necesita compartir una base de datos entre múltiples wikis, o entre MediaWiki y otra aplicación web, puede optar por agregar un prefijo a todos los nombres de tabla para evitar conflictos. 
+       'config-db-prefix-help' => 'Si necesita compartir una base de datos entre múltiples wikis, o entre MediaWiki y otra aplicación web, puede optar por agregar un prefijo a todos los nombres de tabla para evitar conflictos.
 No utilice espacios.
 
 Normalmente se deja este campo vacío.',
@@ -15509,7 +15532,7 @@ Jeśli korzystasz ze współdzielonego hostingu, dostawca usługi hostingowej mo
 
 Możesz utworzyć konto użytkownika bazy danych podczas instalacji MediaWiki. Wówczas należy podać nazwę i hasło użytkownika z rolą SYSDBA w celu użycia go przez instalator do utworzenia nowe konta użytkownika, z którego korzystać będzie MediaWiki.
 
-Możesz również skorzystać z konta użytkownika bazy danych utworzonego bezpośrednio w Oracle i wówczas wystarczy podać tylko nazwę i hasło tego użytkownika. Konto z rolą SYSDBA nie będzie potrzebne, jednak konto użytkownika powinno mieć uprawnienia do utworzenia obiektów w schemacie bazy danych. Możesz też podać dwa konta - konto dla instalatora, z pomocą którego zostaną obiekty w schemacie bazy danych i drugie konto, z którego będzie MediaWiki korzystać będzie do pracy. 
+Możesz również skorzystać z konta użytkownika bazy danych utworzonego bezpośrednio w Oracle i wówczas wystarczy podać tylko nazwę i hasło tego użytkownika. Konto z rolą SYSDBA nie będzie potrzebne, jednak konto użytkownika powinno mieć uprawnienia do utworzenia obiektów w schemacie bazy danych. Możesz też podać dwa konta - konto dla instalatora, z pomocą którego zostaną obiekty w schemacie bazy danych i drugie konto, z którego będzie MediaWiki korzystać będzie do pracy.
 
 W podkatalogu "maintenance/oracle" znajduje się skrypt do tworzenia konta użytkownika. Korzystanie z konta użytkownika z ograniczonymi uprawnieniami spowoduje wyłączenie funkcji związanych z aktualizacją oprogramowania MediaWiki.',
        'config-db-install-account' => 'Konto użytkownika dla instalatora',
@@ -15900,7 +15923,7 @@ A la trovrà an LocalSetting.php.",
 Për agiorné sta instalassion, për piasì fà anvece giré <code>update.php</code>",
        'config-localsettings-key' => "Ciav d'agiornament:",
        'config-localsettings-badkey' => "La ciav ch'it l'has dàit a l'é pa giusta.",
-       'config-upgrade-key-missing' => "A l'é stàita trovà n'istalassion esistenta ëd MediaWiki. 
+       'config-upgrade-key-missing' => "A l'é stàita trovà n'istalassion esistenta ëd MediaWiki.
 Për agiorné soa istalassion, për piasì ch'a buta la linia sì-sota al fond ëd sò <code>LocalSettings.php</code>:
 
 $1",
@@ -19593,7 +19616,7 @@ Ang mas masasalimuot na mga kaayusan ng mga karapatan ng tagagamit ay makukuha p
        'config-license-gfdl' => 'Lisensiyang 1.3 ng Malayang Dokumentasyon ng GNU o mas lalong huli',
        'config-license-pd' => 'Nasasakupan ng Madla',
        'config-license-cc-choose' => 'Pumili ng isang pasadyang Lisensiya ng Malikhaing mga Pangkaraniwan',
-       'config-license-help' => "Maraming mga pangmadlang wiki ang naglalagay ng lahat ng mga ambag sa ilalim ng [http://freedomdefined.org/Definition lisensiyang malaya]. 
+       'config-license-help' => "Maraming mga pangmadlang wiki ang naglalagay ng lahat ng mga ambag sa ilalim ng [http://freedomdefined.org/Definition lisensiyang malaya].
 Nakakatulong ito sa paglikha ng isang diwa ng pagmamay-ari ng pamayanan at nakapanghihikayat ng ambag na pangmahabang panahon.
 Sa pangkalahatan, hindi kailangan ang isang wiking pribado o pangsamahan.
 
@@ -20023,7 +20046,7 @@ MediaWiki вимагає підтримку UTF-8 для коректної ро
        'config-mysql-old' => 'Необхідна MySQL $1 або пізніша, а у Вас $2.',
        'config-db-port' => 'Порт бази даних:',
        'config-db-schema' => 'Схема для MediaWiki',
-       'config-db-schema-help' => 'Ця схема зазвичай працює добре. 
+       'config-db-schema-help' => 'Ця схема зазвичай працює добре.
 Змінюйте її тільки якщо знаєте, що Вам це потрібно.',
        'config-pg-test-error' => "Не вдається підключитися до бази даних '''$1''': $2",
        'config-sqlite-dir' => 'Папка даних SQLite:',
@@ -20250,7 +20273,7 @@ GFDL — допустима ліцензія, але у ній важко роз
        'config-upload-deleted-help' => 'Оберіть папку для архівації видалених файлів.
 В ідеалі, вона не має бути доступною через інтернет.',
        'config-logo' => 'URL логотипу:',
-       'config-logo-help' => 'Стандартна схема оформлення MediaWiki містить вільне для логотипу місце над бічною панеллю розміром 135x160 пікселів. 
+       'config-logo-help' => 'Стандартна схема оформлення MediaWiki містить вільне для логотипу місце над бічною панеллю розміром 135x160 пікселів.
 
 Завантажте зображення відповідного розміру і введіть тут його URL.
 
@@ -20370,9 +20393,9 @@ $messages['ur'] = array(
        'config-git' => 'Git ورژن کنٹرول مصنع لطیف ملا: <code>$1</code> ۔',
        'config-git-bad' => 'GIT ورژن کنٹرول مصنع لطیف نہيں ملا ۔',
        'config-mysql-only-myisam-dep' => "' ' تنبیہ: ' '[[MyISAM|مائ اسام]] واحد دستیاب 'ذخیرہ جاتی انجن' ہے جو مائی ایس کیو ایل کے لیے ہے ، جو کہ ناموزوں ہے میڈیا وکی کے لیے ،کیوں کہ :
-* یہ ہموار قطاروں کی سہولت بمشکل فراہم کرتا ہے 
+* یہ ہموار قطاروں کی سہولت بمشکل فراہم کرتا ہے
 * یہ دوسرے انجنوں کے مقابلے  زیادہ بگڑ جاتا ہے
-* میڈیا وکی کوڈ بیس ہمیشہ سنبھال نہيں پاتا مائی اسام کو ۔ 
+* میڈیا وکی کوڈ بیس ہمیشہ سنبھال نہيں پاتا مائی اسام کو ۔
 
 آپ کا مائی ایس کیو ایل کا نصب ہمیشہ اننو ڈی بی کی سہولت نہيں دے سکتا ، ہو سکتا ہے یہ مزید ترقیاتی کام چاہے", # Fuzzy
        'config-profile-fishbowl' => 'صرف مجاز ایڈیٹرز',
index edc0feb..55ca014 100644 (file)
@@ -102,6 +102,7 @@ abstract class Installer {
                'mysql',
                'postgres',
                'oracle',
+               'mssql',
                'sqlite',
        );
 
diff --git a/includes/installer/MssqlInstaller.php b/includes/installer/MssqlInstaller.php
new file mode 100644 (file)
index 0000000..952b902
--- /dev/null
@@ -0,0 +1,692 @@
+<?php
+/**
+ * Microsoft SQL Server-specific installer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Deployment
+ */
+
+/**
+ * Class for setting up the MediaWiki database using Microsoft SQL Server.
+ *
+ * @ingroup Deployment
+ * @since 1.23
+ */
+class MssqlInstaller extends DatabaseInstaller {
+
+       protected $globalNames = array(
+               'wgDBserver',
+               'wgDBname',
+               'wgDBuser',
+               'wgDBpassword',
+               'wgDBmwschema',
+               'wgDBprefix',
+               'wgDBWindowsAuthentication',
+       );
+
+       protected $internalDefaults = array(
+               '_InstallUser' => 'sa',
+               '_InstallWindowsAuthentication' => 'sqlauth',
+               '_WebWindowsAuthentication' => 'sqlauth',
+       );
+
+       public $minimumVersion = '9.00.1399'; // SQL Server 2005 RTM (TODO: are SQL Express version numbers different?)
+
+       // These are schema-level privs
+       // Note: the web user will be created will full permissions if possible, this permission
+       // list is only used if we are unable to grant full permissions.
+       public $webUserPrivs = array(
+               'DELETE',
+               'INSERT',
+               'SELECT',
+               'UPDATE',
+               'EXECUTE',
+       );
+
+       /**
+        * @return string
+        */
+       public function getName() {
+               return 'mssql';
+       }
+
+       /**
+        * @return Bool
+        */
+       public function isCompiled() {
+               return self::checkExtension( 'sqlsrv' );
+       }
+
+       /**
+        * @return string
+        */
+       public function getConnectForm() {
+               if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
+                       $displayStyle = 'display: none;';
+               } else {
+                       $displayStyle = 'display: block;';
+               }
+
+               return $this->getTextBox(
+                       'wgDBserver',
+                       'config-db-host',
+                       array(),
+                       $this->parent->getHelpBox( 'config-db-host-help' )
+               ) .
+                       Html::openElement( 'fieldset' ) .
+                       Html::element( 'legend', array(), wfMessage( 'config-db-wiki-settings' )->text() ) .
+                       $this->getTextBox( 'wgDBname', 'config-db-name', array( 'dir' => 'ltr' ),
+                               $this->parent->getHelpBox( 'config-db-name-help' ) ) .
+                       $this->getTextBox( 'wgDBmwschema', 'config-db-schema', array( 'dir' => 'ltr' ),
+                               $this->parent->getHelpBox( 'config-db-schema-help' ) ) .
+                       $this->getTextBox( 'wgDBprefix', 'config-db-prefix', array( 'dir' => 'ltr' ),
+                               $this->parent->getHelpBox( 'config-db-prefix-help' ) ) .
+                       Html::closeElement( 'fieldset' ) .
+                       Html::openElement( 'fieldset' ) .
+                       Html::element( 'legend', array(), wfMessage( 'config-db-install-account' )->text() ) .
+                       $this->getRadioSet( array(
+                               'var' => '_InstallWindowsAuthentication',
+                               'label' => 'config-mssql-auth',
+                               'itemLabelPrefix' => 'config-mssql-',
+                               'values' => array( 'sqlauth', 'windowsauth' ),
+                               'itemAttribs' => array(
+                                       'sqlauth' => array(
+                                               'class' => 'showHideRadio',
+                                               'rel' => 'dbCredentialBox',
+                                       ),
+                                       'windowsauth' => array(
+                                               'class' => 'hideShowRadio',
+                                               'rel' => 'dbCredentialBox',
+                                       )
+                               ),
+                               'help' => $this->parent->getHelpBox( 'config-mssql-install-auth' )
+                       ) ) .
+                       Html::openElement( 'div', array( 'id' => 'dbCredentialBox', 'style' => $displayStyle ) ) .
+                       $this->getTextBox(
+                               '_InstallUser',
+                               'config-db-username',
+                               array( 'dir' => 'ltr' ),
+                               $this->parent->getHelpBox( 'config-db-install-username' )
+                       ) .
+                       $this->getPasswordBox(
+                               '_InstallPassword',
+                               'config-db-password',
+                               array( 'dir' => 'ltr' ),
+                               $this->parent->getHelpBox( 'config-db-install-password' )
+                       ) .
+                       Html::closeElement( 'div' ) .
+                       Html::closeElement( 'fieldset' );
+       }
+
+       public function submitConnectForm() {
+               // Get variables from the request.
+               $newValues = $this->setVarsFromRequest( array( 'wgDBserver', 'wgDBname', 'wgDBmwschema', 'wgDBprefix' ) );
+
+               // Validate them.
+               $status = Status::newGood();
+               if ( !strlen( $newValues['wgDBserver'] ) ) {
+                       $status->fatal( 'config-missing-db-host' );
+               }
+               if ( !strlen( $newValues['wgDBname'] ) ) {
+                       $status->fatal( 'config-missing-db-name' );
+               } elseif ( !preg_match( '/^[a-z0-9_]+$/i', $newValues['wgDBname'] ) ) {
+                       $status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] );
+               }
+               if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBmwschema'] ) ) {
+                       $status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] );
+               }
+               if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBprefix'] ) ) {
+                       $status->fatal( 'config-invalid-db-prefix', $newValues['wgDBprefix'] );
+               }
+               if ( !$status->isOK() ) {
+                       return $status;
+               }
+
+               // Check for blank schema and remap to dbo
+               if ( $newValues['wgDBmwschema'] === '' ) {
+                       $this->setVar( 'wgDBmwschema', 'dbo' );
+               }
+
+               // User box
+               $this->setVarsFromRequest( array( '_InstallUser', '_InstallPassword', '_InstallWindowsAuthentication' ) );
+
+               // Try to connect
+               $status = $this->getConnection();
+               if ( !$status->isOK() ) {
+                       return $status;
+               }
+               /**
+                * @var $conn DatabaseBase
+                */
+               $conn = $status->value;
+
+               // Check version
+               $version = $conn->getServerVersion();
+               if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
+                       return Status::newFatal( 'config-mssql-old', $this->minimumVersion, $version );
+               }
+
+               return $status;
+       }
+
+       /**
+        * @return Status
+        */
+       public function openConnection() {
+               global $wgDBWindowsAuthentication;
+               $status = Status::newGood();
+               $user = $this->getVar( '_InstallUser' );
+               $password = $this->getVar( '_InstallPassword' );
+
+               if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
+                       // Use Windows authentication for this connection
+                       $wgDBWindowsAuthentication = true;
+               } else {
+                       $wgDBWindowsAuthentication = false;
+               }
+
+               try {
+                       $db = DatabaseBase::factory( 'mssql', array(
+                               'host' => $this->getVar( 'wgDBserver' ),
+                               'user' => $user,
+                               'password' => $password,
+                               'dbname' => false,
+                               'flags' => 0,
+                               'tablePrefix' => $this->getVar( 'wgDBprefix' ) ) );
+                       $db->prepareStatements( false );
+                       $db->scrollableCursor( false );
+                       $status->value = $db;
+               } catch ( DBConnectionError $e ) {
+                       $status->fatal( 'config-connection-error', $e->getMessage() );
+               }
+
+               return $status;
+       }
+
+       public function preUpgrade() {
+               global $wgDBuser, $wgDBpassword;
+
+               $status = $this->getConnection();
+               if ( !$status->isOK() ) {
+                       $this->parent->showStatusError( $status );
+
+                       return;
+               }
+               /**
+                * @var $conn DatabaseBase
+                */
+               $conn = $status->value;
+               $conn->selectDB( $this->getVar( 'wgDBname' ) );
+
+               # Normal user and password are selected after this step, so for now
+               # just copy these two
+               $wgDBuser = $this->getVar( '_InstallUser' );
+               $wgDBpassword = $this->getVar( '_InstallPassword' );
+       }
+
+       /**
+        * Return true if the install user can create accounts
+        *
+        * @return bool
+        */
+       public function canCreateAccounts() {
+               $status = $this->getConnection();
+               if ( !$status->isOK() ) {
+                       return false;
+               }
+               /** @var $conn DatabaseBase */
+               $conn = $status->value;
+
+               // We need the server-level ALTER ANY LOGIN permission to create new accounts
+               $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'SERVER' )" );
+               $serverPrivs = array(
+                       'ALTER ANY LOGIN' => false,
+                       'CONTROL SERVER' => false,
+               );
+
+               foreach ( $res as $row ) {
+                       $serverPrivs[$row->permission_name] = true;
+               }
+
+               if ( !$serverPrivs['ALTER ANY LOGIN'] ) {
+                       return false;
+               }
+
+               // Check to ensure we can grant everything needed as well
+               // We can't actually tell if we have WITH GRANT OPTION for a given permission, so we assume we do
+               // and just check for the permission
+               // http://technet.microsoft.com/en-us/library/ms178569.aspx
+               // The following array sets up which permissions imply whatever permissions we specify
+               $implied = array(
+                       // schema           database   server
+                       'DELETE'  => array( 'DELETE',  'CONTROL SERVER' ),
+                       'EXECUTE' => array( 'EXECUTE', 'CONTROL SERVER' ),
+                       'INSERT'  => array( 'INSERT',  'CONTROL SERVER' ),
+                       'SELECT'  => array( 'SELECT',  'CONTROL SERVER' ),
+                       'UPDATE'  => array( 'UPDATE',  'CONTROL SERVER' ),
+               );
+
+               $grantOptions = array_flip( $this->webUserPrivs );
+
+               // Check for schema and db-level permissions, but only if the schema/db exists
+               $schemaPrivs = $dbPrivs = array(
+                       'DELETE' => false,
+                       'EXECUTE' => false,
+                       'INSERT' => false,
+                       'SELECT' => false,
+                       'UPDATE' => false,
+               );
+
+               $dbPrivs['ALTER ANY USER'] = false;
+
+               if ( $this->databaseExists( $this->getVar( 'wgDBname' ) ) ) {
+                       $conn->selectDB( $this->getVar( 'wgDBname' ) );
+                       $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'DATABASE' )" );
+
+                       foreach ( $res as $row ) {
+                               $dbPrivs[$row->permission_name] = true;
+                       }
+
+                       // If the db exists, we need ALTER ANY USER privs on it to make a new user
+                       if ( !$dbPrivs['ALTER ANY USER'] ) {
+                               return false;
+                       }
+
+                       if ( $this->schemaExists( $this->getVar( 'wgDBmwschema' ) ) ) {
+                               // wgDBmwschema is validated to only contain alphanumeric + underscore, so this is safe
+                               $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( '{$this->getVar( 'wgDBmwschema' )}', 'SCHEMA' )" );
+
+                               foreach ( $res as $row ) {
+                                       $schemaPrivs[$row->permission_name] = true;
+                               }
+                       }
+               }
+
+               // Now check all the grants we'll need to be doing to see if we can
+               foreach ( $this->webUserPrivs as $permission ) {
+                       if ( ( isset( $schemaPrivs[$permission] ) && $schemaPrivs[$permission] )
+                                       || ( isset( $dbPrivs[$implied[$permission][0]] ) && $dbPrivs[$implied[$permission][0]] )
+                                       || ( isset( $serverPrivs[$implied[$permission][1]] ) && $serverPrivs[$implied[$permission][1]] ) ) {
+
+                               unset( $grantOptions[$permission] );
+                       }
+               }
+
+               if ( count( $grantOptions ) ) {
+                       // Can't grant everything
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * @return string
+        */
+       public function getSettingsForm() {
+               if ( $this->canCreateAccounts() ) {
+                       $noCreateMsg = false;
+               } else {
+                       $noCreateMsg = 'config-db-web-no-create-privs';
+               }
+               $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
+               $displayStyle = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ? 'display: none' : '';
+               $s = Html::openElement( 'fieldset' ) .
+                       Html::element( 'legend', array(), wfMessage( 'config-db-web-account' )->text() ) .
+                       $this->getCheckBox(
+                               '_SameAccount', 'config-db-web-account-same',
+                               array( 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' )
+                       ) .
+                       Html::openElement( 'div', array( 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ) ) .
+                       $this->getRadioSet( array(
+                               'var' => '_WebWindowsAuthentication',
+                               'label' => 'config-mssql-auth',
+                               'itemLabelPrefix' => 'config-mssql-',
+                               'values' => array( 'sqlauth', 'windowsauth' ),
+                               'itemAttribs' => array(
+                                       'sqlauth' => array(
+                                               'class' => 'showHideRadio',
+                                               'rel' => 'dbCredentialBox',
+                                       ),
+                                       'windowsauth' => array(
+                                               'class' => 'hideShowRadio',
+                                               'rel' => 'dbCredentialBox',
+                                       )
+                               ),
+                               'help' => $this->parent->getHelpBox( 'config-mssql-web-auth' )
+                       ) ) .
+                       Html::openElement( 'div', array( 'id' => 'dbCredentialBox', 'style' => $displayStyle ) ) .
+                       $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
+                       $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
+                       Html::closeElement( 'div' );
+
+               if ( $noCreateMsg ) {
+                       $s .= $this->parent->getWarningBox( wfMessage( $noCreateMsg )->plain() );
+               } else {
+                       $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
+               }
+
+               $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
+
+               return $s;
+       }
+
+       /**
+        * @return Status
+        */
+       public function submitSettingsForm() {
+               $this->setVarsFromRequest(
+                       array( 'wgDBuser', 'wgDBpassword', '_SameAccount', '_CreateDBAccount', '_WebWindowsAuthentication' )
+               );
+
+               if ( $this->getVar( '_SameAccount' ) ) {
+                       $this->setVar( '_WebWindowsAuthentication', $this->getVar( '_InstallWindowsAuthentication' ) );
+                       $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
+                       $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
+               }
+
+               if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
+                       $this->setVar( 'wgDBuser', '' );
+                       $this->setVar( 'wgDBpassword', '' );
+                       $this->setVar( 'wgDBWindowsAuthentication', true );
+               } else {
+                       $this->setVar( 'wgDBWindowsAuthentication', false );
+               }
+
+               if ( $this->getVar( '_CreateDBAccount' ) && $this->getVar( '_WebWindowsAuthentication' ) == 'sqlauth' && strval( $this->getVar( 'wgDBpassword' ) ) == '' ) {
+                       return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
+               }
+
+               // Validate the create checkbox
+               $canCreate = $this->canCreateAccounts();
+               if ( !$canCreate ) {
+                       $this->setVar( '_CreateDBAccount', false );
+                       $create = false;
+               } else {
+                       $create = $this->getVar( '_CreateDBAccount' );
+               }
+
+               if ( !$create ) {
+                       // Test the web account
+                       $user = $this->getVar( 'wgDBuser' );
+                       $password = $this->getVar( 'wgDBpassword' );
+
+                       if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
+                               $user = 'windowsauth';
+                               $password = 'windowsauth';
+                       }
+
+                       try {
+                               DatabaseBase::factory( 'mssql', array(
+                                       'host' => $this->getVar( 'wgDBserver' ),
+                                       'user' => $user,
+                                       'password' => $password,
+                                       'dbname' => false,
+                                       'flags' => 0,
+                                       'tablePrefix' => $this->getVar( 'wgDBprefix' ),
+                                       'schema' => $this->getVar( 'wgDBmwschema' ),
+                               ) );
+                       } catch ( DBConnectionError $e ) {
+                               return Status::newFatal( 'config-connection-error', $e->getMessage() );
+                       }
+               }
+
+               return Status::newGood();
+       }
+
+       public function preInstall() {
+               # Add our user callback to installSteps, right before the tables are created.
+               $callback = array(
+                       'name' => 'user',
+                       'callback' => array( $this, 'setupUser' ),
+               );
+               $this->parent->addInstallStep( $callback, 'tables' );
+       }
+
+       /**
+        * @return Status
+        */
+       public function setupDatabase() {
+               $status = $this->getConnection();
+               if ( !$status->isOK() ) {
+                       return $status;
+               }
+               /** @var DatabaseBase $conn */
+               $conn = $status->value;
+               $dbName = $this->getVar( 'wgDBname' );
+               $schemaName = $this->getVar( 'wgDBmwschema' );
+               if ( !$this->databaseExists( $dbName ) ) {
+                       $conn->query( "CREATE DATABASE " . $conn->addIdentifierQuotes( $dbName ), __METHOD__ );
+                       $conn->selectDB( $dbName );
+                       if ( !$this->schemaExists( $schemaName ) ) {
+                               $conn->query( "CREATE SCHEMA " . $conn->addIdentifierQuotes( $schemaName ), __METHOD__ );
+                       }
+                       if ( !$this->catalogExists( $schemaName ) ) {
+                               $conn->query( "CREATE FULLTEXT CATALOG " . $conn->addIdentifierQuotes( $schemaName ), __METHOD__ );
+                       }
+               }
+               $this->setupSchemaVars();
+
+               return $status;
+       }
+
+       /**
+        * @return Status
+        */
+       public function setupUser() {
+               $dbUser = $this->getVar( 'wgDBuser' );
+               if ( $dbUser == $this->getVar( '_InstallUser' )
+                               || ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth'
+                                       && $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) ) {
+                       return Status::newGood();
+               }
+               $status = $this->getConnection();
+               if ( !$status->isOK() ) {
+                       return $status;
+               }
+
+               $this->setupSchemaVars();
+               $dbName = $this->getVar( 'wgDBname' );
+               $this->db->selectDB( $dbName );
+               $server = $this->getVar( 'wgDBserver' );
+               $password = $this->getVar( 'wgDBpassword' );
+               $schemaName = $this->getVar( 'wgDBmwschema' );
+
+               if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
+                       $dbUser = 'windowsauth';
+                       $password = 'windowsauth';
+               }
+
+               if ( $this->getVar( '_CreateDBAccount' ) ) {
+                       $tryToCreate = true;
+               } else {
+                       $tryToCreate = false;
+               }
+
+               $escUser = $this->db->addIdentifierQuotes( $dbUser );
+               $escDb = $this->db->addIdentifierQuotes( $dbName );
+               $escSchema = $this->db->addIdentifierQuotes( $schemaName );
+               $grantableNames = array();
+               if ( $tryToCreate ) {
+                       $escPass = $this->db->addQuotes( $password );
+
+                       if ( !$this->loginExists( $dbUser ) ) {
+                               try {
+                                       $this->db->begin();
+                                       $this->db->selectDB( 'master' );
+                                       $logintype = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ? 'FROM WINDOWS' : "WITH PASSWORD = $escPass";
+                                       $this->db->query( "CREATE LOGIN $escUser $logintype" );
+                                       $this->db->selectDB( $dbName );
+                                       $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
+                                       $this->db->commit();
+                                       $grantableNames[] = $dbUser;
+                               } catch ( DBQueryError $dqe ) {
+                                       $this->db->rollback();
+                                       $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getText() );
+                               }
+                       } elseif ( !$this->userExists( $dbUser ) ) {
+                               try {
+                                       $this->db->begin();
+                                       $this->db->selectDB( $dbName );
+                                       $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
+                                       $this->db->commit();
+                                       $grantableNames[] = $dbUser;
+                               } catch ( DBQueryError $dqe ) {
+                                       $this->db->rollback();
+                                       $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getText() );
+                               }
+                       } else {
+                               $status->warning( 'config-install-user-alreadyexists', $dbUser );
+                               $grantableNames[] = $dbUser;
+                       }
+               }
+
+               // Try to grant to all the users we know exist or we were able to create
+               $this->db->selectDB( $dbName );
+               foreach ( $grantableNames as $name ) {
+                       try {
+                               // First try to grant full permissions
+                               $fullPrivArr = array(
+                                       'BACKUP DATABASE', 'BACKUP LOG', 'CREATE FUNCTION', 'CREATE PROCEDURE',
+                                       'CREATE TABLE', 'CREATE VIEW', 'CREATE FULLTEXT CATALOG', 'SHOWPLAN'
+                               );
+                               $fullPrivList = implode( ', ', $fullPrivArr );
+                               $this->db->begin();
+                               $this->db->query( "GRANT $fullPrivList ON DATABASE :: $escDb TO $escUser", __METHOD__ );
+                               $this->db->query( "GRANT CONTROL ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
+                               $this->db->commit();
+                       } catch ( DBQueryError $dqe ) {
+                               // If that fails, try to grant the limited subset specified in $this->webUserPrivs
+                               try {
+                                       $privList = implode( ', ', $this->webUserPrivs );
+                                       $this->db->rollback();
+                                       $this->db->begin();
+                                       $this->db->query( "GRANT $privList ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
+                                       $this->db->commit();
+                               } catch ( DBQueryError $dqe ) {
+                                       $this->db->rollback();
+                                       $status->fatal( 'config-install-user-grant-failed', $dbUser, $dqe->getText() );
+                               }
+                               // Also try to grant SHOWPLAN on the db, but don't fail if we can't
+                               // (just makes a couple things in mediawiki run slower since
+                               // we have to run SELECT COUNT(*) instead of getting the query plan)
+                               try {
+                                       $this->db->query( "GRANT SHOWPLAN ON DATABASE :: $escDb TO $escUser", __METHOD__ );
+                               } catch ( DBQueryError $dqe ) {
+                               }
+                       }
+               }
+
+               return $status;
+       }
+
+       public function createTables() {
+               $status = parent::createTables();
+
+               // Do last-minute stuff like fulltext indexes (since they can't be inside a transaction)
+               if ( $status->isOk() ) {
+                       $searchindex = $this->db->tableName( 'searchindex' );
+                       $schema = $this->db->addIdentifierQuotes( $this->getVar( 'wgDBmwschema' ) );
+                       try {
+                               $this->db->query( "CREATE FULLTEXT INDEX ON $searchindex (si_title, si_text) KEY INDEX si_page ON $schema" );
+                       } catch ( DBQueryError $dqe ) {
+                               $status->fatal( 'config-install-tables-failed', $dqe->getText() );
+                       }
+               }
+
+               return $status;
+       }
+
+       /**
+        * Try to see if the login exists
+        * @param string $user Username to check
+        * @return boolean
+        */
+       private function loginExists( $user ) {
+               $res = $this->db->selectField( 'sys.sql_logins', 1, array( 'name' => $user ) );
+               return (bool)$res;
+       }
+
+       /**
+        * Try to see if the user account exists
+        * We assume we already have the appropriate database selected
+        * @param string $user Username to check
+        * @return boolean
+        */
+       private function userExists( $user ) {
+               $res = $this->db->selectField( 'sys.sysusers', 1, array( 'name' => $user ) );
+               return (bool)$res;
+       }
+
+       /**
+        * Try to see if a given database exists
+        * @param string $dbName Database name to check
+        * @return boolean
+        */
+       private function databaseExists( $dbName ) {
+               $res = $this->db->selectField( 'sys.databases', 1, array( 'name' => $dbName ) );
+               return (bool)$res;
+       }
+
+       /**
+        * Try to see if a given schema exists
+        * We assume we already have the appropriate database selected
+        * @param string $schemaName Schema name to check
+        * @return boolean
+        */
+       private function schemaExists( $schemaName ) {
+               $res = $this->db->selectField( 'sys.schemas', 1, array( 'name' => $schemaName ) );
+               return (bool)$res;
+       }
+
+       /**
+        * 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
+        * @return boolean
+        */
+       private function catalogExists( $catalogName ) {
+               $res = $this->db->selectField( 'sys.fulltext_catalogs', 1, array( 'name' => $catalogName ) );
+               return (bool)$res;
+       }
+
+       /**
+        * Get variables to substitute into tables.sql and the SQL patch files.
+        *
+        * @return array
+        */
+       public function getSchemaVars() {
+               return array(
+                       'wgDBname' => $this->getVar( 'wgDBname' ),
+                       'wgDBmwschema' => $this->getVar( 'wgDBmwschema' ),
+                       'wgDBuser' => $this->getVar( 'wgDBuser' ),
+                       'wgDBpassword' => $this->getVar( 'wgDBpassword' ),
+               );
+       }
+
+       public function getLocalSettings() {
+               $schema = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBmwschema' ) );
+               $prefix = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBprefix' ) );
+               $windowsauth = $this->getVar( 'wgDBWindowsAuthentication' ) ? 'true' : 'false';
+
+               return "# MSSQL specific settings
+\$wgDBWindowsAuthentication = {$windowsauth};
+\$wgDBmwschema = \"{$schema}\";
+\$wgDBprefix = \"{$prefix}\";";
+       }
+}
diff --git a/includes/installer/MssqlUpdater.php b/includes/installer/MssqlUpdater.php
new file mode 100644 (file)
index 0000000..7d3833b
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Microsoft SQL Server-specific installer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Deployment
+ */
+
+/**
+ * Class for setting up the MediaWiki database using Microsoft SQL Server.
+ *
+ * @ingroup Deployment
+ * @since 1.23
+ */
+
+class MssqlUpdater extends DatabaseUpdater {
+
+       /**
+        * @var DatabaseMssql
+        */
+       protected $db;
+
+       protected function getCoreUpdateList() {
+               return array(
+                       array( 'disableContentHandlerUseDB' ),
+
+                       // 1.23
+
+               );
+       }
+}
index a608657..607c4e5 100644 (file)
@@ -797,8 +797,7 @@ class BitmapHandler extends ImageHandler {
                                wfDebug( __METHOD__ . ": running ImageMagick: $cmd\n" );
                                wfProfileIn( 'convert' );
                                $retval = 0;
-                               // @todo FIXME: Undefined variable %env
-                               $err = wfShellExecWithStderr( $cmd, $retval, $env );
+                               $err = wfShellExecWithStderr( $cmd, $retval );
                                wfProfileOut( 'convert' );
                                if ( $retval !== 0 ) {
                                        $this->logErrorForExternalProcess( $retval, $err, $cmd );
index c021bea..b2c9757 100644 (file)
@@ -41,6 +41,7 @@ class ParserOutput extends CacheTime {
                $mModuleScripts = array(),    # Modules of which only the JS will be loaded by the resource loader
                $mModuleStyles = array(),     # Modules of which only the CSSS will be loaded by the resource loader
                $mModuleMessages = array(),   # Modules of which only the messages will be loaded by the resource loader
+               $mJsConfigVars = array(),     # JavaScript config variable for mw.config combined with this page
                $mOutputHooks = array(),      # Hook tags as per $wgParserOutputHooks
                $mWarnings = array(),         # Warning text to be returned to the user. Wikitext formatted, in the key only
                $mSections = array(),         # Table of contents
@@ -134,6 +135,8 @@ class ParserOutput extends CacheTime {
        function getModuleScripts()          { return $this->mModuleScripts; }
        function getModuleStyles()           { return $this->mModuleStyles; }
        function getModuleMessages()         { return $this->mModuleMessages; }
+       /** @since 1.23 */
+       function getJsConfigVars()           { return $this->mJsConfigVars; }
        function getOutputHooks()            { return (array)$this->mOutputHooks; }
        function getWarnings()               { return array_keys( $this->mWarnings ); }
        function getIndexPolicy()            { return $this->mIndexPolicy; }
@@ -318,6 +321,24 @@ class ParserOutput extends CacheTime {
                $this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules );
        }
 
+       /**
+        * Add one or more variables to be set in mw.config in JavaScript.
+        *
+        * @param $keys {String|Array} Key or array of key/value pairs.
+        * @param $value {Mixed} [optional] Value of the configuration variable.
+        * @since 1.23
+        */
+       public function addJsConfigVars( $keys, $value = null ) {
+               if ( is_array( $keys ) ) {
+                       foreach ( $keys as $key => $value ) {
+                               $this->mJsConfigVars[$key] = $value;
+                       }
+                       return;
+               }
+
+               $this->mJsConfigVars[$keys] = $value;
+       }
+
        /**
         * Copy items from the OutputPage object into this one
         *
@@ -328,6 +349,7 @@ class ParserOutput extends CacheTime {
                $this->addModuleScripts( $out->getModuleScripts() );
                $this->addModuleStyles( $out->getModuleStyles() );
                $this->addModuleMessages( $out->getModuleMessages() );
+               $this->addJsConfigVars( $out->getJsConfigVars() );
 
                $this->mHeadItems = array_merge( $this->mHeadItems, $out->getHeadItemsArray() );
        }
index 22ff6a7..b90ca44 100644 (file)
@@ -83,8 +83,6 @@ class ResourceLoaderContext {
         */
        public static function expandModuleNames( $modules ) {
                $retval = array();
-               // For backwards compatibility with an earlier hack, replace ! with .
-               $modules = str_replace( '!', '.', $modules );
                $exploded = explode( '|', $modules );
                foreach ( $exploded as $group ) {
                        if ( strpos( $group, ',' ) === false ) {
index eaff86f..23d5825 100644 (file)
@@ -674,6 +674,7 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
         *
         * @param bool $flip
         *
+        * @throws MWException
         * @return array: List of concatenated and remapped CSS data from $styles,
         *     keyed by media type
         */
@@ -683,14 +684,11 @@ class ResourceLoaderFileModule extends ResourceLoaderModule {
                }
                foreach ( $styles as $media => $files ) {
                        $uniqueFiles = array_unique( $files );
-                       $styles[$media] = implode(
-                               "\n",
-                               array_map(
-                                       array( $this, 'readStyleFile' ),
-                                       $uniqueFiles,
-                                       array_fill( 0, count( $uniqueFiles ), $flip )
-                               )
-                       );
+                       $styleFiles = array();
+                       foreach ( $uniqueFiles as $file ) {
+                               $styleFiles[] = $this->readStyleFile( $file, $flip );
+                       }
+                       $styles[$media] = implode( "\n", $styleFiles );
                }
                return $styles;
        }
index 09284d0..e505ecb 100644 (file)
@@ -38,6 +38,7 @@ class SpecialProtectedpages extends SpecialPage {
        public function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
+               $this->getOutput()->addModuleStyles( 'mediawiki.special' );
 
                // Purge expired entries on one in every 10 queries
                if ( !mt_rand( 0, 10 ) ) {
@@ -81,7 +82,7 @@ class SpecialProtectedpages extends SpecialPage {
                if ( $pager->getNumRows() ) {
                        $this->getOutput()->addHTML(
                                $pager->getNavigationBar() .
-                                       '<ul>' . $pager->getBody() . '</ul>' .
+                                       $pager->getBody() .
                                        $pager->getNavigationBar()
                        );
                } else {
@@ -89,105 +90,6 @@ class SpecialProtectedpages extends SpecialPage {
                }
        }
 
-       /**
-        * Callback function to output a restriction
-        * @param Title $row Protected title
-        * @return string Formatted "<li>" element
-        */
-       public function formatRow( $row ) {
-               wfProfileIn( __METHOD__ );
-
-               static $infinity = null;
-
-               if ( is_null( $infinity ) ) {
-                       $infinity = wfGetDB( DB_SLAVE )->getInfinity();
-               }
-
-               $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
-               if ( !$title ) {
-                       wfProfileOut( __METHOD__ );
-
-                       return Html::rawElement(
-                               'li',
-                               array(),
-                               Html::element(
-                                       'span',
-                                       array( 'class' => 'mw-invalidtitle' ),
-                                       Linker::getInvalidTitleDescription(
-                                               $this->getContext(),
-                                               $row->page_namespace,
-                                               $row->page_title
-                                       )
-                               )
-                       ) . "\n";
-               }
-
-               $link = Linker::link( $title );
-
-               $description_items = array();
-
-               // Messages: restriction-level-sysop, restriction-level-autoconfirmed
-               $protType = $this->msg( 'restriction-level-' . $row->pr_level )->escaped();
-
-               $description_items[] = $protType;
-
-               if ( $row->pr_cascade ) {
-                       $description_items[] = $this->msg( 'protect-summary-cascade' )->text();
-               }
-
-               $stxt = '';
-               $lang = $this->getLanguage();
-
-               $expiry = $lang->formatExpiry( $row->pr_expiry, TS_MW );
-               if ( $expiry != $infinity ) {
-                       $user = $this->getUser();
-                       $description_items[] = $this->msg(
-                               'protect-expiring-local',
-                               $lang->userTimeAndDate( $expiry, $user ),
-                               $lang->userDate( $expiry, $user ),
-                               $lang->userTime( $expiry, $user )
-                       )->escaped();
-               }
-
-               if ( !is_null( $size = $row->page_len ) ) {
-                       $stxt = $lang->getDirMark() . ' ' . Linker::formatRevisionSize( $size );
-               }
-
-               // Show a link to the change protection form for allowed users otherwise
-               // a link to the protection log
-               if ( $this->getUser()->isAllowed( 'protect' ) ) {
-                       $changeProtection = Linker::linkKnown(
-                               $title,
-                               $this->msg( 'protect_change' )->escaped(),
-                               array(),
-                               array( 'action' => 'unprotect' )
-                       );
-               } else {
-                       $ltitle = SpecialPage::getTitleFor( 'Log' );
-                       $changeProtection = Linker::linkKnown(
-                               $ltitle,
-                               $this->msg( 'protectlogpage' )->escaped(),
-                               array(),
-                               array(
-                                       'type' => 'protect',
-                                       'page' => $title->getPrefixedText()
-                               )
-                       );
-               }
-
-               $changeProtection = ' ' . $this->msg( 'parentheses' )->rawParams( $changeProtection )
-                       ->escaped();
-
-               wfProfileOut( __METHOD__ );
-
-               return Html::rawElement(
-                       'li',
-                       array(),
-                       $lang->specialList( $link . $stxt, $lang->commaList( $description_items ), false ) .
-                               $changeProtection
-               ) . "\n";
-       }
-
        /**
         * @param int $namespace
         * @param string $type Restriction type
@@ -388,7 +290,7 @@ class SpecialProtectedpages extends SpecialPage {
  * @todo document
  * @ingroup Pager
  */
-class ProtectedPagesPager extends AlphabeticPager {
+class ProtectedPagesPager extends TablePager {
        public $mForm, $mConds;
        private $type, $level, $namespace, $sizetype, $size, $indefonly, $cascadeonly, $noredirect;
 
@@ -408,19 +310,185 @@ class ProtectedPagesPager extends AlphabeticPager {
                parent::__construct( $form->getContext() );
        }
 
-       function getStartBody() {
+       function preprocessResults( $result ) {
                # Do a link batch query
                $lb = new LinkBatch;
-               foreach ( $this->mResult as $row ) {
+               $userids = array();
+
+               foreach ( $result as $row ) {
                        $lb->add( $row->page_namespace, $row->page_title );
+                       // field is nullable, maybe null on old protections
+                       if ( $row->log_user !== null ) {
+                               $userids[] = $row->log_user;
+                       }
+               }
+
+               // fill LinkBatch with user page and user talk
+               if ( count( $userids ) ) {
+                       $userCache = UserCache::singleton();
+                       $userCache->doQuery( $userids, array(), __METHOD__ );
+                       foreach ( $userids as $userid ) {
+                               $name = $userCache->getProp( $userid, 'name' );
+                               if ( $name !== false ) {
+                                       $lb->add( NS_USER, $name );
+                                       $lb->add( NS_USER_TALK, $name );
+                               }
+                       }
                }
+
                $lb->execute();
+       }
 
-               return '';
+       function getFieldNames() {
+               static $headers = null;
+
+               if ( $headers == array() ) {
+                       $headers = array(
+                               'log_timestamp' => 'protectedpages-timestamp',
+                               'pr_page' => 'protectedpages-page',
+                               'pr_expiry' => 'protectedpages-expiry',
+                               'log_user' => 'protectedpages-performer',
+                               'pr_params' => 'protectedpages-params',
+                               'log_comment' => 'protectedpages-reason',
+                       );
+                       foreach ( $headers as $key => $val ) {
+                               $headers[$key] = $this->msg( $val )->text();
+                       }
+               }
+
+               return $headers;
        }
 
-       function formatRow( $row ) {
-               return $this->mForm->formatRow( $row );
+       /**
+        * @param string $field
+        * @param string $value
+        * @return string
+        * @throws MWException
+        */
+       function formatValue( $field, $value ) {
+               /** @var $row object */
+               $row = $this->mCurrentRow;
+
+               $formatted = '';
+
+               switch ( $field ) {
+                       case 'log_timestamp':
+                               // when timestamp is null, this is a old protection row
+                               if ( $value === null ) {
+                                       $formatted = Html::rawElement(
+                                               'span',
+                                               array( 'class' => 'mw-protectedpages-unknown' ),
+                                               $this->msg( 'protectedpages-unknown-timestamp' )->escaped()
+                                       );
+                               } else {
+                                       $formatted = $this->getLanguage()->userTimeAndDate( $value, $this->getUser() );
+                               }
+                               break;
+
+                       case 'pr_page':
+                               $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
+                               if ( !$title ) {
+                                       $formatted = Html::element(
+                                               'span',
+                                               array( 'class' => 'mw-invalidtitle' ),
+                                               Linker::getInvalidTitleDescription(
+                                                       $this->getContext(),
+                                                       $row->page_namespace,
+                                                       $row->page_title
+                                               )
+                                       );
+                               } else {
+                                       $formatted = Linker::link( $title );
+                               }
+                               if ( !is_null( $row->page_len ) ) {
+                                       $formatted .= $this->getLanguage()->getDirMark() .
+                                               ' ' . Html::rawElement(
+                                               'span',
+                                               array( 'class' => 'mw-protectedpages-length' ),
+                                               Linker::formatRevisionSize( $row->page_len )
+                                       );
+                               }
+                               break;
+
+                       case 'pr_expiry':
+                               $formatted = $this->getLanguage()->formatExpiry( $value, /* User preference timezone */true );
+                               $title = Title::makeTitleSafe( $row->page_namespace, $row->page_title );
+                               if ( $this->getUser()->isAllowed( 'protect' ) && $title ) {
+                                       $changeProtection = Linker::linkKnown(
+                                               $title,
+                                               $this->msg( 'protect_change' )->escaped(),
+                                               array(),
+                                               array( 'action' => 'unprotect' )
+                                       );
+                                       $formatted .= ' ' . Html::rawElement(
+                                               'span',
+                                               array( 'class' => 'mw-protectedpages-actions' ),
+                                               $this->msg( 'parentheses' )->rawParams( $changeProtection )->escaped()
+                                       );
+                               }
+                               break;
+
+                       case 'log_user':
+                               // when timestamp is null, this is a old protection row
+                               if ( $row->log_timestamp === null ) {
+                                       $formatted = Html::rawElement(
+                                               'span',
+                                               array( 'class' => 'mw-protectedpages-unknown' ),
+                                               $this->msg( 'protectedpages-unknown-performer' )->escaped()
+                                       );
+                               } else {
+                                       $username = UserCache::singleton()->getProp( $value, 'name' );
+                                       if ( LogEventsList::userCanBitfield( $row->log_deleted, LogPage::DELETED_USER, $this->getUser() ) ) {
+                                               if ( $username === false ) {
+                                                       $formatted = htmlspecialchars( $value );
+                                               } else {
+                                                       $formatted = Linker::userLink( $value, $username )
+                                                               . Linker::userToolLinks( $value, $username );
+                                               }
+                                       } else {
+                                               $formatted = $this->msg( 'rev-deleted-user' )->escaped();
+                                       }
+                                       if ( LogEventsList::isDeleted( $row, LogPage::DELETED_USER ) ) {
+                                               $formatted = '<span class="history-deleted">' . $formatted . '</span>';
+                                       }
+                               }
+                               break;
+
+                       case 'pr_params':
+                               $params = array();
+                               // Messages: restriction-level-sysop, restriction-level-autoconfirmed
+                               $params[] = $this->msg( 'restriction-level-' . $row->pr_level )->escaped();
+                               if ( $row->pr_cascade ) {
+                                       $params[] = $this->msg( 'protect-summary-cascade' )->text();
+                               }
+                               $formatted = $this->getLanguage()->commaList( $params );
+                               break;
+
+                       case 'log_comment':
+                               // when timestamp is null, this is a old protection row
+                               if ( $row->log_timestamp === null ) {
+                                       $formatted = Html::rawElement(
+                                               'span',
+                                               array( 'class' => 'mw-protectedpages-unknown' ),
+                                               $this->msg( 'protectedpages-unknown-reason' )->escaped()
+                                       );
+                               } else {
+                                       if ( LogEventsList::userCanBitfield( $row->log_deleted, LogPage::DELETED_COMMENT, $this->getUser() ) ) {
+                                               $formatted = Linker::formatComment( $value !== null ? $value : '' );
+                                       } else {
+                                               $formatted = $this->msg( 'rev-deleted-comment' )->escaped();
+                                       }
+                                       if ( LogEventsList::isDeleted( $row, LogPage::DELETED_COMMENT ) ) {
+                                               $formatted = '<span class="history-deleted">' . $formatted . '</span>';
+                                       }
+                               }
+                               break;
+
+                       default:
+                               throw new MWException( "Unknown field '$field'" );
+               }
+
+               return $formatted;
        }
 
        function getQueryInfo() {
@@ -455,14 +523,51 @@ class ProtectedPagesPager extends AlphabeticPager {
                }
 
                return array(
-                       'tables' => array( 'page_restrictions', 'page' ),
-                       'fields' => array( 'pr_id', 'page_namespace', 'page_title', 'page_len',
-                               'pr_type', 'pr_level', 'pr_expiry', 'pr_cascade' ),
-                       'conds' => $conds
+                       'tables' => array( 'page', 'page_restrictions', 'log_search', 'logging' ),
+                       'fields' => array(
+                               'pr_id',
+                               'page_namespace',
+                               'page_title',
+                               'page_len',
+                               'pr_type',
+                               'pr_level',
+                               'pr_expiry',
+                               'pr_cascade',
+                               'log_timestamp',
+                               'log_user',
+                               'log_comment',
+                               'log_deleted',
+                       ),
+                       'conds' => $conds,
+                       'join_conds' => array(
+                               'log_search' => array(
+                                       'LEFT JOIN', array(
+                                               'ls_field' => 'pr_id', 'ls_value = pr_id'
+                                       )
+                               ),
+                               'logging' => array(
+                                       'LEFT JOIN', array(
+                                               'ls_log_id = log_id'
+                                       )
+                               )
+                       )
                );
        }
 
+       public function getTableClass() {
+               return 'TablePager mw-protectedpages';
+       }
+
        function getIndexField() {
                return 'pr_id';
        }
+
+       function getDefaultSort() {
+               return 'pr_id';
+       }
+
+       function isFieldSortable( $field ) {
+               // no index for sorting exists
+               return false;
+       }
 }
index 3f9b98d..789ea76 100644 (file)
@@ -152,10 +152,6 @@ class SpecialWhatLinksHere extends SpecialPage {
                // Read an extra row as an at-end check
                $queryLimit = $limit + 1;
 
-               // Enforce join order, sometimes namespace selector may
-               // trigger filesorts which are far less efficient than scanning many entries
-               $options[] = 'STRAIGHT_JOIN';
-
                $options['LIMIT'] = $queryLimit;
                $fields = array( 'page_id', 'page_namespace', 'page_title', 'rd_from' );
 
index 311aedc..6ba9cc1 100644 (file)
@@ -207,7 +207,6 @@ $messages = array(
 'vector-action-protect' => 'Beorgan',
 'vector-action-undelete' => 'Scieppan tramet eft',
 'vector-action-unprotect' => 'Andwendan beorgunge',
-'vector-simplesearch-preference' => 'Ānfealdlīc sēcunge mearc (synderlīce on Vector scinne)',
 'vector-view-create' => 'Scieppan',
 'vector-view-edit' => 'Adihtan',
 'vector-view-history' => 'Stǣr',
@@ -280,7 +279,7 @@ $1',
 'pool-errorunknown' => 'Uncūþ wōh',
 
 # All link text and link target definitions of links into project namespace that get used by other message strings, with the exception of user group pages (see grouppage).
-'aboutsite' => 'Gecȳþness ymbe {{SITENAME}}',
+'aboutsite' => 'Gecȳþness ymbe {{GRAMMAR:wrēgendlīc|{{SITENAME}}}}',
 'aboutpage' => 'Project:Gecȳþness',
 'copyright' => 'Man mæg innunge under $1 findan.',
 'copyrightpage' => '{{ns:project}}:Gelīcnessriht',
index dc73702..259e290 100644 (file)
@@ -651,7 +651,6 @@ $messages = array(
 'vector-action-protect' => 'احم',
 'vector-action-undelete' => 'ألغ الحذف',
 'vector-action-unprotect' => 'غير الحماية',
-'vector-simplesearch-preference' => 'تفعيل شريط البحث المبسط (لمظهر فكتور فقط)',
 'vector-view-create' => 'أنشئ',
 'vector-view-edit' => 'عدل',
 'vector-view-history' => 'اعرض التاريخ',
@@ -1923,7 +1922,7 @@ $1",
 'recentchanges-legend-heading' => 'شرح',
 'recentchanges-legend-newpage' => '(راجع أيضا [[Special:NewPages|قائمة الصفحات الجديدة]])',
 'rcnotefrom' => "بالأسفل التغييرات منذ '''$2''' (إلى '''$1''' معروضة).",
-'rclistfrom' => 'أظهر التغييرات بدءا من $1',
+'rclistfrom' => 'أظهر التغييرات بدء من $1',
 'rcshowhideminor' => '$1 التعديلات الطفيفة',
 'rcshowhidebots' => '$1 البوتات',
 'rcshowhideliu' => '$1 {{GENDER:$1|مستخدمين مسجلين|مستخدمات مسجلات|مستخدمون مسجلون}}',
@@ -2487,7 +2486,7 @@ $1',
 'alphaindexline' => '$1 إلى $2',
 'nextpage' => 'الصفحة التالية ($1)',
 'prevpage' => 'الصفحة السابقة ($1)',
-'allpagesfrom' => 'اعرض Ø§Ù\84صÙ\81حات Ø¨Ø¯Ø¡Ø§Ù\8b من:',
+'allpagesfrom' => 'اعرض Ø§Ù\84صÙ\81حات Ø§Ø¨ØªØ¯Ø§Ø¡ من:',
 'allpagesto' => 'اعرض الصفحات المنتهية عند:',
 'allarticles' => 'كل الصفحات',
 'allinnamespace' => 'كل الصفحات (في نطاق $1)',
@@ -2508,7 +2507,7 @@ $1',
 'categoriespagetext' => '{{PLURAL:$1|التصنيف التالي يحتوي|التصنيفات التالية تحتوي}} على صفحات أو وسائط.
 [[Special:UnusedCategories|التصنيفات غير المستخدمة]] غير معروضة هنا.
 انظر أيضاً [[Special:WantedCategories|التصنيفات المطلوبة]].',
-'categoriesfrom' => 'أظÙ\87ر Ø§Ù\84تصÙ\86Ù\8aÙ\81ات Ø¨Ø¯Ø¡Ø§Ù\8b من:',
+'categoriesfrom' => 'اعرض Ø§Ù\84تصÙ\86Ù\8aÙ\81ات Ø§Ø¨ØªØ¯Ø§Ø¡ من:',
 'special-categories-sort-count' => 'رتب بالعدد',
 'special-categories-sort-abc' => 'رتب هجائياً',
 
@@ -2538,7 +2537,7 @@ $1',
 'activeusers' => 'قائمة المستخدمين النشطين',
 'activeusers-intro' => 'هذه قائمة بالمستخدمين الذين مارسوا نوعاً من النشاط خلال {{PLURAL:$1||اليوم الماضي|اليومين الماضيين|ال$1 أيام الماضية|ال$1 يوماً ماضياً|ال$1 يوم ماضي}}.',
 'activeusers-count' => '{{PLURAL:$1|لا أفعال|فعل واحد|فعلان اثنان|$1 أفعال|$1 فعلاً|$1 فعل}} منذ {{PLURAL:$3||يوم|يومين|$3 أيام|$3 يوماً|$1 يوم}}',
-'activeusers-from' => 'اعرض Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø¨Ø¯Ø¡Ø§Ù\8b من:',
+'activeusers-from' => 'اعرض Ø§Ù\84Ù\85ستخدÙ\85Ù\8aÙ\86 Ø§Ø¨ØªØ¯Ø§Ø¡ من:',
 'activeusers-hidebots' => 'أخف البوتات',
 'activeusers-hidesysops' => 'أخف الإداريين',
 'activeusers-noresult' => 'لم يعثر على أي مستخدمين',
index 76959a1..23291de 100644 (file)
@@ -227,7 +227,6 @@ $messages = array(
 'vector-action-protect' => 'Protexer',
 'vector-action-undelete' => 'Restaurar',
 'vector-action-unprotect' => 'Camudar la proteición',
-'vector-simplesearch-preference' => 'Activar la barra de búsqueda simplificada (namái tema Vector)',
 'vector-view-create' => 'Crear',
 'vector-view-edit' => 'Editar',
 'vector-view-history' => 'Ver historial',
@@ -737,7 +736,7 @@ Tendría de facelo si los compartió con alguién de mou accidental o si la so c
 'showpreview' => 'Amosar previsualización',
 'showlivepreview' => 'Vista rápida',
 'showdiff' => 'Amosar cambeos',
-'anoneditwarning' => "'''Avisu:''' Nun anició sesión.
+'anoneditwarning' => "<strong>Avisu:</strong> Nun anició sesión.
 La direición IP quedará grabada nel historial d'edición d'esta páxina.",
 'anonpreviewwarning' => "''Nun aniciasti sesión. Al guardar quedará rexistrada la to direición IP nel historial d'edición d'esta páxina.''",
 'missingsummary' => "'''Recordatoriu:''' Nun conseñasti un resume d'edición.
@@ -863,9 +862,9 @@ Vas tener que fusionar los tos cambios dientro del testu esistente.
 'nonunicodebrowser' => "'''Avisu: El to navegador nun cumple la norma Unicode.''' Hai un sistema alternativu que te permite editar páxines de forma segura: los caráuteres non-ASCII apaecerán nel cuadru d'edición como códigos hexadecimales.",
 'editingold' => "'''AVISU: Tas editando una revisión vieya d'esta páxina. Si la grabes, los cambios que se ficieron dende esta revisión van perdese.'''",
 'yourdiff' => 'Diferencies',
-'copyrightwarning' => "Por favor, ten en cuenta que toles collaboraciones de {{SITENAME}} considerense espublizaes baxo la $2 (ver $1 pa más detalles). Si nun quies que'l to trabayu s'edite ensin midida y se distribuya al debalu, nun lu pongas equí.<br />
-Amás tas prometiendonos qu'escribisti esto tu mesmu o que copiastilo d'una fonte llibre de dominiu públicu o asemeyao.
-'''¡Nun unvies obres con drechos d'autor ensin permisu!'''",
+'copyrightwarning' => "Por favor, ten en cuenta que toles collaboraciones de {{SITENAME}} considérense espublizaes baxo la $2 (ver $1 pa más detalles). Si nun quies que'l to trabayu s'edite ensin midida y se distribuya al debalu, nun lu pongas equí.<br />
+Amás tas prometiéndonos qu'escribisti esto tu mesmu, o que lo copiasti d'una fonte llibre, de dominiu públicu o asemeyada.
+<strong>¡Nun unvies obres con drechos d'autor ensin permisu!</strong>",
 'copyrightwarning2' => "Por favor, ten en cuenta que toles contribuciones de {{SITENAME}} se puen editar, alterar o desaniciar por otros usuarios. Si nun quies que'l to trabayu s'edite ensin midida, nun lu pongas equí.<br />
 Amás tas dexándonos afitao qu'escribisti esto tu mesmu, o que lo copiasti d'una fonte llibre de dominiu públicu o asemeyao (ver $1 pa más detalles).
 '''¡Nun pongas trabayos con drechos d'autor ensin permisu!'''",
@@ -1931,7 +1930,7 @@ Alcuérdate de comprobar otros enllaces a les plantíes enantes d'esborrales.",
 'statistics-edits' => "Ediciones de páxines dende qu'entamó {{SITENAME}}",
 'statistics-edits-average' => "Media d'ediciones por páxina",
 'statistics-views-total' => 'Visites totales',
-'statistics-views-total-desc' => "Les vistes de páxines non-esistentes y especiales nun s'incluyen",
+'statistics-views-total-desc' => "Nun s'incluyen les visites a les páxines inesistentes y especiales",
 'statistics-views-peredit' => 'Visites por edición',
 'statistics-users' => '[[Special:ListUsers|Usuarios]] rexistraos',
 'statistics-users-active' => 'Usuarios activos',
@@ -2013,6 +2012,14 @@ Les entraes <del>tachaes</del> tan resueltes.',
 'protectedpages-cascade' => 'Namái proteiciones en cascada',
 'protectedpages-noredirect' => 'Anubrir redireiciones',
 'protectedpagesempty' => 'Nun hai páxines protexíes anguaño con estos parámetros.',
+'protectedpages-timestamp' => "Marca d'hora",
+'protectedpages-page' => 'Páxina',
+'protectedpages-expiry' => 'Caduca',
+'protectedpages-performer' => 'Usuariu que protexe',
+'protectedpages-params' => 'Parámetros de proteición',
+'protectedpages-reason' => 'Motivu',
+'protectedpages-unknown-timestamp' => 'Desconocida',
+'protectedpages-unknown-performer' => 'Usuariu desconocíu',
 'protectedtitles' => 'Títulos protexíos',
 'protectedtitlesempty' => 'Nun hai títulos protexíos anguaño con estos parámetros.',
 'listusers' => "Llista d'usuarios",
@@ -2078,8 +2085,8 @@ Pues filtrar la visualización seleicionando una mena de rexistru, el nome d'usu
 
 # Special:Categories
 'categories' => 'Categoríes',
-'categoriespagetext' => "{{PLURAL:$1|La categoría darréu contién|Les categoríes darréu contienen}} páxines o ficheros multimedia.
-Les [[Special:UnusedCategories|categoríes non usaes]] nun s'amuesen equí.
+'categoriespagetext' => "{{PLURAL:$1|La siguiente categoría contién|Les siguientes categoríes contienen}} páxines o ficheros multimedia.
+Les [[Special:UnusedCategories|categoríes nun usaes]] nun s'amuesen equí.
 Ver tamién les [[Special:WantedCategories|categoríes más buscaes]].",
 'categoriesfrom' => "Amosar categoríes qu'emprimen por:",
 'special-categories-sort-count' => 'ordenar por tamañu',
@@ -2774,6 +2781,7 @@ $2",
 'thumbnail_image-type' => "Triba d'imaxe ensin sofitu",
 'thumbnail_gd-library' => 'Configuración incompleta de la biblioteca GD: falta la función $1',
 'thumbnail_image-missing' => "Paez que falta'l ficheru: $1",
+'thumbnail_image-failure-limit' => 'Hebo demasiaos intentos recientes que fallaron ($1 o más) al representar esta miniatura. Vuelva a intentalo más sero.',
 
 # Special:Import
 'import' => 'Importar páxines',
@@ -3657,7 +3665,7 @@ Por favor confirma que daveres quies volver a crear esta páxina.",
 'autosumm-blank' => 'Desaniciáu el conteníu de la páxina',
 'autosumm-replace' => "Sustituyendo la páxina por '$1'",
 'autoredircomment' => 'Redirixendo a [[$1]]',
-'autosumm-new' => "Páxina creada con '$1'",
+'autosumm-new' => 'Páxina creada con «$1»',
 
 # Size units
 'size-gigabytes' => '$1 XB',
index 25f654b..bf9a777 100644 (file)
@@ -295,7 +295,7 @@ $messages = array(
 'tog-watchlisthideliu' => 'Хаваць праўкі зарэгістраваных удзельнікаў у сьпісе назіраньня',
 'tog-watchlisthideanons' => 'Хаваць праўкі ананімаў у сьпісе назіраньня',
 'tog-watchlisthidepatrolled' => 'Хаваць патруляваныя праўкі ў сьпісе назіраньня',
-'tog-ccmeonemails' => 'Ð\94аÑ\81Ñ\8bлаць мне копіі лістоў, якія я дасылаю іншым удзельнікам',
+'tog-ccmeonemails' => 'Ð\90дпÑ\80аÑ\9eлÑ\8fць мне копіі лістоў, якія я дасылаю іншым удзельнікам',
 'tog-diffonly' => 'Не паказваць зьмест старонкі пад параўнаньнем зьменаў',
 'tog-showhiddencats' => 'Паказваць схаваныя катэгорыі',
 'tog-noconvertlink' => 'Забараніць канвэртацыю назваў спасылак',
@@ -425,7 +425,6 @@ $messages = array(
 'vector-action-protect' => 'Абараніць',
 'vector-action-undelete' => 'Аднавіць',
 'vector-action-unprotect' => 'Зьмяніць абарону',
-'vector-simplesearch-preference' => 'Уключыць спрошчанае поле пошуку (толькі для афармленьня «Вэктар»)',
 'vector-view-create' => 'Стварыць',
 'vector-view-edit' => 'Рэдагаваць',
 'vector-view-history' => 'Паказаць гісторыю',
@@ -2166,6 +2165,11 @@ $1',
 'protectedpages-cascade' => 'Толькі каскадныя абароны',
 'protectedpages-noredirect' => 'Схаваць перанакіраваньні',
 'protectedpagesempty' => 'Цяпер няма абароненых старонак з пазначанымі парамэтрамі.',
+'protectedpages-timestamp' => 'Дата і час',
+'protectedpages-page' => 'Старонка',
+'protectedpages-expiry' => 'Сканчаецца',
+'protectedpages-performer' => 'Хто абараніў',
+'protectedpages-params' => 'Парамэтры абароны',
 'protectedtitles' => 'Забароненыя старонкі',
 'protectedtitlesempty' => 'Цяпер няма абароненых назваў з пазначанымі парамэтрамі.',
 'listusers' => 'Сьпіс удзельнікаў і ўдзельніц',
@@ -2913,6 +2917,7 @@ $1',
 'allmessages-prefix' => 'Фільтар па прэфіксе:',
 'allmessages-language' => 'Мова:',
 'allmessages-filter-submit' => 'Паказаць',
+'allmessages-filter-translate' => 'Перакласьці',
 
 # Thumbnails
 'thumbnail-more' => 'Павялічыць',
@@ -2967,7 +2972,7 @@ $2',
 Не стае часовай дырэкторыі.',
 'import-parse-failure' => 'Памылка разбору XML пры імпартаваньні',
 'import-noarticle' => 'Няма старонкі для імпартаваньня!',
-'import-nonewrevisions' => 'УÑ\81е Ð²Ñ\8dÑ\80Ñ\81Ñ\96Ñ\96 Ð±Ñ\8bлÑ\96 Ñ\96мпаÑ\80Ñ\82аванÑ\8bÑ\8f Ñ\80аней.',
+'import-nonewrevisions' => 'Ð\9dÑ\96Ñ\8fкÑ\96Ñ\8f Ð¿Ñ\80аÑ\9eкÑ\96 Ð½Ðµ Ð±Ñ\8bлÑ\96 Ñ\96мпаÑ\80Ñ\82аванÑ\8bÑ\8f (Ñ\83Ñ\81е Ñ\9eжо Ð°Ð±Ð¾ Ð±Ñ\8bлÑ\96 Ð°Ð¿Ñ\80аÑ\86аванÑ\8bÑ\8f, Ð°Ð±Ð¾ Ð¿Ñ\80апÑ\83Ñ\88Ñ\87анÑ\8bÑ\8f Ð¿Ñ\80аз Ð¿Ð°Ð¼Ñ\8bлкÑ\96).',
 'xml-error-string' => '$1 у радку $2, пазыцыі $3 (байт $4): $5',
 'import-upload' => 'Загрузіць XML-зьвесткі',
 'import-token-mismatch' => 'Страчаныя зьвесткі сэсіі. Калі ласка, паспрабуйце ізноў.',
@@ -3116,7 +3121,7 @@ $2',
 'pageinfo-robot-noindex' => 'Не дазволеная',
 'pageinfo-views' => 'Колькасьць праглядаў',
 'pageinfo-watchers' => 'Колькасьць назіральнікаў і назіральніц',
-'pageinfo-few-watchers' => 'Менш за $1 {{PLURAL:$1|1=назіральніка|назіральнікаў}}',
+'pageinfo-few-watchers' => 'Менш за $1 {{PLURAL:$1|назіральніка|назіральнікі|назіральнікаў}}',
 'pageinfo-redirects-name' => 'Перанакіраваньняў на гэтую старонку',
 'pageinfo-subpages-name' => 'Колькасьць падстаронак',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|перанакіраваньне|перанакіраваньні|перанакіраваньняў}}; $3 {{PLURAL:$3|звычайная|звычайныя|звычайных}})',
index 692311c..b365b72 100644 (file)
@@ -235,7 +235,6 @@ $messages = array(
 'vector-action-protect' => 'সুরক্ষা',
 'vector-action-undelete' => 'পুনরুদ্ধার',
 'vector-action-unprotect' => 'সুরক্ষা পরিবর্তন',
-'vector-simplesearch-preference' => 'সরল অনুসন্ধান সক্রিয় করুন (শুধুমাত্র ভেক্টর স্কিনের জন্য)',
 'vector-view-create' => 'তৈরি',
 'vector-view-edit' => 'সম্পাদনা',
 'vector-view-history' => 'ইতিহাস',
@@ -1956,6 +1955,11 @@ Maybe you want to edit the description on its [$2 file description page] there.'
 'protectedpages-cascade' => 'শুধুমাত্র প্রপাতাকার সুরক্ষা',
 'protectedpages-noredirect' => 'পুনর্নির্দেশনাগুলো লুকাও',
 'protectedpagesempty' => 'কোন পাতা বর্তমানে এই প্যারামিটারগুলিসহ সুরক্ষিত নয়।',
+'protectedpages-page' => 'পাতা',
+'protectedpages-params' => 'সুরক্ষা প্যারামিটার',
+'protectedpages-reason' => 'কারণ',
+'protectedpages-unknown-timestamp' => 'অজানা',
+'protectedpages-unknown-performer' => 'অজানা ব্যবহারকারী',
 'protectedtitles' => 'সুরক্ষিত শিরোনামগুলি',
 'protectedtitlesempty' => 'কোন শিরোনাম বর্তমানে এই প্যারামিটারগুলিসহ সুরক্ষিত নয়।',
 'listusers' => 'ব্যবহারকারীর তালিকা',
index 9ee95a8..f8fdb42 100644 (file)
@@ -343,7 +343,6 @@ $messages = array(
 'vector-action-protect' => 'Gwareziñ',
 'vector-action-undelete' => 'Diziverkañ',
 'vector-action-unprotect' => 'Cheñch gwarez',
-'vector-simplesearch-preference' => "Aotren ar c'hinnigoù klask gwellaet (gant Vektor nemetken)",
 'vector-view-create' => 'Krouiñ',
 'vector-view-edit' => 'Kemmañ',
 'vector-view-history' => 'Gwelet an istor',
@@ -626,6 +625,8 @@ Na zisoñjit ket resisaat ho [[Special:Preferences|penndibaboù evit {{SITENAME}
 'userlogin-resetpassword-link' => 'Ankouaet ho peus ho ker-tremen ?',
 'helplogin-url' => 'Help:Kevreañ',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Skoazell evit kevreañ]]',
+'userlogin-loggedin' => "Kevreet oc'h dija evel {{GENDER:$1|$1}}.
+Implijit ar furmskrid amañ dindan evit kevreañ evel un implijer all.",
 'userlogin-createanother' => 'Krouiñ ur gont all',
 'createacct-join' => 'Skrivit ho titouroù amañ dindan.',
 'createacct-another-join' => 'Ebarzhiñ titouroù ar gont nevez amañ dindan.',
@@ -729,6 +730,8 @@ Gortozit $1, mar plij, a-raok esaeañ en-dro.",
 'retypenew' => 'Adskrivañ ar ger-tremen nevez :',
 'resetpass_submit' => 'Cheñch ar ger-tremen ha kevreañ',
 'changepassword-success' => 'Cheñchet eo bet ho ker-tremen !',
+'changepassword-throttled' => "Betek re hoc'h heus klasket kevreañ en aner.
+Gortozit $1, mar plij, a-raok esaeañ en-dro.",
 'resetpass_forbidden' => "N'haller ket cheñch ar gerioù-termen",
 'resetpass-no-info' => "Ret eo deoc'h bezañ kevreet a-benn mont d'ar bajenn-se war-eeun.",
 'resetpass-submit-loggedin' => 'Cheñch ger-tremen',
@@ -779,6 +782,8 @@ Ger-tremen da c'hortoz : $2",
 'changeemail-password' => 'Ho ker-tremen war {{SITENAME}}:',
 'changeemail-submit' => "Cheñch chomlec'h postel",
 'changeemail-cancel' => 'Nullañ',
+'changeemail-throttled' => "Betek re hoc'h heus klasket kevreañ en aner.
+Gortozit $1, mar plij, a-raok esaeañ en-dro.",
 
 # Special:ResetTokens
 'resettokens' => 'Adderaouekaat ar jedoueroù',
@@ -1026,6 +1031,7 @@ A-gostez eo bet lezet an arventenn-se.',
 'undo-success' => "Gallout a reer dizober ar c'hemmoù-mañ. Gwiriit, mar plij, gant ar geñveriadenn a-is evit bezañ sur eo an dra-se a fell deoc'h ober; goude-se enrollit ar c'hemmoù a-is a-benn echuiñ disteurel ar c'hemmoù.",
 'undo-failure' => "N'eus ket bet tu da zisteuler ar c'hemm-mañ abalamour d'un tabut gant kemmoù degaset e-keit-se.",
 'undo-norev' => "N'eus ket bet gallet degas ar c'hemmoù-mañ rak pe n'eus ket anezho pe int bet diverket.",
+'undo-nochange' => "War a seblant eo bet nullet ar c'hemm dija.",
 'undo-summary' => 'Dizober kemmoù $1 a-berzh [[Special:Contributions/$2|$2]] ([[User talk:$2|kaozeal]])',
 'undo-summary-username-hidden' => 'Dizober ar reizhadenn $1 gant un implijer kuzhet',
 
@@ -1236,6 +1242,7 @@ Gallout a reot kavout munudoù e [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'search-result-score' => 'Klotadusted : $1%',
 'search-redirect' => '(adkas $1)',
 'search-section' => '(rann $1)',
+'search-file-match' => "(klotañ a ra gant endalc'had ar restr)",
 'search-suggest' => "N'hoc'h eus ket soñjet kentoc'h e : $1",
 'search-interwiki-caption' => 'Raktresoù kar',
 'search-interwiki-default' => "$1 disoc'h :",
@@ -1522,8 +1529,8 @@ Ma skrivit anezhañ e vo implijet evit lakaat war wel ar pezh a vo bet degaset g
 'action-block' => 'mirout ouzh an impplijer-mañ da zegas kemmoù',
 'action-protect' => 'kemmañ liveoù gwareziñ ar bajenn-mañ',
 'action-rollback' => 'disteuler prim kemmoù an implijer diwezhañ kemmet gantañ ur bajenn resis',
-'action-import' => 'Enporzhiañ ar bajenn-mañ adal ur wiki all',
-'action-importupload' => 'Enporzhiañ ar bajenn-mañ adal ur restr pellgarget',
+'action-import' => 'Enporzhiañ pajennoù eus ur wiki all',
+'action-importupload' => 'Enporzhiañ pajennoù eus ur restr pellgarget',
 'action-patrol' => 'merkañ kemmoù ar re all evel gwiriet',
 'action-autopatrol' => 'bezañ merket ho tegasadennoù evel gwiriet',
 'action-unwatchedpages' => "gwelet roll ar pajennoù n'int ket evezhiet",
@@ -2051,6 +2058,14 @@ $1 {{PLURAL:$1|rummad|rummad}}',
 'protectedpages-cascade' => 'Gwarez dre skalierad hepken',
 'protectedpages-noredirect' => 'Kuzhat an adkasoù',
 'protectedpagesempty' => "N'eus pajenn gwarezet ebet gant an arventennoù-mañ evit poent.",
+'protectedpages-timestamp' => 'Deiziad hag eur',
+'protectedpages-page' => 'Pajenn',
+'protectedpages-expiry' => "A ya d'e dermen",
+'protectedpages-performer' => 'Gwareziñ an implijer',
+'protectedpages-params' => 'Arventennoù gwareziñ',
+'protectedpages-reason' => 'Abeg',
+'protectedpages-unknown-timestamp' => 'Dianav',
+'protectedpages-unknown-performer' => 'Implijer dianav',
 'protectedtitles' => 'Titloù gwarezet',
 'protectedtitlesempty' => "N'eus bet gwarezet titl ebet dezhañ an arventennoù-se evit poent.",
 'listusers' => 'Roll an implijerien',
@@ -2787,6 +2802,7 @@ Kit da welet [https://www.mediawiki.org/wiki/Localisation Lec'heladur MediaWiki]
 'allmessages-prefix' => 'Silañ dre rakger',
 'allmessages-language' => 'Yezh :',
 'allmessages-filter-submit' => 'Mont',
+'allmessages-filter-translate' => 'Treiñ',
 
 # Thumbnails
 'thumbnail-more' => 'Brasaat',
@@ -3079,7 +3095,7 @@ Ma vez erounezet ganeoc'h e c'hallje tagañ ho reizhiad.",
 'svg-long-desc' => 'restr SVG file, pizhder $1 × $2 piksel, ment ar restr : $3',
 'svg-long-desc-animated' => 'Restr SVG bev, ment $1 × $2 piksel, ment ar restr: $3',
 'svg-long-error' => 'Restr SVG direizh : $1',
-'show-big-image' => 'Pizhder leun',
+'show-big-image' => 'Restr orin',
 'show-big-image-preview' => 'Ment ar rakweled-mañ : $1.',
 'show-big-image-other' => '{{PLURAL:$2|pizhder all|pizhderioù all}} : $1.',
 'show-big-image-size' => '$1 × $2 piksel',
@@ -3645,6 +3661,7 @@ Kadarnait mar plij e fell deoc'h krouiñ ar pennad-mañ da vat.",
 
 # Language selector for translatable SVGs
 'img-lang-default' => '(yezh dre ziouer)',
+'img-lang-info' => 'Diskouez ar skeudenn-mañ e $1. $2',
 'img-lang-go' => 'Mont',
 
 # Table pager
@@ -4005,9 +4022,8 @@ A-hend-all e c'hallit ober gant ar furmskrid eeunaet dindan. Ouzhpennet e vo hoc
 'expandtemplates' => 'Emled ar patromoù',
 'expand_templates_intro' => "Kemer a ra ar bajenn dibar-mañ tammoù testenn hag astenn a ra an holl batromoù enni en un doare azkizat.
 Astenn a ra ivez an arc'hwelioù parser evel
-<nowiki>{{</nowiki>#language:…}}, hag an argemmoù evel
-<nowiki>{{</nowiki>CURRENTDAY}}&mdash; e gwirionez, koulz lavaret kement tra zo etre briataennoù.
-Ober a ra kement-mañ dre c'hervel ar bazenn a zegouezh digant parser MediaWiki e-unan.",
+<code><nowiki>{{</nowiki>#language:…}}</code>, hag an argemmoù evel
+<code><nowiki>{{</nowiki>CURRENTDAY}}</code. E gwirionez, koulz lavaret kement tra zo etre briataennoù doubl.",
 'expand_templates_title' => 'Titl ar gendestenn, evit {{FULLPAGENAME}} h.a. :',
 'expand_templates_input' => 'Merkañ ho testenn amañ :',
 'expand_templates_output' => "Disoc'h",
index 8530d68..d09fa00 100644 (file)
@@ -483,7 +483,6 @@ $messages = array(
 'vector-action-protect' => 'Гlаролла дé',
 'vector-action-undelete' => 'Меттахlоттадé',
 'vector-action-unprotect' => 'ГӀароллех къаста',
-'vector-simplesearch-preference' => 'Атта лахаран хьехар лата де («Векторан» кечярна бен)',
 'vector-view-create' => 'Кхоллар',
 'vector-view-edit' => 'Нисйé',
 'vector-view-history' => 'АгӀона хийцамаш',
@@ -1167,6 +1166,7 @@ $1",
 # Search results
 'searchresults' => 'Лахарна хилам',
 'searchresults-title' => 'Лаха «$1»',
+'titlematches' => 'АгӀонийн цӀераш цхьаьнанисялар',
 'notextmatches' => 'Агlонаш чура йозанашца цхьатера йогlуш яц',
 'prevn' => 'хьалхарнаш {{PLURAL:$1|$1}}',
 'nextn' => 'тӀаьхьйогӀурш {{PLURAL:$1|$1}}',
@@ -1750,6 +1750,14 @@ PICT # тайп тайпан
 'protectedpages' => 'ГIаролла дина агIонаш',
 'protectedpages-indef' => 'Хан йоцуш гӀоралла динарш бен',
 'protectedpages-cascade' => 'Чахчарин гӀоралла бен',
+'protectedpages-timestamp' => 'Терахь/хан',
+'protectedpages-page' => 'АгӀо',
+'protectedpages-expiry' => 'Чекхйолу',
+'protectedpages-performer' => 'Декъашхо ларор',
+'protectedpages-params' => 'ГӀаролийн параметраш',
+'protectedpages-reason' => 'Бахьан',
+'protectedpages-unknown-timestamp' => 'Хууш дац',
+'protectedpages-unknown-performer' => 'Хууш доцу декъашхо',
 'protectedtitles' => 'ГIаролла дина цIераш',
 'listusers' => 'Декъашхой могlам',
 'listusers-editsonly' => 'Цхаъ мукъане а хийцам бина декъашхой гайта',
index 4f3531a..5b9aec3 100644 (file)
@@ -530,7 +530,6 @@ $messages = array(
 'vector-action-protect' => 'Zamknout',
 'vector-action-undelete' => 'Obnovit',
 'vector-action-unprotect' => 'Změnit zámek',
-'vector-simplesearch-preference' => 'Zapnout zjednodušené vyhledávání (pouze vzhled Vektor)',
 'vector-view-create' => 'Založit',
 'vector-view-edit' => 'Editovat',
 'vector-view-history' => 'Zobrazit historii',
@@ -2270,6 +2269,14 @@ Každý řádek obsahuje odkaz na první a druhé přesměrování a k tomu cíl
 'protectedpages-cascade' => 'Pouze kaskádové zámky',
 'protectedpages-noredirect' => 'Skrýt přesměrování',
 'protectedpagesempty' => 'Žádná stránka není zamčena s těmito parametry.',
+'protectedpages-timestamp' => 'Datum a čas',
+'protectedpages-page' => 'Stránka',
+'protectedpages-expiry' => 'Vyprší',
+'protectedpages-performer' => 'Zamykající',
+'protectedpages-params' => 'Nastavení zámku',
+'protectedpages-reason' => 'Důvod',
+'protectedpages-unknown-timestamp' => 'Neznámé',
+'protectedpages-unknown-performer' => 'Neznámý uživatel',
 'protectedtitles' => 'Zamčené názvy stránek',
 'protectedtitlesempty' => 'S těmito parametry nejsou zamčeny žádné názvy.',
 'listusers' => 'Uživatelé',
@@ -3016,6 +3023,7 @@ $2',
 'thumbnail_image-type' => 'Nepodporovaný typ obrázku',
 'thumbnail_gd-library' => 'Neúplná konfigurace knihovny GD: chybí funkce $1',
 'thumbnail_image-missing' => 'Soubor patrně chybí: $1',
+'thumbnail_image-failure-limit' => 'V poslední době došlo k příliš mnoha neúspěšným pokusům (nejméně $1) o vytvoření tohoto náhledu. Zkuste to později.',
 
 # Special:Import
 'import' => 'Import stránek',
index 6c11cc1..5b194d8 100644 (file)
@@ -281,7 +281,6 @@ $messages = array(
 'vector-action-protect' => 'Diogelu',
 'vector-action-undelete' => 'Adfer',
 'vector-action-unprotect' => 'Newid y diogelwch',
-'vector-simplesearch-preference' => 'Galluogi bar chwilio syml (gwedd Vector yn unig)',
 'vector-view-create' => 'Dechrau',
 'vector-view-edit' => 'Golygu',
 'vector-view-history' => 'Gweld yr hanes',
@@ -927,7 +926,7 @@ Mae ar gael yn barod.',
 'invalid-content-data' => "Data annilys i'r cynnwys",
 'content-not-allowed-here' => 'Nid yw cynnwys ar ffurf "$1" yn cael ei ganiatau ar y dudalen [[$2]]',
 'editwarning-warning' => 'Os y gadewch y dudalen hon mae\'n bosib y collwch eich newidiadau iddi.
-Os ydych wedi mewngofnodi gallwch ddiddymu\'r rhybudd hwn yn yr adran "Golygu" yn eich dewisiadau.',
+Os ydych wedi mewngofnodi gallwch ddiddymu\'r rhybudd hwn yn yr adran "{{int:prefs-editing}}" yn eich dewisiadau.',
 
 # Content models
 'content-model-wikitext' => 'cystrawen wici',
@@ -1161,7 +1160,7 @@ Mae manylion pellach i'w cael yn [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'shown-title' => 'Dangos $1 {{PLURAL:$1|canlyiad|canlyniad|ganlyniad|chanlyniad|chanlyniad|canlyniad}} y dudalen',
 'viewprevnext' => 'Dangos ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''Mae tudalen o'r enw \"[[\$1]]\" ar y wici hwn'''",
-'searchmenu-new' => "'''Creu'r dudalen \"[[:\$1]]\" ar y wici hwn!'''",
+'searchmenu-new' => "'''Creu'r dudalen \"[[:\$1]]\" ar y wici hwn!''' {{PLURAL:\$2||Gweler hefyd y dudalen a ganfyddwyd wrth chwilio.|Gweler hefyd y canlyniadau chwilio.}}",
 'searchprofile-articles' => 'Tudalennau pwnc (erthyglau/ffeiliau)',
 'searchprofile-project' => 'Tudalennau Cymorth a Phrosiect',
 'searchprofile-images' => 'Ffeiliau amlgyfrwng',
@@ -1999,6 +1998,14 @@ Gosodwyd <del>llinell</del> drwy'r eitemau sydd eisoes wedi eu datrys.",
 'protectedpages-cascade' => 'A sgydol-ddiogelwyd yn unig',
 'protectedpages-noredirect' => 'Cuddio ailgyfeiriadau',
 'protectedpagesempty' => "Does dim tudalennau wedi eu diogelu gyda'r paramedrau hyn.",
+'protectedpages-timestamp' => 'Stamp amser',
+'protectedpages-page' => 'Tudalen',
+'protectedpages-expiry' => 'Daw i ben',
+'protectedpages-performer' => 'Y diogelwr',
+'protectedpages-params' => "Paramedrau'r diogelu",
+'protectedpages-reason' => 'Rheswm',
+'protectedpages-unknown-timestamp' => 'Anhysbys',
+'protectedpages-unknown-performer' => 'Defnyddiwr anhysbys',
 'protectedtitles' => 'Teitlau wedi eu diogelu',
 'protectedtitlesempty' => "Ar hyn o bryd nid oes unrhyw deitlau wedi eu diogelu a'r paramedrau hyn.",
 'listusers' => 'Rhestr defnyddwyr',
@@ -2274,7 +2281,7 @@ Gwelwch y $2 am gofnod o\'r dileuon diweddar.',
 Cyfyngwyd ar y gallu i ddileu tudalennau sydd wedi eu golygu cymaint â hyn, er mwyn osgoi amharu ar weithrediad databas {{SITENAME}} yn ddamweiniol.",
 'delete-warning-toobig' => "Cafwyd dros $1 {{PLURAL:$1|o olygiadau}} i'r dudalen hon.
 Gallai dileu tudalen, gyda hanes golygu cymaint â hyn iddi, beri dryswch i weithrediadau'r databas ar {{SITENAME}}; ewch ati'n ofalus.",
-'deleting-backlinks-warning' => "'''Rhybudd:''' Mae tudalennau eraill yn cysylltu i'r dudalen yr ydych ar fin ei dileu.",
+'deleting-backlinks-warning' => "'''Rhybudd:''' Mae tudalennau eraill yn cysylltu i'r dudalen yr ydych ar fin ei dileu, neu'n trawsgynnwys y dudalen hon.",
 
 # Rollback
 'rollback' => 'Gwrthdroi golygiadau',
@@ -2575,7 +2582,7 @@ Gallwch weld rhestr y rhwystrau a'r gwaharddiadau sydd yn weithredol ar hyn o br
 'range_block_disabled' => 'Nid oes modd i weinyddwyr greu rhwystrau ystod.',
 'ipb_expiry_invalid' => 'Amser terfynu yn annilys.',
 'ipb_expiry_temp' => "Mae'n rhaid i rwystr ar ddefnyddiwr fod yn barhaus os am guddio'r enw.",
-'ipb_hide_invalid' => "Ddim yn gallu cuddio'r cyfrif hwn; efallai bod ganddo ormod o olygiadau.",
+'ipb_hide_invalid' => "Ddim yn gallu cuddio'r cyfrif hwn; mae mwy {{PLURAL:$1||nag 1 golygiad|na $1 olygiad|na $1 golygiad}} iddo.",
 'ipb_already_blocked' => 'Mae "$1" eisoes wedi\'i rwystro',
 'ipb-needreblock' => "Mae $1 wedi' rwystro'n barod. A ydych am newid y gosodiadau?",
 'ipb-otherblocks-header' => '{{PLURAL:$1|Rhwystr|Rhwystr|Rhwystrau|Rhwystrau|Rhwystrau|Rhwystrau}} eraill',
@@ -2745,6 +2752,7 @@ Os ydych am gyfrannu at y gwaith o gyfieithu ar gyfer holl prosiectau MediaWiki
 'allmessages-prefix' => 'Hidlo yn ôl rhagddodiad:',
 'allmessages-language' => 'Iaith:',
 'allmessages-filter-submit' => 'Eler',
+'allmessages-filter-translate' => 'Cyfieithu',
 
 # Thumbnails
 'thumbnail-more' => 'Chwyddo',
@@ -2798,7 +2806,7 @@ Dim ond rhan o'r ffeil sydd wedi ei huwchlwytho.",
 Mae ffolder dros dro yn eisiau.',
 'import-parse-failure' => "Wedi methu dosrannu'r mewnforiad XML",
 'import-noarticle' => "Ni chafwyd tudalen i'w mewnforio!",
-'import-nonewrevisions' => "Mae'r holl ddiwygiadau eisoes wedi eu mewnforio.",
+'import-nonewrevisions' => 'Ni fewnforwyd unrhyw ddiwygiadau (y cwbl eisoes yn bresennol, neu wedi eu hepgor oherwydd eu bod yn wallus).',
 'xml-error-string' => '$1 ar linell $2, col $3 (beit $4): $5',
 'import-upload' => 'Uwchlwytho data XML',
 'import-token-mismatch' => "Collwyd data'r sesiwn. Ceisiwch eto.",
@@ -3946,7 +3954,10 @@ Defnydd:
 'expand_templates_ok' => 'Iawn',
 'expand_templates_remove_comments' => 'Peidio â dangos sylwadau',
 'expand_templates_remove_nowiki' => "Cuddio'r tagiau <nowiki> wrth ehangu",
+'expand_templates_generate_xml' => 'Dangos y goeden dosrannu XML',
 'expand_templates_generate_rawhtml' => 'Dangos HTML crai',
 'expand_templates_preview' => 'Rhagolwg',
 
+# Unknown messages
+'uploadinvalidxml' => "Ni ellid dosrannu'r XML yn y ffeil a uwchlwythwyd.",
 );
index df6c555..83bbb66 100644 (file)
@@ -588,7 +588,6 @@ $messages = array(
 'vector-action-protect' => 'Schützen',
 'vector-action-undelete' => 'Wiederherstellen',
 'vector-action-unprotect' => 'Seitenschutz ändern',
-'vector-simplesearch-preference' => 'Vereinfachte Suchleiste aktivieren (nur Vector)',
 'vector-view-create' => 'Erstellen',
 'vector-view-edit' => 'Bearbeiten',
 'vector-view-history' => 'Versionsgeschichte',
@@ -2336,10 +2335,20 @@ Jede Zeile enthält Links zur ersten und zweiten Weiterleitung sowie dem Ziel de
 'deadendpagestext' => 'Die folgenden Seiten verweisen nicht auf andere Seiten von {{SITENAME}}.',
 'protectedpages' => 'Geschützte Seiten',
 'protectedpages-indef' => 'Nur unbeschränkt geschützte Seiten zeigen',
+'protectedpages-summary' => 'Diese Seite listet vorhandene Seiten auf, die derzeit geschützt sind. Für eine Liste vor Erstellung geschützter Titel, siehe [[{{#special:ProtectedTitles}}]].',
 'protectedpages-cascade' => 'Nur Seiten mit Kaskadenschutz',
 'protectedpages-noredirect' => 'Weiterleitungen ausblenden',
 'protectedpagesempty' => 'Aktuell sind keine Seiten mit diesen Parametern geschützt.',
+'protectedpages-timestamp' => 'Zeitstempel',
+'protectedpages-page' => 'Seite',
+'protectedpages-expiry' => 'Gültig bis',
+'protectedpages-performer' => 'Geschützt von',
+'protectedpages-params' => 'Schutzparameter',
+'protectedpages-reason' => 'Grund',
+'protectedpages-unknown-timestamp' => 'Unbekannt',
+'protectedpages-unknown-performer' => 'Unbekannter Benutzer',
 'protectedtitles' => 'Geschützte Seitennamen',
+'protectedtitles-summary' => 'Diese Seite listet Titel auf, die derzeit vor der Erstellung geschützt sind. Für eine Liste vorhandener geschützter Seiten, siehe [[{{#special:ProtectedPages}}]].',
 'protectedtitlesempty' => 'Zurzeit sind mit den angegebenen Parametern keine Seiten zur Neuerstellung gesperrt.',
 'listusers' => 'Benutzerverzeichnis',
 'listusers-editsonly' => 'Zeige nur Benutzer mit Beiträgen',
@@ -3084,6 +3093,7 @@ $2',
 'thumbnail_image-type' => 'Bildtyp nicht unterstützt',
 'thumbnail_gd-library' => 'Unvollständige Konfiguration der GD-Bibliothek: Fehlende Funktion $1',
 'thumbnail_image-missing' => 'Datei scheint fehlend zu sein: $1',
+'thumbnail_image-failure-limit' => 'Es wurden in letzter Zeit zu viele Versuche ($1 oder mehr) unternommen, dieses Vorschaubild zu rendern. Bitte versuche es später erneut.',
 
 # Special:Import
 'import' => 'Seiten importieren',
index 7e6a757..d6c1cbf 100644 (file)
@@ -354,7 +354,7 @@ $messages = array(
 'tog-enotifminoredits' => 'Pelan de vurnayışanê qıckekan u dosyan de ki mı rê e-mail bırışe',
 'tog-enotifrevealaddr' => 'Adresa e-posteyê mı posteyê xeberan de bımocne',
 'tog-shownumberswatching' => 'Amarê karberanê seyrkerdoğan bımocne',
-'tog-oldsig' => 'İmza mewcude:',
+'tog-oldsig' => 'İmzaya mewcude:',
 'tog-fancysig' => 'İmza rê mameleyê wikimeqaley bıke (bê gıreyo otomatik)',
 'tog-uselivepreview' => 'Verqayto giyane bıgureyne (cerrebane)',
 'tog-forceeditsummary' => 'Mı ke xulasa veng verdaye, hay a mı ser de',
@@ -496,7 +496,6 @@ $messages = array(
 'vector-action-protect' => 'Bışevekne',
 'vector-action-undelete' => 'Esterıtışi peyser bıgê',
 'vector-action-unprotect' => 'Starkerdışi bıvurne',
-'vector-simplesearch-preference' => 'Çuweya cı geyreyış de rehater aktiv ke (Tenya vector skin de)',
 'vector-view-create' => 'Vıraze',
 'vector-view-edit' => 'Bıvurne',
 'vector-view-history' => 'Verênan bıvêne',
@@ -642,7 +641,7 @@ $1',
 'nstab-user' => 'Pela karberi',
 'nstab-media' => 'Pera Medya',
 'nstab-special' => 'Pela xase',
-'nstab-project' => 'Pera proci',
+'nstab-project' => 'Pela procey',
 'nstab-image' => 'Dosya',
 'nstab-mediawiki' => 'Mesac',
 'nstab-template' => 'Şablon',
@@ -965,9 +964,9 @@ Kerem ke verdi dekewten $1 bıpawe.',
 'bold_tip' => 'Metno qalın',
 'italic_sample' => 'Metno çewt',
 'italic_tip' => 'Metno çewt',
-'link_sample' => 'Namey gırey',
-'link_tip' => 'Gırey miyani',
-'extlink_sample' => 'http://www.misal.com sernamey gırey',
+'link_sample' => 'Sernameyê gırey',
+'link_tip' => 'Gıreyê miyani',
+'extlink_sample' => 'http://www.misal.com sernameyê gırey',
 'extlink_tip' => 'Gırey teberi (xo vira mekerên http:// prefix)',
 'headline_sample' => 'metnê sernamey',
 'headline_tip' => 'Sewiya 2ıne sername',
@@ -976,7 +975,7 @@ Kerem ke verdi dekewten $1 bıpawe.',
 'image_sample' => 'Misal resim.jpg',
 'image_tip' => 'Dosya tewrkerdiye',
 'media_sample' => 'misal.jpg',
-'media_tip' => 'Gırey dosya',
+'media_tip' => 'Gıreyê dosya',
 'sig_tip' => 'İmzay şıma be morê zemani',
 'hr_tip' => 'Xeta verardiye (teserrufın bıgureyne/bıxebetne)',
 
@@ -1160,8 +1159,8 @@ Pel ca ra esto.',
 'content-failed-to-parse' => 'Qandê madela $3 zereyê $1, $2 sero nêagozyayo',
 'invalid-content-data' => 'Zerrey malumati nêravêrdeyo',
 'content-not-allowed-here' => '"$1" sero per da [[$2]] rê mısade nêdeyêno',
-'editwarning-warning' => 'ihtimal o ke wexta şıma peli ra bıveci, vurnayiş o ke şıma kerdo, hewna şiyêro .
-eke şıma kewtê hesabê xo, no hişyari tercihanê xo ra şıma eşkeni "Vurnayış"\'i vındarne.',
+'editwarning-warning' => 'Wexto ke şıma na pele ra veciyê, beno ke vurnayışê şıma vindi bê.
+Eke şıma kewtê hesabê xo, şıma şenê nê balantışi qısmê "{{int:prefs-editing}}"i de tercihanê xo ra bıvındarnê.',
 'editpage-notsupportedcontentformat-title' => 'Formatê zerreki qebul nêbeno',
 
 # Content models
@@ -1409,7 +1408,7 @@ Detayê besternayışi [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}
 'search-result-score' => 'Eleqa: $1%',
 'search-redirect' => '($1 ra ardış)',
 'search-section' => '(qısmê $1)',
-'search-file-match' => '(zerrey dosya yeno pıro)',
+'search-file-match' => '(zerreyê dosya yewbini gêno)',
 'search-suggest' => 'To va: $1',
 'search-interwiki-caption' => 'Projey Bıray',
 'search-interwiki-default' => '$1 neticeyan:',
@@ -1461,7 +1460,7 @@ Detayê besternayışi [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}
 'prefs-rendering' => 'Asayış',
 'saveprefs' => 'Qeyd ke',
 'restoreprefs' => 'Sazanê hesıbyaya pêron newe ke',
-'prefs-editing' => 'Cay pela nustısi',
+'prefs-editing' => 'Vurnayış',
 'rows' => 'Xeti:',
 'columns' => 'Estûni:',
 'searchresultshead' => 'Cı geyre',
@@ -1514,12 +1513,12 @@ Na game tepeya nêerziyena.',
 'yourlanguage' => 'Zıwan:',
 'yourvariant' => 'Varyante miyandê zuwani:',
 'prefs-help-variant' => 'Zerrey ena viki mocnayışi rê varyant yana ortografi re şıre tercihan dê xo.',
-'yournick' => 'imza:',
+'yournick' => 'Leqebe:',
 'prefs-help-signature' => 'Peran de vatenana de vatışi"<nowiki>~~~~</nowiki>" ya do imza bé, no bahdo beno çerğé imza u wahdey zemani',
 'badsig' => 'Îmzayê tu raşt niyo.
 Etiketê HTMLî kontrol bike.',
 'badsiglength' => 'İmzaya şıma zaf derga.
-$1 gani {{PLURAL:$1|karakter|karakteran}} ra şenık bo.',
+A gani be $1 {{PLURAL:$1|karakter|karakteran}} ra zêde mebo.',
 'yourgender' => 'Çıçiy cı esto?',
 'gender-unknown' => 'Ez detay nivana',
 'gender-male' => 'Perané wiki camérd deyne ezo vırnena',
@@ -1730,7 +1729,7 @@ Eka tu wazene ke nameyo raşt xo bide, ma nameyo raşt ti iştirakanê ti de moc
 'recentchanges' => 'Vurnayışê peyêni',
 'recentchanges-legend' => 'Tercihê vurnayışanê peyênan',
 'recentchanges-summary' => 'Ena pele de wiki sero vurnayışanê peyênan teqib ke.',
-'recentchanges-noresult' => 'Zey kiterandé şıma vırnayış névineya',
+'recentchanges-noresult' => 'Goreyê kriteranê kıfşkerdeyan ra qet yew vurnayış nêvêniya.',
 'recentchanges-feed-description' => 'Ena feed dı vurnayişanê tewr peniyan teqip bık.',
 'recentchanges-label-newpage' => 'Enê vurnayışi ra yew pela newiye vıraziye',
 'recentchanges-label-minor' => 'Eno yew vurnayışo werdiyo',
@@ -2033,7 +2032,7 @@ keyepel nıka zaf meşğulo yew dema herayi de newe ra tesel bıkerê.',
 'listfiles_name' => 'Name',
 'listfiles_user' => 'Karber',
 'listfiles_size' => 'Gırdiye',
-'listfiles_description' => 'Sılasnayış',
+'listfiles_description' => 'Şınasnayış',
 'listfiles_count' => 'Versiyoni',
 'listfiles-show-all' => 'Asayışa versiyonandé verénan',
 'listfiles-latestversion' => 'Versiyono verin',
@@ -2237,9 +2236,18 @@ gıreyê her satıri de gıreyi; raş motışê yewın u dıyıni esto.
 'deadendpagestext' => 'Ena pelan ke {{SITENAME}} de zerrî ey de link çini yo.',
 'protectedpages' => 'Pelê pawıtiyey',
 'protectedpages-indef' => 'têna pawıteyê bêmuddeti',
+'protectedpages-summary' => 'têna pawıteyê têdimî',
 'protectedpages-cascade' => 'Kilit biyaye ke teyna cascadiye',
 'protectedpages-noredirect' => 'Hetenayışan bınımnê',
 'protectedpagesempty' => 'pê ney parametreyan pelê pawiteyi çinî',
+'protectedpages-timestamp' => 'Mareyê demi',
+'protectedpages-page' => 'Pele',
+'protectedpages-expiry' => 'Wextê qediyayışi',
+'protectedpages-performer' => 'Şeveknayışê karberi',
+'protectedpages-params' => 'Parametreyê şeveknayışi',
+'protectedpages-reason' => 'Sebeb',
+'protectedpages-unknown-timestamp' => 'Nêzanaye',
+'protectedpages-unknown-performer' => 'Karbero nêzanaye',
 'protectedtitles' => 'Sernameyê pawıtiyey',
 'protectedtitlesempty' => 'pê ney parametreyan sernuşteyê pawite çinê',
 'listusers' => 'Listeyê Karberan',
@@ -2285,7 +2293,7 @@ tipa rocaneyi, nameyê karberi (herfa pil u qıci re hessas a), ya zi peli (reyn
 'showhideselectedlogentries' => 'Qeydê weçinayışê bımocne/bınımne dekerê',
 
 # Special:AllPages
-'allpages' => 'Peri pêro',
+'allpages' => 'Peli pêro',
 'alphaindexline' => '$1 ra $2ine',
 'nextpage' => 'Pela badê cû ($1)',
 'prevpage' => 'Pela verêne ($1)',
@@ -2429,6 +2437,7 @@ Ena deme ra, ma qe vurnayışan ser ena pele tı haberdar keni.',
 'watchmethod-list' => 'pel ê ke şıma temaşa kenî vuryayişê peyinê ey konrol beno',
 'watchlistcontains' => 'listeya seyrkerdışê şıma de $1 tene {{PLURAL:$1|peli|peli}} estî.',
 'iteminvalidname' => "pê no '$1' unsuri problem bı, nameyo nemeqbul...",
+'wlnote2' => 'Cêr vurnayışê {{PLURAL:$1|saeta|<strong>$1</strong> saetanê}} peyênan estê, $2 ra be hetan $3.',
 'wlshowlast' => 'Peyni de vurnayışan ra  $1 seata u $2 roca $3 bımocnê',
 'watchlist-options' => 'Tercihê liste da seyri',
 
@@ -2793,8 +2802,8 @@ Cıkewtışo tewr peyêno ke bloke biyo, cêr seba referansi belikerdeyo:',
 'change-blocklink' => 'kılitkerdışi bıvurne',
 'contribslink' => 'iştıraqi',
 'emaillink' => 'e-poste bırışe',
-'autoblocker' => 'Şıma otomatikmen kılit biy, çıke adresa şımawa \'\'IP\'\'y terefê "[[User:$1|$1]]" gureniyena.
-Sebebê kılit-biyayışê $1\'i: "$2"o',
+'autoblocker' => 'Şıma otomatikmen kılit biy, çıke adresa şımaya \'\'IP\'\'y terefê "[[User:$1|$1]]" gureniyena.
+Sebebê kılitbiyayışê $1\'i "$2"o',
 'blocklogpage' => 'Qeydê bloqi',
 'blocklog-showlog' => 'verniyê no/na karberi cıwa ver geriyayo/ya.',
 'blocklog-showsuppresslog' => 'verniyê no/na karberi cıwa ver geriyayo/ya.',
@@ -3120,7 +3129,7 @@ dosyaya emaneti vindbiyo',
 'tooltip-ca-nstab-user' => 'Pela karberi bıvêne',
 'tooltip-ca-nstab-media' => 'Pera medya bıvin',
 'tooltip-ca-nstab-special' => 'Na yew pela xasa, şıma nêşenê sero vurnayış bıkerê',
-'tooltip-ca-nstab-project' => 'Pera proci bıvin',
+'tooltip-ca-nstab-project' => 'Pela procey bıvêne',
 'tooltip-ca-nstab-image' => 'Pera dosyayer bıvin',
 'tooltip-ca-nstab-mediawiki' => 'Mesacané sistemi bıvin',
 'tooltip-ca-nstab-template' => 'Şabloni bıvin',
@@ -3295,7 +3304,7 @@ Gurênayışê nae de, beno ke sistemê şıma zerar bıvêno.",
 'noimages' => 'Çik çini yo.',
 'ilsubmit' => 'Cı geyre',
 'bydate' => 'goreyê zemani',
-'sp-newimages-showfrom' => '$1, sehat $2 ra tepya dosyayané newan bıasné',
+'sp-newimages-showfrom' => 'Dosyayanê newiyanê ke be $1, $2 ra dest pêkenê bımocne',
 
 # Video information, used by Language::formatTimePeriod() to format lengths in the above messages
 'video-dims' => '$1, $2 × $3',
@@ -4127,6 +4136,7 @@ Ti hem zi eşkeno [[Special:EditWatchlist|use the standard editor]].',
 'version-ext-colheader-description' => 'Şınasnayış',
 'version-ext-colheader-credits' => 'Nuştekari',
 'version-license-title' => 'Semedê $1 ra lisans',
+'version-license-not-found' => 'Seba na derganiye melumatê lisansê detayıni nêvêniya.',
 'version-credits-title' => 'Semedê $1 ra krediy',
 'version-poweredby-credits' => "Ena wiki, dezginda '''[https://www.mediawiki.org/ MediaWiki]''' ya piya vıraziyaya, heqê telifi © 2001-$1 $2.",
 'version-poweredby-others' => 'Zewmi',
index 1bc9da8..879f221 100644 (file)
@@ -322,7 +322,6 @@ $messages = array(
 'vector-action-protect' => 'Šćitaś',
 'vector-action-undelete' => 'Wótnowiś',
 'vector-action-unprotect' => 'Šćit změniś',
-'vector-simplesearch-preference' => 'Zjadnorjonu pytańsku lejstwu zmóžniś (jano drastwa Vector)',
 'vector-view-create' => 'Napóraś',
 'vector-view-edit' => 'Wobźěłaś',
 'vector-view-history' => 'Wersije a awtory',
@@ -990,6 +989,7 @@ Njesmějo daś wěcej nježli $2 {{PLURAL:$2|wołanja|wołanjowu|wołanjow|woła
 'undo-success' => 'Wobźěłanje móžo se wótpóraś. Pšosym pśeglěduj dołojcne pśirownowanje aby se wěsty był, až to wót wěrnosći coš, a pón składuj změny, aby se wobźěłanje doskóńcnje wótpórało.',
 'undo-failure' => 'Změna njejo se mógała wótpóraś, dokulaž jo něchten pótrjefjony wótrězk mjaztym změnił.',
 'undo-norev' => 'Změna njeda se wótwrośiś, dokulaž njeeksistěčujo abo jo se wulašowała.',
+'undo-nochange' => 'Zda se, až změna jo se južo anulěrowała.',
 'undo-summary' => 'Wersija $1 wót [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskusija]]) jo se anulěrowała',
 'undo-summary-username-hidden' => 'Změna $1 schowanego wužywarja jo se anulěrowała',
 
@@ -1170,6 +1170,8 @@ Zaruc, až historija wersijow nastawka jo njepśetergnjona.',
 'showhideselectedversions' => 'Wubrane wersije pokazaś/schowaś',
 'editundo' => 'wótwrośiś',
 'diff-empty' => '(Žeden rozdźěl)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Jadna mjazywersija|$1 mjazywersiji|$1 mjazywersije|$1 mjazywersijow}} wót togo samskego wužywarja {{PLURAL:$1|njepokazana|njepokazanej|njepokazane}})',
+'diff-multi-otherusers' => '({{PLURAL:$1|Jadna mjazywersija|$1 mjazywersiji|$1 mjazywersije|$1 mjazywersijow}} wót {{PLURAL:$2|jadnogo dalšnego wužywarja|$2 wužywarjow}} {{PLURAL:$1|njepokazana|njepokazanej|njepokazane}})',
 'diff-multi-manyusers' => '({{PLURAL:$1|Jadna mjazywersija|$1 mjazywersiji|$1 mjazywersije|$1 mjazywersijow}} wót wěcej ako {{PLURAL:$2|jadnogo wužywarja|$2 wužywarjowu|$2 wužywarjow|$2 wužywarjow}} {{PLURAL:$1|njepokazana|njepokazanej|njepokazane|njepokazane}})',
 'difference-missing-revision' => '{{PLURAL:$2|Jadna wersija|$2 wersiji|$2 wersije|$2 wersijow}} toś togo rozdźěla ($1) {{PLURAL:$2|njejo se namakała|njejstej se namakałej|njejsu namakali|njejo se namakało}}.
 
@@ -1216,6 +1218,7 @@ Drobnostki móžoš w [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'searchrelated' => 'swójźbne',
 'searchall' => 'wše',
 'showingresults' => "How {{PLURAL:|jo '''1''' wuslědk|stej '''$1''' wuslědka|su '''$1''' wuslědki}} wót cysła '''$2'''.",
+'showingresultsinrange' => 'Dołojce pokazujo se do {{PLURAL:$1|<strong>1</strong> wuslědka|<strong>$1</strong> wuslědkowu|<strong>$1</strong> wuslědkow}} we wobłuku <strong>$2</strong> až do <strong>$3</strong>.',
 'showingresultsnum' => "How {{PLURAL:$3|jo '''1''' wuslědk|stej '''$3''' wuslědka|su '''$3''' wuslědki}} wót cysła '''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Wuslědk '''$1''' z '''$3'''|Wuslědki '''$1 - $2''' z '''$3'''}} za '''$4'''",
 'search-nonefound' => 'Njejsu se wuslědki namakali, kótarež wótpowěduju napšašowanjeju.',
@@ -2024,9 +2027,18 @@ Kužda smužka wopśimjejo wótkaze na prědne a druge dalejpósrědnjenje a tek
 'deadendpagestext' => 'Slědujuce boki njewótkazuju na druge boki we {{GRAMMAR:lokatiw|{{SITENAME}}}}.',
 'protectedpages' => 'Šćitane boki',
 'protectedpages-indef' => 'Jano boki pokazaś, kótarež su na njewěsty cas šćitane',
+'protectedpages-summary' => 'Toś ten specialny bok pokazujo wšykne boki, kótarež njamgu se mimo wósebnych pšawow wobźěłowaś a pśesuwaś.',
 'protectedpages-cascade' => 'Jano boki z kaskadowym šćitom',
 'protectedpages-noredirect' => 'Dalejpósrědnjenja schowaś',
 'protectedpagesempty' => 'Z toś tymi parametrami njejsu tuchylu žedne boki šćitane.',
+'protectedpages-timestamp' => 'Casowy kołk',
+'protectedpages-page' => 'Bok',
+'protectedpages-expiry' => 'Płaśiwy až do',
+'protectedpages-performer' => 'Šćitajucy wužywaŕ',
+'protectedpages-params' => 'Šćitowe parametry',
+'protectedpages-reason' => 'Pśicyna',
+'protectedpages-unknown-timestamp' => 'Njeznaty',
+'protectedpages-unknown-performer' => 'Njeznaty wužywaŕ',
 'protectedtitles' => 'Šćitane titele',
 'protectedtitlesempty' => 'Tuchylu njejsu žedne boki z pódanych parametrami šćitane.',
 'listusers' => 'Lisćina wužywarjow',
@@ -2211,6 +2223,7 @@ Pózdźejšne změny na toś tom boku a w pśisłušecej diskusiji se tam nalicu
 'watchmethod-list' => 'Pśepytanje wobglědowanych bokow za aktualnymi změnami',
 'watchlistcontains' => 'Twója wobglědowańka wopśimujo $1 {{PLURAL:$1|bok|boka|boki|bokow}}.',
 'iteminvalidname' => 'Problem ze zapisom „$1“, njepłaśece mě.',
+'wlnote2' => 'Slěduju změny {{PLURAL:$1|zachadneje góźiny|zachadneju <strong>$1</strong> góźinowu|zachadnych <strong>$1</strong> góźinow}} Staw: $2, $3.',
 'wlshowlast' => 'Pokaž změny slědnych $1 góźinow, $2 dnjow abo $3 (w slědnych 30 dnjach).',
 'watchlist-options' => 'Opcije wobglědowańki',
 
@@ -2764,6 +2777,7 @@ $2',
 'thumbnail_image-type' => 'Wobrazy typ se njepódpěra',
 'thumbnail_gd-library' => 'Njedopołna konfiguracija GD-biblioteki: felujuca funkcija $1',
 'thumbnail_image-missing' => 'Zda se, až dataja felujo: $1',
+'thumbnail_image-failure-limit' => 'Njedawno jo pśewjele wopytow było, kótarež jo se njeraźiło ($1 abo wěcej), aby toś tu miniaturu kresliło. Pšosym wopytajśo pózdźej hyšći raz.',
 
 # Special:Import
 'import' => 'Boki importěrowaś',
@@ -2809,6 +2823,7 @@ Wšykne transwiki-importowe akcije protokolěruju se w [[Special:Log/import|log-
 'import-error-special' => 'Bok "$1" se njeimportěrujo, dokulaž słuša k wósebnemu mjenjowemu rumoju, kótaryž njedowólujo boki.',
 'import-error-invalid' => 'Bok "$1" se njeimportěrujo, dokulaž jogo mě jo njepłaśiwe.',
 'import-error-unserialize' => 'Wersija $2 boka "$1" njedajo se wótserializěrowaś. Wersija jo se za wužywanje wopśimjeśowego $3 k wěsći dała, kótaryž jo ako $4 serializěrowany.',
+'import-error-bad-location' => 'Wersija $2, kótaraž wužywa wopśimjeśowy model $3, njedajo se pód "$1" w toś tom wikiju składowaś, dokulaž model njepódpěra se na toś tom boku.',
 'import-options-wrong' => '{{PLURAL:$2|Wopacna opcija|Wopacnej opciji|Wopacne opcije|Wopacne opcije}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Pódany kórjenjowy bok jo njepłaśiwy.',
 'import-rootpage-nosubpage' => 'Mjenjowy rum "$1" kórjenjowego boka njedowólujo pódboki.',
index 66d9413..d90623f 100644 (file)
@@ -177,7 +177,6 @@ $messages = array(
 'vector-action-protect' => 'Prutēz',
 'vector-action-undelete' => 'Fà al recóper',
 'vector-action-unprotect' => 'Câmbia la prutesiòun',
-'vector-simplesearch-preference' => 'Drōva la bâra per la sērca pió fâcila (sōl per la skin Vector)',
 'vector-view-create' => 'Invèinta',
 'vector-view-edit' => 'Mudéfica',
 'vector-view-history' => 'Guêrda la stôria',
@@ -683,9 +682,29 @@ Per impustêr e cunfermêr l'indirés dervîres dal [[Special:Preferences|prefer
 'noarticletext' => 'In cól mumèint ché la pàgina serchêda l\'é vōda. L\'é pusébil [[Special:Search/{{PAGENAME}}|serchêr sté tétol]] int al j êtri pàgini dal sît, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serchêr int i regéster coleghê] opór  [{{fullurl:{{FULLPAGENAME}}|action=edit}} mudifichêr la pàgina adèsa]</span>.',
 'noarticletext-nopermission' => "In cól mumèint ché la pàgina serchêda l'é vōda. L'é pusébil [[Special:Search/{{PAGENAME}}|serchêr sté tétol]] int al j êtri pàgini dal sît o<span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} serchêr int i regéster coleghê] <span>, mó an 't gh'ê mìa al permès ed fêr cla pàgina ché.",
 'missing-revision' => "La revişiòun #\$1 'd la pagina \"{{PAGENAME}}\" l' an gh'è mìa. Còst, ed sôlit, a sucēd mèint'r as va drē a 'n colegamèint a 'na pàgina scanşlêda, in 'na stòria, di lavōr fât, mìa arnuvêda. I particulêr a 's pōlen catêr int al [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} regéster dal scanşladûri].",
+'userpage-userdoesnotexist' => 'L\'inscrisiòun "<nowiki>$1</nowiki>" la cumbîna mìa cun \'n utèint registrê. Ét sicûr ed vrèir fêr o mudifichêr cla pàgina ché.',
+'userpage-userdoesnotexist-view' => 'L\'utèin "$1" an n\'à mìa fât l\'inscrisiòun.',
+'blocked-notice-logextract' => "Cl'utèint ché adèsa l'é bluchê. 
+Per infurmasiòun l'ûltem elemèint dal regéster di blôch l'é scrét ché sòta:",
+'clearyourcache' => "'''Nôta:''' dôpa vèir salvê a pré èser necesâri pulîr la memôria pruvişôria dal navigadôr per vèder i cambiamèint.
+*'''Firefox / Safari''': tgnîr cucê al tâst dal lètri grândi e clichêr insém a \"Ricarica\" opór cucêr i tâst ''Ctrl-F5'' o ''Ctrl-R'' (''⌘-R'' insém a un Mac)
+*'''Google Chrome''': cucêr i tâst ''Ctrl-Shift-R'' (''⌘-Shift-R'' insém a un Mac) 
+*'''Internet Explorer''': tgnîr cucê al tâst ''Ctrl'' mènter es fà cléch insém a ''Refresh'', opór cucêr ''Ctrl-F5'' 
+*'''Opera''': svudêr dal tót la memôria pruvişôria 'd la lésta ''Strumenti → Preferenze''",
+'usercssyoucanpreview' => "'''Cunséli:''' drōva al tâst 'Guêrda préma' per pruvêr al tó nōv CSS préma 'd salvêrel'''",
+'userjsyoucanpreview' => "'''Cunséli:''' drōva al tâst 'Guêrda préma' per pruvêr al tó nōv  JavaScript préma 'd salvêrel'''",
+'usercsspreview' => "'''Còsta l'é sōl 'na guardêda al tó CSS préma 'd salvêr al mudéfichi ch'în stêdi fâti.Ricôrdet che al mudéfichi în mìa incòra stêdi salvêdi!'''",
+'userjspreview' => "'''Còsta l'é sōl 'na guardêda préma 'd salvêr al mudéfichi per pruvêr al tó JavaScript personêl. Ricôrdet che al mudéfichi în mìa incòra stêdi salvêdi!'''",
+'sitecsspreview' => "'''Còsta l'é sōl 'na guardêda 'l CSS préma 'd salvêrel. Ricôrdet che al mudéfichi în mìa incòra stêdi salvêdi!'''",
+'sitejspreview' => "'''Còsta l'é sōl 'na guardêda préma per pruvêr al JavaScript. Ricôrdet che al mudéfichi în mìa incòra stêdi salvêdi!'''",
+'userinvalidcssjstitle' => "'''Atensiòun:''' An gh'é nisóna skin cun al nòm \"\$1\". As fà nutêr che al pàgini per i .css e .js personêl a gh'àn la préma lètra dal tétol in céch, per eşèimpi {{ns:user}}:Eşèimpi/vector.css e non {{ns:user}}:Eşèimpi/Vector.css.",
+'updated' => '(Arnuvê)',
 'note' => "'''Nôta:'''",
 'previewnote' => "'''Ricôrdet che còsta l'é sōl 'na guardêda préma 'd salvêr.'''
 Al tō mudéfichi în MIA incòra stêdi salvêdi.",
+'continue-editing' => "Và int la zôna 'd mudéfica",
+'previewconflict' => "La vésta la cumbîna cun al tèst int la zôna 'd mudéfica tèst ché d'ed sōver e l'é cme la srà la pàgina s'ed decéd ed clichêr insém a \"Sêlva la pàgina\" in cól mumèint ché.",
+'session_fail_preview' => "'''An n'é mìa stê pusébil registrêr la mudéfica perchè a s' în pêrsi al j infurmasiòun relatîvi a la sesiòun. Tōrna a pruvêr. Se al prublēma al cunténva, a 's pōl pruvêr [[Special:UserLogout|ed coleghêres]] e fêr un ingrès nōv.'''",
 'editing' => 'Mudéfica ed $1',
 'editingsection' => 'Mudéfica ed $1 (sesiòun)',
 'editingcomment' => 'Mudéfica e $1 (sesiòun nōva)',
@@ -761,7 +780,7 @@ Per cumditê còst l'é l'èlèinch dal scanşladûri e di spustamèint relatîv
 'viewprevnext' => 'Guêrda ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''Int al sît a gh'é 'na pàgina cun al nòm [[:$1]].'''
 {{PLURAL:$2|0=|Guêrda ânca chiêter ch'în stê catê.}}",
-'searchmenu-new' => "'''Şvilópa la pàgina \"[[:\$1]]\" insém a cól sît ché! '''{{PLURAL:\$2|0=|Guêrda ânch i rişultêt catê}}.",
+'searchmenu-new' => '<strong>Şvilópa la pàgina "[[:$1]]" insém a cól sît ché!</strong> {{PLURAL:$2|0=|Guêrda ânch la pàgina che t\'é serchê|Guêrda ânch i rişultêt catê}}.',
 'searchprofile-articles' => "Pàgini 'd j argumèint",
 'searchprofile-project' => "Pàgini 'd ajót e relatîvi al prugèt.",
 'searchprofile-images' => 'Multimèdia',
index f0d5a03..b1a80a0 100644 (file)
@@ -534,7 +534,6 @@ $messages = array(
 'vector-action-protect' => 'Προστασία',
 'vector-action-undelete' => 'Επαναφορά',
 'vector-action-unprotect' => 'Αλλαγή προστασίας',
-'vector-simplesearch-preference' => 'Ενεργοποίηση απλοποιημένης μπάρας αναζήτησης (μόνον για skin Vector)',
 'vector-view-create' => 'Δημιουργία',
 'vector-view-edit' => 'Επεξεργασία',
 'vector-view-history' => 'Προβολή ιστορικού',
@@ -1312,9 +1311,10 @@ Mπορείτε να δείτε αυτή την διαφορά. Λεπτομέρ
 'revdelete-text' => "'''Οι διεγραμμένες αναθεωρήσεις και τα γεγονότα θα εμφανίζονται ακόμα στο ιστορικό της σελίδας και στα αρχεία καταγραφών, αλλά μέρη του περιεχομένου τους θα είναι απροσπέλαστα στο κοινό.'''
 Άλλοι διαχειριστές στον ιστότοπο {{SITENAME}} θα είναι ακόμα ικανοί να προσπελάσουν το κρυμμένο περιεχόμενο και μπορούν να το επαναφέρουν ξανά μέσω αυτής της διεπαφής, εκτός αν τεθούν πρόσθετοι περιορισμοί.",
 'revdelete-confirm' => 'Παρακαλούμε επιβεβαιώστε ότι σκοπεύετε να το κάνετε αυτό, ότι αντιλαμβάνεσθε τις συνέπειες, και ότι το κάνετε σύμφωνα με την [[{{MediaWiki:Policy-url}}|πολιτική]].',
-'revdelete-suppress-text' => "Η καταστολή μπορεί να χρησιμοποιηθεί ''' μόνο ''' για τις ακόλουθες περιπτώσεις:
+'revdelete-suppress-text' => 'Η καταστολή μπορεί να χρησιμοποιηθεί <strong> μόνο </strong> για τις ακόλουθες περιπτώσεις:
+* Ενδεχόμενη συκοφαντική δυσφήμιση
 * Ακατάλληλες προσωπικές πληροφορίες
-*: ''διευθύνσεις κατοικίας και αριθμοί τηλεφώνου, αριθμοί ταυτότητας, κλπ. ''",
+*: <em>διευθύνσεις κατοικίας και αριθμοί τηλεφώνου, αριθμοί ταυτότητας, κλπ. </em>',
 'revdelete-legend' => 'Θέστε περιορισμούς ορατότητας',
 'revdelete-hide-text' => 'Κείμενο αναθεώρησης',
 'revdelete-hide-image' => 'Κρύψε περιεχόμενο αρχείου',
@@ -1730,7 +1730,7 @@ $1",
 'action-block' => 'να φράξετε τις επεξεργασίες αυτού του χρήστη',
 'action-protect' => 'να αλλάξετε τα επίπεδα προστασίας για αυτή τη σελίδα',
 'action-rollback' => 'γρήγορη επαναφορά των επεξεργασιών του τελευταίου χρήστη που επεξεργάστηκε μια συγκεκριμένη σελίδα',
-'action-import' => 'να ÎµÎ¹Ï\83άγεÏ\84ε Î±Ï\85Ï\84ή Ï\84η Ï\83ελίδα από άλλο wiki',
+'action-import' => 'ειÏ\83άγεÏ\84ε Ï\83ελίδεÏ\82 από άλλο wiki',
 'action-importupload' => 'εισάγετε αυτή τη σελίδα από φόρτωση αρχείου',
 'action-patrol' => 'να επισημάνετε τις επεξεργασίες άλλων ως ελεγμένες',
 'action-autopatrol' => 'να επισημάνετε την επεξεργασία σας ως ελεγμένη',
@@ -1765,7 +1765,7 @@ $1",
 'rclistfrom' => 'Εμφάνιση νέων αλλαγών αρχίζοντας από $1',
 'rcshowhideminor' => '$1 μικροεπεξεργασιών',
 'rcshowhidebots' => '$1 ρομπότ',
-'rcshowhideliu' => '$1 συνδεδεμένων χρηστών',
+'rcshowhideliu' => '$1 εγγεγραμμένων χρηστών',
 'rcshowhideanons' => '$1 ανωνύμων χρηστών',
 'rcshowhidepatr' => '$1 ελεγμένων επεξεργασιών',
 'rcshowhidemine' => '$1 των επεξεργασιών μου',
@@ -1782,7 +1782,7 @@ $1",
 'rc_categories_any' => 'Οποιαδήποτε',
 'rc-change-size-new' => '$1 {{PLURAL:$1|byte|bytes}} μετά από την αλλαγή',
 'newsectionsummary' => '/* $1 */ νέα ενότητα',
-'rc-enhanced-expand' => 'Εμφάνιση λεπτομερειών (απαιτείται JavaScript)',
+'rc-enhanced-expand' => 'Εμφάνιση λεπτομερειών',
 'rc-enhanced-hide' => 'Απόκρυψη λεπτομερειών',
 'rc-old-title' => 'αρχικά δημιουργήθηκε ως " $1 "',
 
@@ -1802,7 +1802,7 @@ $1",
 'reuploaddesc' => 'Επιστροφή στη φόρμα φόρτωσης',
 'upload-tryagain' => 'Η καταχώρηση άλλαξε την περιγραφή αρχείου',
 'uploadnologin' => 'Δεν έχετε συνδεθεί!',
-'uploadnologintext' => 'Î\93ια Î½Î± Ï\86οÏ\81Ï\84Ï\8eÏ\83εÏ\84ε Î±Ï\81Ï\87εία Ï\80Ï\81έÏ\80ει Ï\80Ï\81Ï\8eÏ\84α Î½Î± [[Special:UserLogin|Ï\83Ï\85νδεθείÏ\84ε]].',
+'uploadnologintext' => 'ΠαÏ\81ακαλÏ\8e $1 Î³Î¹Î± Î½Î± ÎµÏ\80ιÏ\86οÏ\81Ï\84Ï\8eÏ\83εÏ\84ε Î±Ï\81Ï\87εία.',
 'upload_directory_missing' => 'Λείπει το αποθηκευτήριο επιφορτώσεων ($1) και δεν μπορεί να δημιουργηθεί από τον webserver.',
 'upload_directory_read_only' => 'Δεν είναι δυνατή η εγγραφή στον κατάλογο ($1) από τον server.',
 'uploaderror' => 'Σφάλμα στη φόρτωση αρχείου',
@@ -2035,8 +2035,7 @@ $1',
 'upload_source_file' => ' (ένα αρχείο στον υπολογιστή σας)',
 
 # Special:ListFiles
-'listfiles-summary' => 'Αυτή η ειδική σελίδα δείχνει όλα τα αρχεία που έχουν φορτωθεί.
-Όταν γίνεται φιλτράρισμα από τον χρήστη, εμφανίζονται μόνο οι πιο πρόσφατες εκδόσεις των αρχείων που αυτός έχει φορτώσει.',
+'listfiles-summary' => 'Αυτή η ειδική σελίδα δείχνει όλα τα επιφορτωμένα αρχεία.',
 'listfiles_search_for' => 'Αναζήτηση για όνομα πολυμέσου:',
 'imgfile' => 'αρχείο',
 'listfiles' => 'Κατάλογος εικόνων',
@@ -2243,12 +2242,20 @@ $1',
 'protectedpages' => 'Προστατευμένες σελίδες',
 'protectedpages-indef' => 'Προστασίες επαόριστον μόνο',
 'protectedpages-cascade' => 'Μόνο διαδοχικές προστασίες',
+'protectedpages-noredirect' => 'Απόκρυψη ανακατευθύνσεων',
 'protectedpagesempty' => 'Καμία σελίδα με αυτές τις παραμέτρους δεν είναι προς το παρόν προστατευμένη.',
+'protectedpages-timestamp' => 'Χρονική σήμανση',
+'protectedpages-page' => 'Σελίδα',
+'protectedpages-expiry' => 'Λήγει',
+'protectedpages-performer' => 'Προστασία χρήστη',
+'protectedpages-unknown-timestamp' => 'Άγνωστο',
+'protectedpages-unknown-performer' => 'Άγνωστος χρήστης',
 'protectedtitles' => 'Προστατευμένοι τίτλοι',
 'protectedtitlesempty' => 'Δεν υπάρχουν προστατευμένοι τίτλοι με αυτές τις παραμέτρους.',
 'listusers' => 'Κατάλογος χρηστών',
 'listusers-editsonly' => 'Εμφάνιση μόνο των χρηστών με επεξεργασίες',
 'listusers-creationsort' => 'Ταξινόμηση κατά ημερομηνία δημιουργίας',
+'listusers-desc' => 'Η ταξινόμηση κατά φθίνουσα σειρά',
 'usereditcount' => '$1 {{PLURAL:$1|επεξεργασία|επεξεργασίες}}',
 'usercreated' => '{{GENDER:$3|Δημιουργήθηκε}} στις $1 στις $2',
 'newpages' => 'Νέες σελίδες',
@@ -2530,7 +2537,7 @@ $UNWATCHURL
 Τελευταία αλλαγή από το χρήστη ([[User:$3|$3]] ([[User talk:$3|Συζήτηση]]){{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
 'editcomment' => "Το σχόλιο της επεξεργασίας ήταν: \"''\$1''\".",
 'revertpage' => 'Ανάκληση των αλλαγών $2 (επιστροφή στην προηγούμενη αναθεώρηση $1)',
-'revertpage-nouser' => 'Αναστράφηκαν οι επεξεργασίες από τον (όνομα χρήστη αφαιρέθηκε) στη τελευταία έκδοση από τον/την [[User:$1|$1]]',
+'revertpage-nouser' => 'Αναστράφηκαν οι επεξεργασίες από τον (όνομα χρήστη αφαιρέθηκε) στη τελευταία έκδοση από τον/την {{GENDER:$1|[[User:$1|$1]]}}φ',
 'rollback-success' => 'Ανεστραμμένες εκδόσεις από $1, αλλάχθηκαν στην προηγούμενη έκδοση από $2.',
 
 # Edit tokens
@@ -2668,7 +2675,7 @@ $1',
 'contributions' => 'Συνεισφορές {{GENDER:$1|χρήστη|χρήστριας}}',
 'contributions-title' => 'Συνεισφορές χρήστη για {{GENDER:$1|τον|την}} $1',
 'mycontris' => 'Συνεισφορές',
-'contribsub2' => 'Για {{GENDER:$1|τον|την}} $1 ($2)',
+'contribsub2' => 'Για {{GENDER:$3|$1}} ($2)',
 'nocontribs' => 'Δεν βρέθηκαν αλλαγές με αυτά τα κριτήρια.',
 'uctop' => '(τρέχουσα)',
 'month' => 'Από το μήνα (και νωρίτερα):',
index 5e92d3d..c382bbf 100644 (file)
@@ -825,7 +825,6 @@ future releases. Also note that since each list value is wrapped in a unique
 'vector-action-protect'          => 'Protect',
 'vector-action-undelete'         => 'Undelete',
 'vector-action-unprotect'        => 'Change protection',
-'vector-simplesearch-preference' => 'Enable simplified search bar (Vector skin only)',
 'vector-view-create'             => 'Create',
 'vector-view-edit'               => 'Edit',
 'vector-view-history'            => 'View history',
@@ -1928,7 +1927,7 @@ Note that their indexes of {{SITENAME}} content may be out of date.',
 'prefs-help-recentchangescount' => 'This includes recent changes, page histories, and logs.',
 'prefs-help-watchlist-token2'   => 'This is the secret key to the web feed of your watchlist.
 Anyone who knows it will be able to read your watchlist, so do not share it.
-[[Special:ResetTokens|Click here if you need to reset it]].',
+If you need to, [[Special:ResetTokens|you can reset it]].',
 'savedprefs'                    => 'Your preferences have been saved.',
 'timezonelegend'                => 'Time zone:',
 'localtime'                     => 'Local time:',
@@ -2763,12 +2762,21 @@ It now redirects to [[$2]].',
 'deadendpagestext'                => 'The following pages do not link to other pages in {{SITENAME}}.',
 'protectedpages'                  => 'Protected pages',
 'protectedpages-indef'            => 'Indefinite protections only',
-'protectedpages-summary'          => '', # do not translate or duplicate this message to other languages
+'protectedpages-summary'          => 'This page lists existing pages that are currently protected. For a list of titles that are protected from creation, see [[{{#special:ProtectedTitles}}]].',
 'protectedpages-cascade'          => 'Cascading protections only',
 'protectedpages-noredirect'       => 'Hide redirects',
 'protectedpagesempty'             => 'No pages are currently protected with these parameters.',
+'protectedpages-timestamp'        => 'Timestamp',
+'protectedpages-page'             => 'Page',
+'protectedpages-expiry'           => 'Expires',
+'protectedpages-performer'        => 'Protecting user',
+'protectedpages-params'           => 'Protection parameters',
+'protectedpages-reason'           => 'Reason',
+'protectedpages-unknown-timestamp' => 'Unknown',
+'protectedpages-unknown-performer' => 'Unknown user',
+'protectedpages-unknown-reason'   => '—', # do not translate or duplicate this message to other languages
 'protectedtitles'                 => 'Protected titles',
-'protectedtitles-summary'         => '', # do not translate or duplicate this message to other languages
+'protectedtitles-summary'         => 'This page lists titles that are currently protected from creation. For a list of existing pages that are protected, see [[{{#special:ProtectedPages}}]].',
 'protectedtitlesempty'            => 'No titles are currently protected with these parameters.',
 'listusers'                       => 'User list',
 'listusers-summary'               => '', # do not translate or duplicate this message to other languages
index 256c3e9..4de1cfe 100644 (file)
@@ -486,7 +486,6 @@ $messages = array(
 'vector-action-protect' => 'Protekti',
 'vector-action-undelete' => 'Malforigi',
 'vector-action-unprotect' => 'Ŝanĝi protektadon',
-'vector-simplesearch-preference' => 'Ebligi simpligitan serĉan strion (nur Vektora etoso)',
 'vector-view-create' => 'Krei',
 'vector-view-edit' => 'Redakti',
 'vector-view-history' => 'Vidi historion',
@@ -715,6 +714,7 @@ $2',
 'customjsprotected' => 'Vi ne rajtas redakti ĉi tiun Ĝavaskriptan paĝon, ĉar ĝi enhavas personajn alĝustigojn de alia uzanto.',
 'mycustomcssprotected' => 'Vi ne havas la rajton redakti tiun ĉi CSS-paĝon.',
 'mycustomjsprotected' => 'Vi ne havas la rajton redakti tiun ĉi JavaScript-paĝon.',
+'mypreferencesprotected' => 'Vi ne havas permeson por redakti viajn preferojn.',
 'ns-specialprotected' => 'Paĝoj en la {{ns:special}} nomspaco ne povas esti redaktataj.',
 'titleprotected' => "Ĉi tiu titolo estas protektita de kreado de [[User:$1|$1]].
 La kialo donata estis ''$2''.",
@@ -774,7 +774,11 @@ Ne forgesu ŝanĝi viajn [[Special:Preferences|{{SITENAME}}-preferojn]]',
 'userlogin-resetpassword-link' => 'Ĉu vi forgesis vian pasvorton?',
 'helplogin-url' => 'Help:Ensalutado',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Helpo pri ensalutado]]',
+'userlogin-loggedin' => 'Vi jam estas ensalutita kiel {{GENDER:$1|$1}}.
+Uzu la formularon suben por ensaluti kiel alia uzanto.',
+'userlogin-createanother' => 'Krei alian konton',
 'createacct-join' => 'Suben enigu informojn pri vi',
+'createacct-another-join' => 'Enigu la informon de la nova konto suben.',
 'createacct-emailrequired' => 'Retpoŝta adreso',
 'createacct-emailoptional' => 'Retpoŝta adreso (nedeviga)',
 'createacct-email-ph' => 'Enigu vian retpoŝtan adreson',
@@ -889,6 +893,7 @@ Vi eble jam ŝanĝis vian pasvorton aŭ petis novan provizoran pasvorton.',
 # Special:PasswordReset
 'passwordreset' => 'Restarigo de pasvorto',
 'passwordreset-text-one' => 'Plenigu ĉi tiun formularon por renovigi vian pasvorton.',
+'passwordreset-text-many' => '{{PLURAL:$1|Plenumu unu el la kampoj por restarigi vian pasvorton.}}',
 'passwordreset-legend' => 'Refari pasvorton',
 'passwordreset-disabled' => 'Pasvortaj restarigoj estis malŝaltitaj en ĉi tiu vikio.',
 'passwordreset-emaildisabled' => 'Retpoŝtaj funkcioj estas malfunkciigitaj en tiu ĉi vikio.',
@@ -1630,6 +1635,7 @@ indekso pro troŝarĝita servilo. Intertempe, vi povas serĉi per <i>guglo</i> a
 'right-viewmywatchlist' => 'Rigardi vian atentaron',
 'right-viewmyprivateinfo' => 'Vidi viajn proprajn privatajn informojn (ekz. retpoŝtan adreson, veran nomon)',
 'right-editmyprivateinfo' => 'Redakti viajn proprajn privatajn informojn (ekz. retpoŝtan adreson, veran nomon)',
+'right-editmyoptions' => 'Redakti proprajn preferojn',
 'right-rollback' => 'Tuj malfari la redaktojn de la lasta uzanto kiu redaktis specifan paĝon',
 'right-markbotedits' => 'Marki restarigitajn redaktojn kiel robotajn redaktojn',
 'right-noratelimit' => 'Ne influita de po-limoj',
@@ -1993,6 +1999,7 @@ Kiam oni filtras ĝin laŭ uzanto, nur la aktuala versio de la dosiero estos mon
 'listfiles_size' => 'Grandeco',
 'listfiles_description' => 'Priskribo',
 'listfiles_count' => 'Versioj',
+'listfiles-show-all' => 'Inkluzivi malaktualajn versiojn de bildoj',
 'listfiles-latestversion' => 'Nuna versio',
 'listfiles-latestversion-yes' => 'Jes',
 'listfiles-latestversion-no' => 'Ne',
@@ -2095,7 +2102,8 @@ Bonvolu kontroli aliajn ligilojn al la ŝablonoj antaŭ ol forigi ilin.',
 'randomincategory' => 'Hazarda paĝo en kategorio',
 'randomincategory-invalidcategory' => '"$1" ne estas valida kategoria nomo.',
 'randomincategory-nopages' => 'Ne estas paĝoj en la kategorio [[:Category:$1|$1]].',
-'randomincategory-selectcategory-submit' => 'Ek',
+'randomincategory-selectcategory' => 'Iri al hazarda paĝo el kategorio: $1 $2.$1',
+'randomincategory-selectcategory-submit' => 'Ek!',
 
 # Random redirect
 'randomredirect' => 'Hazarda alidirekto',
@@ -2192,6 +2200,11 @@ Bonvolu kontroli aliajn ligilojn al la ŝablonoj antaŭ ol forigi ilin.',
 'protectedpages-indef' => 'Nur ĉiamaj protektaĵoj',
 'protectedpages-cascade' => 'Nur kaskadaj protektoj',
 'protectedpagesempty' => 'Neniuj paĝoj estas momente protektitaj kun ĉi tiuj parametroj.',
+'protectedpages-timestamp' => 'Tempindiko',
+'protectedpages-page' => 'Paĝo',
+'protectedpages-reason' => 'Kialo',
+'protectedpages-unknown-timestamp' => 'Nekonata',
+'protectedpages-unknown-performer' => 'Nekonata uzanto',
 'protectedtitles' => 'Protektitaj titoloj',
 'protectedtitlesempty' => 'Neniuj titoloj estas nune protektitaj kun ĉi parametroj.',
 'listusers' => 'Uzantaro',
@@ -2936,6 +2949,8 @@ se vi volus kontribui al la komuna MediaWiki-asimilado.',
 'thumbnail-more' => 'Pligrandigi',
 'filemissing' => 'Mankanta dosiero',
 'thumbnail_error' => 'Okazis eraro ĉe kreado de antaŭvida bildeto: $1',
+'thumbnail_error_remote' => 'Eraro-mesaĝo de $1:
+$2',
 'djvu_page_error' => 'DjVu-a paĝo el intervalo',
 'djvu_no_xml' => 'Ne povas akiri XML por DjVu dosiero',
 'thumbnail-temp-create' => 'Ne povas krei provizoran bildetan dosieron',
@@ -3268,6 +3283,14 @@ $1',
 'hours-ago' => 'antaŭ $1 {{PLURAL:$1|horo|horoj}}',
 'minutes-ago' => 'antaŭ $1 {{PLURAL:$1|minuto|minutoj}}',
 'seconds-ago' => 'antaŭ $1 {{PLURAL:$1|sekundo|sekundoj}}',
+'monday-at' => 'Lundo je $1',
+'tuesday-at' => 'Mardo je $1',
+'wednesday-at' => 'Merkredo je $1',
+'thursday-at' => 'Ĵaŭdo je $1',
+'friday-at' => 'Vendredo je $1',
+'saturday-at' => 'Sabato je $1',
+'sunday-at' => 'Dimanĉo je $1',
+'yesterday-at' => 'Hieraŭ je $1',
 
 # Bad image list
 'bad_image_list' => 'La formato estas jen:
@@ -3924,6 +3947,7 @@ Vi povas ankaŭ [[Special:EditWatchlist|redakti norme]].',
 'version-license' => 'Permesilo de MediaWiki',
 'version-poweredby-credits' => "Ĉi tiu vikio funkcias per '''[https://www.mediawiki.org/ MediaWiki]''', aŭtorrajto ©&thinsp;2001–$1 $2.",
 'version-poweredby-others' => 'aliaj',
+'version-poweredby-translators' => 'tradukantoj de translatewiki.net',
 'version-credits-summary' => 'Ni ŝatus agnoski la sekvajn personojn pro siaj kontribuoj al [[Special:Version|MediaWiki]].',
 'version-license-info' => 'MediaWiki estas libera programaro. Vi povas redistribui ĝin kaj/aŭ modifi ĝin sub la kondiĉoj de la GNU General Public Licens (GNU Ĝenerala Publika Permesilo) en ties eldono de la Free Software Foundation (Libera Softvara Fondaĵo) - aŭ versio 2 de la Permesilo, aŭ (laŭ via elekto) iu ajn posta versio.
 
@@ -3939,6 +3963,7 @@ Oni devis doni al vi [{{SERVER}}{{SCRIPTPATH}}/COPYING ekzempleron de la GNU Gen
 
 # Special:Redirect
 'redirect-submit' => 'Ek',
+'redirect-lookup' => 'Traserĉi:',
 'redirect-value' => 'Valoro:',
 'redirect-user' => 'Salutnomo',
 'redirect-revision' => 'Revizio de la paĝo',
@@ -4038,6 +4063,7 @@ Oni devis doni al vi [{{SERVER}}{{SCRIPTPATH}}/COPYING ekzempleron de la GNU Gen
 'htmlform-selectorother-other' => 'Alia',
 'htmlform-no' => 'Ne',
 'htmlform-yes' => 'Jes',
+'htmlform-chosen-placeholder' => 'Elektu opcion',
 
 # SQLite database support
 'sqlite-has-fts' => '$1 kun tut-teksta subteno',
@@ -4159,6 +4185,7 @@ Aŭ vi povas uzi la facilan formularon sube. Via komento estos aldonita al la pa
 'limitreport-cputime-value' => '$1 {{PLURAL:$1|sekundo|sekundoj}}',
 'limitreport-walltime-value' => '$1 {{PLURAL:$1|sekundo|sekundoj}}',
 'limitreport-postexpandincludesize-value' => '$1/$2 {{PLURAL:$2|bitoko|bitokoj}}',
+'limitreport-templateargumentsize-value' => '$1/$2 {{PLURAL:$2|bitoko|bitokoj}}',
 
 # Special:ExpandTemplates
 'expandtemplates' => 'Ampleksigi ŝablonojn',
index 0558289..7dcca1a 100644 (file)
@@ -549,7 +549,6 @@ $messages = array(
 'vector-action-protect' => 'Proteger',
 'vector-action-undelete' => 'Restaurar',
 'vector-action-unprotect' => 'Cambiar protección',
-'vector-simplesearch-preference' => 'Activar la barra de búsqueda simplificada (sólo con la apariencia Vector)',
 'vector-view-create' => 'Crear',
 'vector-view-edit' => 'Editar',
 'vector-view-history' => 'Ver historial',
index 3d17c0c..417d85e 100644 (file)
@@ -468,7 +468,6 @@ $messages = array(
 'vector-action-protect' => 'Kaitse',
 'vector-action-undelete' => 'Taasta',
 'vector-action-unprotect' => 'Muuda kaitset',
-'vector-simplesearch-preference' => 'Kasuta lihtsustatud otsiriba (ainult Vektori-kujunduses)',
 'vector-view-create' => 'Loo',
 'vector-view-edit' => 'Muuda',
 'vector-view-history' => 'Näita ajalugu',
@@ -2192,6 +2191,14 @@ Igal real on ära toodud esimene ja teine ümbersuunamisleht ning samuti teise 
 'protectedpages-cascade' => 'Ainult kaskaadkaitsega',
 'protectedpages-noredirect' => 'Peida ümbersuunamised',
 'protectedpagesempty' => 'Selliste parameetritega ei ole praegu ühtegi lehekülge kaitstud.',
+'protectedpages-timestamp' => 'Ajatempel',
+'protectedpages-page' => 'Lehekülg',
+'protectedpages-expiry' => 'Aegumistähtaeg',
+'protectedpages-performer' => 'Kaitsja',
+'protectedpages-params' => 'Kaitse parameetrid',
+'protectedpages-reason' => 'Põhjus',
+'protectedpages-unknown-timestamp' => 'Teadmata',
+'protectedpages-unknown-performer' => 'Teadmata kasutaja',
 'protectedtitles' => 'Kaitstud pealkirjad',
 'protectedtitlesempty' => 'Hetkel pole ükski pealkiri kaitstud.',
 'listusers' => 'Kasutajad',
@@ -2954,6 +2961,7 @@ $2',
 'thumbnail_image-type' => 'Selline pildi tüüp ei ole toetatav',
 'thumbnail_gd-library' => 'GD teegi häälestus on poolik: funktsioon $1 puudub',
 'thumbnail_image-missing' => 'Fail näib puuduvat: $1',
+'thumbnail_image-failure-limit' => 'Selle pisipildi viimistlemine on hiljuti liiga palju kordi ($1 või rohkem) ebaõnnestunud. Palun proovi hiljem uuesti.',
 
 # Special:Import
 'import' => 'Lehekülgede import',
index d0e559c..87077f2 100644 (file)
@@ -289,7 +289,6 @@ $messages = array(
 'vector-action-protect' => 'Babestu',
 'vector-action-undelete' => 'Berreskuratu',
 'vector-action-unprotect' => 'Babesa aldatu',
-'vector-simplesearch-preference' => 'Bilaketa barra sinplifikatua gaitu (Vector itxurarekin bakarrik)',
 'vector-view-create' => 'Sortu',
 'vector-view-edit' => 'Aldatu',
 'vector-view-history' => 'Historia ikusi',
@@ -861,7 +860,7 @@ Zure aldaketak ez dira oraindik gorde!",
 Aldaketa ezeztatua izan da testuaren galtzea galarazteko.
 Hau batzuetan gertatzen da buggyan oinarritutako web proxy zerbitzua erabiltzean.'''",
 'edit_form_incomplete' => "'''Aldaketa formularioaren atal batzuk ez dira iritsi zerbitzarira; bi aldiz ziurtatu zure aldaketak osorik daudela eta berriro saiatu.'''",
-'editing' => '$1 aldatzen',
+'editing' => '«$1» aldatzen',
 'creating' => '$1 sortzen',
 'editingsection' => '$1 aldatzen (atala)',
 'editingcomment' => '$1 aldatzen (atal berria)',
@@ -2238,7 +2237,7 @@ Ikus [[Special:ProtectedPages|orri babestuen zerrenda]], orain indarrean dauden
 'movedarticleprotection' => 'babes hobespenak "[[$2]]"tik "[[$1]]"(e)ra mugitu dira',
 'protect-title' => '«$1» babesten',
 'protect-title-notallowed' => '"$1"en babes maila ikusi',
-'prot_1movedto2' => '$1 izenburua $2(r)engatik aldatu da',
+'prot_1movedto2' => '«$1» orria «$2» izenera aldatu da',
 'protect-badnamespace-title' => 'Izen-tarte ez babesgarria',
 'protect-badnamespace-text' => 'Izen-tarte honetako orrialdeak ezin dira babestu.',
 'protect-norestrictiontypes-text' => 'Orrialde hau ezin da babestu ez daudelako mugapen mota eskuragarririk.',
@@ -2249,7 +2248,7 @@ Ikus [[Special:ProtectedPages|orri babestuen zerrenda]], orain indarrean dauden
 'protect_expiry_invalid' => 'Babesaldiaren bukaerako data ez da baliozkoa.',
 'protect_expiry_old' => 'Babesaldiaren bukaera iraganekoa da.',
 'protect-unchain-permissions' => 'Babes aukerak desblokeatu',
-'protect-text' => "'''$1''' orrialdearen babes maila ikusi eta aldatu egin beharko zenuke.",
+'protect-text' => '«$1» orriaren babes maila ikusi eta aldatu egin beharko zenuke.',
 'protect-locked-blocked' => "Babes-mailak ezin dira aldatu blokeatuta dagoen bitartean.
 Hemen daude '''$1''' orrialdearen egungo ezarpenak:",
 'protect-locked-dblock' => "Babes-mailak ezin dira aldatu, datu-basea blokeatuta baitago.
@@ -2532,18 +2531,24 @@ Hala ere, $2-(r)en parte denez, blokeoa kendu daiteke.',
 # Move page
 'move-page' => 'Mugitu «$1»',
 'move-page-legend' => 'Orrialdea mugitu',
-'movepagetext' => "Beheko formularioa erabiliz orrialde baten izena aldatuko da, historia osoa izen berrira mugituz.
-Izenburu zaharra izenburu berrira daraman birbideratze bilakatuko da.
-Jatorrizko izenburura doazen birbideratzeak automatikoki egunera ditzakezu.
-Ezetz aukeratzen baduzu, egiazta itzazu birbideratze [[Special:DoubleRedirects|bikoitz]] edo [[Special:BrokenRedirects|apurtuak]].
-Loturak modu zuzenean mantentzea zure erantzukizuna da.
-
-Konturatu zaitez orrialdea '''ez''' dela mugituko izenburu berria duen orrialde bat badago jadanik, ez bada aldaketa-historiarik gabeko orrialde huts edo birbideratze bat.
+'movepagetext' => "Konturatu zaitez orrialdea '''ez''' dela mugituko izenburu berria duen orrialde bat badago jadanik, ez bada aldaketa-historiarik gabeko orrialde huts edo birbideratze bat.
 Horrek esan nahi du hanka sartzekotan orrialde baten jatorrizko izenburua berreskuratu daitekeela, baina ezin dela jada existitzen den orrialde baten gainean idatzi.
 
 '''Oharra!'''
 Aldaketa hau drastikoa eta ustekabekoa izan daiteke orrialde oso ezagunetan;
-mesedez, egiazta ezazu honen ondorioak ulertzen dituzula, jarraitu baino lehen.",
+mesedez, egiazta ezazu honen ondorioak ulertzen dituzula, jarraitu baino lehen.
+Inprimaki hau erabiliz, orri baten izena aldatuko da, eta haren historia izen berrira eraman.
+Izenburu zaharra izenburu berrirantz birzuzendutako orri bihurtuko da.
+Jatorrizko izenburura doazen birzuzenketak automatikoki egunera ditzakezu.
+Halako eguneratze automatikorik ez egitea aukeratzen baduzu, egiazta itzazu birbideratze [[Special:DoubleRedirects|bikoitzak]] eta [[Special:BrokenRedirects|apurtuak]].
+Zure ardura da loturak behar den tokirantz bideratzea.
+
+Gogoan izan ezazu ezazu: orriaren izena <strong>ez</strong> da aldatuko baldin jarri nahi duzun izenburua duen orria dagoeneko sortuta badago, salbu eta historiarik gabeko birzuzenketa orri bat bada.
+Hau da, nahasten baldin bazara, mugitu duzun orria lehengo izenburura itzultzeko modua badago, eta ezin duzun lehendik sortuta dagoen orri bat gainidatzi.
+
+<strong>Kontuz!</strong>
+Oso erabilia den orri batean, aldaketa hau bat-batekoa eta ustekabekoa izan liteke;
+zalantzarik baldin baduzu, lehenbizi adieraz ezazu zure asmoa eztabaida orrian, beste wikilarien iritziak jasotzeko.",
 'movepagetalktext' => "Dagokion eztabaida orrialdea berarekin batera mugitu da, honako kasu hauetan '''ezik:'''
 * Hutsik ez dagoen eztabaida orrialde bat existitzen bada izen berrian.
 * Beheko koadroa hautatzen ez baduzu.
index d26e527..8cbf7a5 100644 (file)
@@ -617,7 +617,6 @@ $messages = array(
 'vector-action-protect' => 'محافظت',
 'vector-action-undelete' => 'احیا',
 'vector-action-unprotect' => 'تغییر سطح حفاظت',
-'vector-simplesearch-preference' => 'فعال‌کردن نوار جستجوی ساده‌شده (فقط در پوستهٔ برداری)',
 'vector-view-create' => 'ایجاد',
 'vector-view-edit' => 'ویرایش',
 'vector-view-history' => 'نمایش تاریخچه',
@@ -1866,7 +1865,7 @@ $1",
 'action-userrights' => 'ویرایش همهٔ اختیارات کاربری',
 'action-userrights-interwiki' => 'ویرایش اختیارات کاربری کاربران یک ویکی دیگر',
 'action-siteadmin' => 'قفل‌کردن و بازکردن پایگاه داده‌ها',
-'action-sendemail' => 'ارساÙ\84 Ø§Û\8cÙ\85Û\8cÙ\84',
+'action-sendemail' => 'ارساÙ\84 Ø±Ø§Û\8cاÙ\86اÙ\85Ù\87',
 'action-editmywatchlist' => 'فهرست پیگیری‌های خود را ویرایش کنید',
 'action-viewmywatchlist' => 'فهرست پیگیری‌های خود را ببینید',
 'action-viewmyprivateinfo' => 'اطلاعات خصوصی خود را ببینید',
@@ -2395,6 +2394,14 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization را ببینید.',
 'protectedpages-cascade' => 'فقط محافظت‌های آبشاری',
 'protectedpages-noredirect' => 'پنهان‌کردن تغییر مسیرها',
 'protectedpagesempty' => 'در حال حاضر هیچ‌صفحه‌ای محافظت نشده‌است.',
+'protectedpages-timestamp' => 'برچسب زمان',
+'protectedpages-page' => 'صفحه',
+'protectedpages-expiry' => 'انقضا',
+'protectedpages-performer' => 'در حال حفاظت از کاربر',
+'protectedpages-params' => 'پارامترهای حفاظت',
+'protectedpages-reason' => 'دلیل',
+'protectedpages-unknown-timestamp' => 'ناشناس',
+'protectedpages-unknown-performer' => 'کاربر ناشناس',
 'protectedtitles' => 'عنوان‌های محافظت‌شده',
 'protectedtitlesempty' => 'در حال حاضر هیچ عنوانی با این پارامترها محافظت نشده‌است.',
 'listusers' => 'فهرست کاربران',
@@ -3168,6 +3175,7 @@ $2',
 'thumbnail_image-type' => 'تصویر از نوع پشتیبانی نشده',
 'thumbnail_gd-library' => 'تنظیمات ناقص کتابخانهٔ GD: عملکرد $1 وجود ندارد',
 'thumbnail_image-missing' => 'پرونده به نظر گم شده‌است: $1',
+'thumbnail_image-failure-limit' => 'تلاش‌های ناموفق اخیر بسیاری ($1 یا بیشتر) برای ارائهٔ این تصویر کوچک وجود داشته‌ است. لطفأ بعداً دوباره تلاش کنید.',
 
 # Special:Import
 'import' => 'درون‌ریزی صفحه‌ها',
index e98f7e2..e9fa116 100644 (file)
@@ -483,7 +483,6 @@ $messages = array(
 'vector-action-protect' => 'Suojaa',
 'vector-action-undelete' => 'Palauta',
 'vector-action-unprotect' => 'Muuta suojausta',
-'vector-simplesearch-preference' => 'Ota käyttöön yksinkertaistettu hakupalkki (vain Vector-ulkoasu)',
 'vector-view-create' => 'Luo',
 'vector-view-edit' => 'Muokkaa',
 'vector-view-history' => 'Näytä historia',
@@ -1134,8 +1133,9 @@ Se on jo olemassa.',
 'invalid-content-data' => 'Virheellinen sisältö',
 'content-not-allowed-here' => 'Sivun [[$2]] sisältö ei voi olla tyyppiä $1.',
 'editwarning-warning' => 'Tältä sivulta poistuminen saattaa aiheuttaa kaikkien tekemiesi muutosten katoamisen.
-Jos olet kirjautuneena sisään, voit poistaa tämän varoituksen käytöstä asetuksissa osiossa "Muokkaus".',
+Jos olet kirjautunut sisään, voit poistaa tämän varoituksen käytöstä omien asetuksien osiossa "{{int:prefs-editing}}".',
 'editpage-notsupportedcontentformat-title' => 'Sisällön muotoa ei tueta',
+'editpage-notsupportedcontentformat-text' => 'Sisällön muotoa $1 ei tueta sisältömallilla $2.',
 
 # Content models
 'content-model-wikitext' => 'wikiteksti',
@@ -1169,6 +1169,7 @@ Nämä muuttujat on jätetty käsittelemättä.",
 Varmista alla olevasta vertailusta, että haluat saada aikaan tämän lopputuloksen, ja sen jälkeen tallenna alla näkyvät muutokset.',
 'undo-failure' => 'Muokkausta ei voi kumota välissä olevien ristiriitaisten muutosten vuoksi.',
 'undo-norev' => 'Muokkausta ei voida kumota, koska sitä ei ole olemassa tai se on poistettu.',
+'undo-nochange' => 'Tämä muokkaus näyttää olevan jo kumottu.',
 'undo-summary' => 'Kumottu muokkaus $1, jonka teki [[Special:Contributions/$2|$2]] ([[User talk:$2|keskustelu]])',
 'undo-summary-username-hidden' => 'Kumottu muokkaus $1, jonka on tehnyt piilotettu käyttäjä',
 
@@ -1348,6 +1349,8 @@ Uuden ja vanhan sivun muutoksien pitää muodostaa jatkumo – ne eivät saa men
 'showhideselectedversions' => 'Näytä tai piilota valitut versiot',
 'editundo' => 'kumoa',
 'diff-empty' => '(ei eroavaisuuksia)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Yhtä välissä olevaa versiota|$1 välissä olevaa versiota}} samalta käyttäjältä ei näytetä)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Yhtä välissä olevaa versiota|$1 välissä olevaa versiota}} {{PLURAL:$2|toisen käyttäjän tekemänä|$2 käyttäjän tekeminä}} ei näytetä)',
 'diff-multi-manyusers' => '(Versioiden välissä on {{PLURAL:$1|yksi muu muokkaus|$1 muuta muokkausta, jotka on tehnyt {{PLURAL:$2|yksi käyttäjä|yli $2 eri käyttäjää}}}}.)',
 'difference-missing-revision' => '{{PLURAL:$2|Yhtä versiota|$2 versiota}} tästä vertailusta ($1) {{PLURAL:$2|ei}} löytynyt.
 
@@ -1395,7 +1398,7 @@ $1 {{int:pipe-separator}} $2',
 'searcheverything-enable' => 'Hae kaikista nimiavaruuksista',
 'searchrelated' => 'samankaltainen',
 'searchall' => 'kaikki',
-'showingresults' => "{{PLURAL:$1|'''Yksi''' tulos|'''$1''' tulosta}} tuloksesta '''$2''' alkaen.",
+'showingresults' => '{{PLURAL:$1|<strong>Yksi</strong> tulos|<strong>$1</strong> tulosta}} tuloksesta <strong>$2</strong> alkaen.',
 'showingresultsnum' => "Alla on {{PLURAL:$3|'''Yksi''' hakutulos|'''$3''' hakutulosta}} alkaen '''$2.''' tuloksesta.",
 'showingresultsheader' => "{{PLURAL:$5|Tulokset '''$1'''–'''$3'''|Tulokset '''$1'''–'''$2''' kaikkiaan '''$3''' osuman joukosta}} haulle '''$4'''",
 'search-nonefound' => 'Hakusi ei tuottanut tulosta.',
@@ -2198,6 +2201,14 @@ Jokaisella rivillä on linkit ensimmäiseen ja toiseen ohjaukseen sekä toisen o
 'protectedpages-cascade' => 'Vain tarttuvasti suojatut',
 'protectedpages-noredirect' => 'Piilota ohjaukset',
 'protectedpagesempty' => 'Mitään sivuja ei ole tällä hetkellä suojattu näillä asetuksilla.',
+'protectedpages-timestamp' => 'Aikaleima',
+'protectedpages-page' => 'Sivu',
+'protectedpages-expiry' => 'Vanhentuu',
+'protectedpages-performer' => 'Suojauksen asettanut',
+'protectedpages-params' => 'Suojauksen parametrit',
+'protectedpages-reason' => 'Syy',
+'protectedpages-unknown-timestamp' => 'Tuntematon',
+'protectedpages-unknown-performer' => 'Tuntematon käyttäjä',
 'protectedtitles' => 'Suojatut sivunimet',
 'protectedtitlesempty' => 'Ei suojattuja sivunimiä näillä hakuehdoilla.',
 'listusers' => 'Käyttäjälista',
@@ -2741,7 +2752,7 @@ Voimassa olevat estot näkyvät [[Special:BlockList|estolistasta]].',
 'contribslink' => 'muokkaukset',
 'emaillink' => 'lähetä sähköpostia',
 'autoblocker' => 'Olet automaattisesti estetty, koska jaat IP-osoitteen käyttäjän [[User:$1|$1]] kanssa. 
-Käyttäjän $1 saaman eston syy on: $2.',
+Käyttäjän $1 saaman eston syy on: "$2".',
 'blocklogpage' => 'Estoloki',
 'blocklog-showlog' => 'Tämä käyttäjä on ollut aiemmin estettynä.
 Alla on ote estolokista.',
@@ -2975,7 +2986,7 @@ Tallenna tiedot koneellesi ja tuo ne tällä sivulla.',
 'importuploaderrortemp' => 'Tuontitiedoston tallennus epäonnistui. Väliaikaistiedostojen kansio puuttuu.',
 'import-parse-failure' => 'XML-tuonti epäonnistui jäsennysvirheen takia.',
 'import-noarticle' => 'Ei sivua tuotavaksi!',
-'import-nonewrevisions' => 'Kaikki versiot on tuotu aiemmin.',
+'import-nonewrevisions' => 'Ei tuotu yhtään versiota, koska kaikki versiot ovat jo täällä tai ne on ohitettu virheiden vuoksi.',
 'xml-error-string' => '$1 rivillä $2, sarakkeessa $3 (tavu $4): $5',
 'import-upload' => 'Tallenna XML-tiedosto',
 'import-token-mismatch' => 'Istuntotiedot ovat kadonneet. Yritä uudelleen.',
index 2d3b82b..124fcea 100644 (file)
@@ -20,6 +20,7 @@
  * @author Crochet.david
  * @author Csisc
  * @author Damouns
+ * @author Darkdadaah
  * @author DavidL
  * @author Delhovlyn
  * @author Dereckson
@@ -581,7 +582,6 @@ $messages = array(
 'vector-action-protect' => 'Protéger',
 'vector-action-undelete' => 'Rétablir',
 'vector-action-unprotect' => 'Changer la protection',
-'vector-simplesearch-preference' => "Activer la barre de recherche simplifiée (seulement pour l'habillage Vector)",
 'vector-view-create' => 'Créer',
 'vector-view-edit' => 'Modifier',
 'vector-view-history' => "Afficher l'historique",
@@ -1761,7 +1761,7 @@ Cette information sera publique.',
 'newuserlogpagetext' => "Cette page affiche l'historique des créations de comptes utilisateur.",
 
 # User rights log
-'rightslog' => "Journal des modifications de droits d'utilisateurs",
+'rightslog' => 'Journal des modifications de droits d’utilisateurs',
 'rightslogtext' => "Voici l'historique des modifications des droits des utilisateurs.",
 
 # Associated actions - in the sentence "You do not have permission to X"
@@ -2330,6 +2330,14 @@ Les entrées <del>barrées</del> ont été résolues.',
 'protectedpages-cascade' => 'Uniquement les protections en cascade',
 'protectedpages-noredirect' => 'Masquer les redirections',
 'protectedpagesempty' => "Aucune page n'est protégée de cette façon.",
+'protectedpages-timestamp' => 'Horodatage',
+'protectedpages-page' => 'Page',
+'protectedpages-expiry' => 'Expire le',
+'protectedpages-performer' => 'Protection de l’utilisateur',
+'protectedpages-params' => 'Paramètres de protection',
+'protectedpages-reason' => 'Motif',
+'protectedpages-unknown-timestamp' => 'Inconnu',
+'protectedpages-unknown-performer' => 'Utilisateur inconnu',
 'protectedtitles' => 'Titres protégés',
 'protectedtitlesempty' => "Aucun titre n'est actuellement protégé avec ces paramètres.",
 'listusers' => 'Liste des utilisateurs',
@@ -2348,7 +2356,7 @@ Veuillez noter que d’autres sites peuvent avoir un lien direct vers un fichier
 'unusedcategoriestext' => 'Les catégories suivantes existent mais aucune page ou catégorie ne les utilise.',
 'notargettitle' => 'Pas de cible',
 'notargettext' => "Vous n'avez pas indiqué une page ou un utilisateur sur lequel vous souhaitez effectuer cette action.",
-'nopagetitle' => 'Aucune telle page cible',
+'nopagetitle' => 'Page cible inexistante',
 'nopagetext' => "La page cible que vous avez indiquée n'existe pas.",
 'pager-newer-n' => '{{PLURAL:$1|plus récente|$1 plus récentes}}',
 'pager-older-n' => '{{PLURAL:$1|plus ancienne|$1 plus anciennes}}',
@@ -2366,7 +2374,7 @@ Veuillez noter que d’autres sites peuvent avoir un lien direct vers un fichier
 # Special:Log
 'specialloguserlabel' => 'Auteur :',
 'speciallogtitlelabel' => 'Cible (titre ou utilisateur):',
-'log' => "Journaux d'opérations",
+'log' => 'Journaux d’opérations',
 'all-logs-page' => 'Tous les journaux publics',
 'alllogstext' => "Affichage combiné de tous les journaux disponibles sur {{SITENAME}}.<br />
 Vous pouvez personnaliser l'affichage en sélectionnant le type de journal, le nom d'utilisateur ou la page concernée (ces deux derniers étant sensibles à la casse).",
@@ -2652,7 +2660,7 @@ Consultez la [[Special:ProtectedPages|liste des pages protégées]] pour la list
 'protectexpiry' => 'Date d’expiration :',
 'protect_expiry_invalid' => "La date d'expiration est invalide.",
 'protect_expiry_old' => "La date d'expiration est déjà passée.",
-'protect-unchain-permissions' => "Déverrouiller davantage d'options de protection",
+'protect-unchain-permissions' => 'Déverrouiller davantage d’options de protection',
 'protect-text' => "Vous pouvez consulter et modifier le niveau de protection de la page '''$1'''.",
 'protect-locked-blocked' => "Vous ne pouvez pas modifier les niveaux de protection tant que vous êtes bloqué{{GENDER:||e|(e)}}.
 Voici les réglages actuels de la page '''$1''' :",
@@ -3091,6 +3099,7 @@ $2",
 'thumbnail_image-type' => "Type d'image non supporté",
 'thumbnail_gd-library' => 'Configuration incomplète de la bibliothèque GD : fonction $1 introuvable',
 'thumbnail_image-missing' => 'Le fichier suivant est introuvable : $1',
+'thumbnail_image-failure-limit' => 'Il y a eu récemment trop de tentatives échouées ($1 ou plus) pour restituer cette vignette. Veuillez réessayer ultérieurement.',
 
 # Special:Import
 'import' => 'Importer des pages',
index b65d175..6aa99a5 100644 (file)
@@ -183,7 +183,6 @@ $messages = array(
 'vector-action-protect' => 'Seekre',
 'vector-action-undelete' => 'Weder iinstel',
 'vector-action-unprotect' => 'Sidjenseekerhaid',
-'vector-simplesearch-preference' => 'Ianfacher schüklist iinstel (bluas bi Vector)',
 'vector-view-create' => 'Maage',
 'vector-view-edit' => 'Bewerke',
 'vector-view-history' => 'Ferluup uunluke',
@@ -887,6 +886,7 @@ Diar mut ei muar üs {{PLURAL:$2|1|$2}} brükt wurd. Nü {{PLURAL:$1|woort diar
 Luke oner, of dü det uk würelk du wel, an do seekre din feranrangen.',
 'undo-failure' => 'Det feranrang küd ei stregen wurd, auer di kirew uuntesken feranert wurden as.',
 'undo-norev' => 'Det feranrang küd ei turagsaat wurd, auer diar niks as of auer det sidj stregen wurden as.',
+'undo-nochange' => 'Detdiar feranrang as wel al ans turagsaat wurden.',
 'undo-summary' => 'Feranrang $1 faan [[Special:Contributions/$2|$2]] ([[User talk:$2|Diskusjuun]]) turagsaat.',
 'undo-summary-username-hidden' => 'Feranrang $1 faan en ferbürgenen brüker turagsaat',
 
@@ -1108,6 +1108,7 @@ Dü könst det uun't [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'searchrelated' => 'ferbünjen',
 'searchall' => 'aaltumaal',
 'showingresults' => "Heer {{PLURAL:$1|as '''1''' resultaat|san '''$1''' resultaaten}}, jo began mä numer '''$2.'''",
+'showingresultsinrange' => 'Oner {{PLURAL:$1|woort <strong>ian</strong> resultaat|wurd bit tu <strong>$1</strong> resultaaten}} tesken <strong>$2</strong> an <strong>$3</strong> uunwiset.',
 'showingresultsnum' => "Heer {{PLURAL:$3|as '''1''' resultaat|san '''$3''' resultaaten}}, jo began mä numer '''$2.'''",
 'showingresultsheader' => "{{PLURAL:$5|resultaat '''$1''' faan '''$3'''|resultaaten '''$1-$2''' faan '''$3'''}}, för '''$4.'''",
 'search-nonefound' => 'För din uunfraag san nian resultaaten fünjen wurden.',
@@ -1906,6 +1907,14 @@ Uun arke rä stun ferwisangen tu't iarst an ööder widjerfeerang an uk tu det s
 'protectedpages-cascade' => 'Bluas sidjen mä kaskaaden-seekerhaid',
 'protectedpages-noredirect' => 'Widjerfeerangen fersteeg',
 'protectedpagesempty' => 'Uun uugenblak san sok sidjen ei seekert.',
+'protectedpages-timestamp' => 'Tidjstempel',
+'protectedpages-page' => 'Sidj',
+'protectedpages-expiry' => 'Lääpt uf di',
+'protectedpages-performer' => 'Seekert faan',
+'protectedpages-params' => 'Seekerangsdooten',
+'protectedpages-reason' => 'Grünj',
+'protectedpages-unknown-timestamp' => 'Ünbekäänd',
+'protectedpages-unknown-performer' => 'Ünbekäänd brüker',
 'protectedtitles' => 'Seekert sidjennöömer',
 'protectedtitlesempty' => 'Uun uugenblak san sok sidjen ei speret.',
 'listusers' => 'Brükerfertiaknis',
@@ -2644,6 +2653,7 @@ $2',
 'thumbnail_image-type' => 'Sok bilen kön ei brükt wurd',
 'thumbnail_gd-library' => 'GD-bibleteek ei gans diar: Det funktjuun $1 waant',
 'thumbnail_image-missing' => 'Det datei as wel ei diar: $1',
+'thumbnail_image-failure-limit' => 'Detdiar föörskaubil as uun a leetst tidj tufölsis ($1 of muarsis) feranert wurden. Ferschük det leeder man noch ans.',
 
 # Special:Import
 'import' => 'Sidjen importiare',
@@ -3324,7 +3334,7 @@ Ferwisangen uun det salew rä wurd üs ütjnoomen uunsen, huar det datei dach uu
 'exif-gpsdirection-t' => 'Rochtwisin kurs',
 'exif-gpsdirection-m' => 'Magneetisk kurs',
 
-'exif-ycbcrpositioning-1' => 'Sentriaret',
+'exif-ycbcrpositioning-1' => 'Uun a maden',
 'exif-ycbcrpositioning-2' => 'Uun naiberskap',
 
 'exif-dc-contributor' => 'Bidracher faan',
index 22b09ba..9c41369 100644 (file)
@@ -9,6 +9,7 @@
  *
  * @author Agbad
  * @author Amire80
+ * @author Crazy Ivan
  * @author Dekel E
  * @author Drorsnir
  * @author Guycn1
@@ -530,7 +531,6 @@ $messages = array(
 'vector-action-protect' => 'הגנה',
 'vector-action-undelete' => 'ביטול מחיקה',
 'vector-action-unprotect' => 'שינוי הגנה',
-'vector-simplesearch-preference' => 'הפעלת סרגל חיפוש מפושט (בעיצוב וקטור בלבד)',
 'vector-view-create' => 'יצירה',
 'vector-view-edit' => 'עריכה',
 'vector-view-history' => 'הצגת היסטוריה',
@@ -1249,6 +1249,7 @@ $2
 'undo-success' => 'ניתן לבטל את העריכה. אנא בִדקו את השוואת הגרסאות למטה כדי לוודא שזה מה שאתם רוצים לעשות, ואז שמרו את השינויים למטה כדי לבצע את ביטול העריכה.',
 'undo-failure' => 'לא ניתן היה לבטל את העריכה עקב התנגשות עם עריכות מאוחרות יותר.',
 'undo-norev' => 'לא ניתן היה לבטל את העריכה כי היא אינה קיימת או כי היא נמחקה.',
+'undo-nochange' => 'נראה שהעריכה כבר בוטלה.',
 'undo-summary' => 'ביטול גרסה $1 של [[Special:Contributions/$2|$2]] ([[User talk:$2|שיחה]])',
 'undo-summary-username-hidden' => 'ביטול גרסה $1 של משתמש מוסתר',
 
@@ -1430,7 +1431,7 @@ $1",
 'showhideselectedversions' => 'הצגת/הסתרת הגרסאות שנבחרו',
 'editundo' => 'ביטול',
 'diff-empty' => '(אין הבדלים)',
-'diff-multi-sameuser' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} ממשתמש אחד אינן מוצגות',
+'diff-multi-sameuser' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} ממשתמש אחד אינן מוצגות)',
 'diff-multi-otherusers' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}}  {{PLURAL:$2|ממשתמש אחד|מ-$2 משתמשים}}  אינן מוצגות)',
 'diff-multi-manyusers' => '({{PLURAL:$1|גרסת ביניים אחת|$1 גרסאות ביניים}} של יותר {{PLURAL:$2|ממשתמש אחד|מ־$2 משתמשים}} {{PLURAL:$1|אינה מוצגת|אינן מוצגות}})',
 'difference-missing-revision' => '{{PLURAL:$2|גרסה אחת|$2 גרסאות}} של ההבדל הזה בין שתי גרסאות ($1) {{PLURAL:$2|לא נמצאה|לא נמצאו}}.
@@ -1479,6 +1480,7 @@ $1",
 'searchrelated' => 'קשור',
 'searchall' => 'הכול',
 'showingresults' => "{{PLURAL:$1|מוצגת תוצאה '''אחת'''|מוצגות עד '''$1''' תוצאות}} החל ממספר '''$2''':",
+'showingresultsinrange' => 'מוצגים להלן עד {{PLURAL:$1|תוצאה <strong>בודדת</strong>|<strong>$1</strong> תוצאות}} בטווח שבין #<strong>$2</strong> לבין #<strong>$3</strong>.',
 'showingresultsnum' => "{{PLURAL:$3|מוצגת תוצאה '''אחת'''|מוצגות '''$3''' תוצאות}} החל ממספר '''$2''':",
 'showingresultsheader' => "{{PLURAL:$5|תוצאה '''$1''' מתוך '''$3'''|תוצאות '''$1 - $2''' מתוך '''$3'''}} עבור '''$4'''",
 'search-nonefound' => 'לא נמצאו תוצאות המתאימות לחיפוש.',
@@ -2311,6 +2313,13 @@ $1',
 'protectedpages-cascade' => 'הגנות מדורגות בלבד',
 'protectedpages-noredirect' => 'הסתרת הפניות',
 'protectedpagesempty' => 'אין כרגע דפים מוגנים עם הפרמטרים הללו.',
+'protectedpages-page' => 'דף',
+'protectedpages-expiry' => 'זמן פקיעה',
+'protectedpages-performer' => 'הוגן על ידי',
+'protectedpages-params' => 'פרמטרים להגנה',
+'protectedpages-reason' => 'סיבה',
+'protectedpages-unknown-timestamp' => 'לא ידוע',
+'protectedpages-unknown-performer' => 'משתמש לא ידוע',
 'protectedtitles' => 'כותרות מוגנות',
 'protectedtitlesempty' => 'אין כרגע כותרות מוגנות עם הפרמטרים האלה.',
 'listusers' => 'רשימת משתמשים',
index db743dc..9e8ad31 100644 (file)
@@ -354,7 +354,6 @@ $messages = array(
 'vector-action-protect' => 'सुरक्षित करें',
 'vector-action-undelete' => 'हटाना वापस लें',
 'vector-action-unprotect' => 'सुरक्षा बदलें',
-'vector-simplesearch-preference' => 'सरलीकृत खोजपट्टी सुझाव सक्षम करें। (केवल वॅक्टर त्वचा हेतु)',
 'vector-view-create' => 'बनाएँ',
 'vector-view-edit' => 'सम्पादन',
 'vector-view-history' => 'इतिहास देखें',
@@ -1629,7 +1628,7 @@ HTML टैग की जाँच करें।',
 'rclistfrom' => '$1 से नये बदलाव दिखाएँ',
 'rcshowhideminor' => 'छोटे बदलाव $1',
 'rcshowhidebots' => 'बॉट $1',
-'rcshowhideliu' => '$1 पंजीकृत सदस्य',
+'rcshowhideliu' => 'पंजीकृत सदस्य $1',
 'rcshowhideanons' => 'आइ॰पी सदस्यों के बदलाव $1',
 'rcshowhidepatr' => 'परीक्षित सम्पादन $1',
 'rcshowhidemine' => 'मेरे बदलाव $1',
@@ -3861,7 +3860,7 @@ $5
 'version-parser-function-hooks' => 'पार्सर कार्य हूक',
 'version-hook-name' => 'हूक नाम',
 'version-hook-subscribedby' => 'ने सदस्यत्व लिया',
-'version-version' => '(अवतरण $1)',
+'version-version' => '($1)',
 'version-license' => 'मीडियाविकि अनुज्ञापत्र',
 'version-ext-colheader-description' => 'विवरण',
 'version-ext-colheader-credits' => 'लेखक',
index 2dee074..3b669ec 100644 (file)
@@ -20,6 +20,7 @@
  * @author Geitost
  * @author Herr Mlinka
  * @author Kaganer
+ * @author Kolega2357
  * @author Luka Krstulovic
  * @author MaGa
  * @author MayaSimFan
@@ -479,7 +480,6 @@ $messages = array(
 'vector-action-protect' => 'Zaštiti',
 'vector-action-undelete' => 'Vrati',
 'vector-action-unprotect' => 'Promijeni zaštitu',
-'vector-simplesearch-preference' => 'Omogući traku za pretraživanje (samo izgled Vector)',
 'vector-view-create' => 'Započni',
 'vector-view-edit' => 'Uredi',
 'vector-view-history' => 'Vidi stare izmjene',
@@ -1321,6 +1321,8 @@ Primijetite da uporaba navigacijskih poveznica resetira Vaše izbore u stupcu.',
 'showhideselectedversions' => 'Otkrij/sakrij odabrane izmjene',
 'editundo' => 'ukloni ovu izmjenu',
 'diff-empty' => 'Nema razlike inačica',
+'diff-multi-sameuser' => '{{PLURAL:$1|Nije prikazana jedna međuinačica|Nisu prikazane $1 međuinačice|Nije prikazano $1 međuinačica}} istog suradnika',
+'diff-multi-otherusers' => '({{PLURAL:$1|Nije prikazana jedna međuinačica|Nisu prikazane $1 međuinačice|Nije prikazano $1 međuinačica}} {{PLURAL:$2|jednog|$2}} suradnika)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Nije prikazana jedna međuinačica|Nisu prikazane $1 međuinačice|Nije prikazano $1 međuinačica}} više od {{PLURAL:$2|jednog|$2|$2}} suradnika)',
 'difference-missing-revision' => '{{PLURAL:$2|Uređivanje|$2 uređivanja}} sljedeće šifre ($1) ne {{PLURAL:$2|postoji|postoje}}.
 
@@ -1366,6 +1368,7 @@ Više informacija možete pronaći u [{{fullurl:{{#Special:Log}}/delete|page={{F
 'searchrelated' => 'povezano',
 'searchall' => 'sve',
 'showingresults' => "Dolje {{PLURAL:$1|je prikazan '''$1''' rezultat|su prikazana '''$1''' rezultata|je prikazano '''$1''' rezultata}}, počevši od '''$2'''.",
+'showingresultsinrange' => "Dolje {{PLURAL:$1|je prikazan '''$1''' rezultat|su prikazana '''$1''' rezultata|je prikazano '''$1''' rezultata}}, u rasponu od '''$2''' do '''$3'''.",
 'showingresultsnum' => "Dolje {{PLURAL:$3|je prikazan '''$3''' rezultat|su prikazana '''$3''' rezultata|je prikazano '''$3''' rezultata}}, počevši s brojem '''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Rezultat '''$1''' od '''$3'''|Rezultati '''$1 - $2''' od '''$3'''}} za '''$4'''",
 'search-nonefound' => 'Ne postoje rezultati koji se podudaraju s upitom.',
@@ -2422,7 +2425,8 @@ Posljednju promjenu napravio je [[User:$3|$3]] ([[User talk:$3|Razgovor]]{{int:p
 'editcomment' => "Sažetak promjene je bio: \"''\$1''\".",
 'revertpage' => 'Uklonjena promjena suradnika $2, vraćeno na zadnju inačicu suradnika $1',
 'revertpage-nouser' => 'Vraćene izmjene suradnika (suradničko ime uklonjeno) na posljednju inačicu suradnika [[User:$1|$1]]',
-'rollback-success' => 'Uklonjeno uređivanje suradnika $1; vraćeno na zadnju inačicu suradnika $2.',
+'rollback-success' => 'Uklonjeno uređivanje {{GENDER:$1|suradnika|suradnice}} $1
+vraćeno na zadnju inačicu {{GENDER:$2|suradnika|suradnice}} $2.',
 
 # Edit tokens
 'sessionfailure-title' => 'Prekid sesije',
index a07e248..508ddf3 100644 (file)
@@ -318,7 +318,6 @@ $messages = array(
 'vector-action-protect' => 'škitać',
 'vector-action-undelete' => 'Wobnowić',
 'vector-action-unprotect' => 'Škit wotstronić',
-'vector-simplesearch-preference' => 'Zjednorjenu pytansku lajstu zmóžnić (jenož drasta Vector)',
 'vector-view-create' => 'Wutworić',
 'vector-view-edit' => 'Wobdźěłać',
 'vector-view-history' => 'Stawizny',
@@ -993,6 +992,7 @@ Dyrbjała mjenje hač $2 {{PLURAL:$2|wołanje|wołanjej|wołanja|wołanjow}} mě
 'undo-success' => 'Wersija je so wuspěšnje wotstroniła. Prošu přepruwuj deleka w přirunanskim napohledźe, hač twoja změna bu přewzata a klikń potom na „Składować”, zo by změnu składował.',
 'undo-failure' => 'Wobdźěłanje njehodźeše so wotstronić, dokelž wotpowědny wotrězk bu mjeztym změnjeny.',
 'undo-norev' => 'Změna njeda so cofnyć, dokelž njeeksistuje abo bu wušmórnjena.',
+'undo-nochange' => 'Zda so, zo změna je so hižo cofnyła.',
 'undo-summary' => 'Změna $1 [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusija]]) bu cofnjena.',
 'undo-summary-username-hidden' => 'Změna $1 schowaneho wužiwarja je so anulowała',
 
@@ -1171,6 +1171,8 @@ Zawěsć, zo tuta změna stawiznisku kontinuitu strony wobchowuje.',
 'showhideselectedversions' => 'Wubrane wersije pokazać/schować',
 'editundo' => 'cofnyć',
 'diff-empty' => '(Žadyn rozdźěl)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Jedna mjezywersija|$1 mjezywersiji|$1 mjezywersije|$1 mjezywersijow}} wot samsneho wužiwarja {{PLURAL:$1|njepokazana|njepokazanej|njepokazane|njepokazanych}})',
+'diff-multi-otherusers' => '({{PLURAL:$1|Jedna mjezywersija|$1 mjezywersiji|$1 mjezywersije|$1 mjezywersijow}} wot {{PLURAL:$2|jednoho dalšeho wužiwarja|$2 wužiwarjow}} {{PLURAL:$1|njepokazana|njepokazanej|njepokazane|njepokazanych}})',
 'diff-multi-manyusers' => '({{PLURAL:$1|Jedna mjezywersija|$1 mjezywersiji|$1 mjezywersije|$1 mjezywersijow}} wot wjace hač {{PLURAL:$2|jednoho wužiwarja|$2 wužiwarjow|$2 wužiwarjow|$2 wužiwarjow}} {{PLURAL:$1|njepokazana|njepokazanej|njepokazane|njepokazane}})',
 'difference-missing-revision' => '{{PLURAL:$2|Jedna wersija|$2 wersiji|$2 wersije|$2 wersijow}} tutoho rozdźěla ($1) {{PLURAL:$2|njeje so namakała|njejstej so namakałoj|njejsu namakali|njeje so namakało}}.
 
@@ -1217,6 +1219,7 @@ Podrobnosće móžeš w [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}
 'searchrelated' => 'přiwuzny',
 'searchall' => 'wšě',
 'showingresults' => "Deleka so hač {{PLURAL:$1|'''1''' wuslědk pokazuje|'''$1''' wuslědkaj pokazujetej|'''$1''' wuslědki pokazuja|'''$1''' wuslědkow pokazuje}}, započinajo z #'''$2'''.",
+'showingresultsinrange' => 'Deleka so do {{PLURAL:$1|<strong>1</strong> wuslědka|<strong>$1</strong> wuslědkow}} we wobłuku <strong>$2</strong> hač do <strong>$3</strong> pokazuje.',
 'showingresultsnum' => "Deleka so {{PLURAL:$3|'''1''' wuslědk pokazuje|'''$3''' wuslědkaj pokazujetej|'''$3''' wuslědki pokazuja|'''$3''' wuslědkow pokazuje}}, započinajo z #'''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Wuslědk '''$1''' z '''$3'''|Wuslědki '''$1 - $2''' z '''$3'''}} za '''$4'''",
 'search-nonefound' => 'Njebuchu wuslědki namakane, kotrež naprašowanju wotpowěduja.',
@@ -2028,9 +2031,18 @@ Kóžda rjadka wobsahuje wotkazy k prěnjemu a druhemu daleposrědkowanju kaž t
 'deadendpagestext' => 'Slědowace strony njejsu z druhimi stronami w tutym wikiju zwjazane.',
 'protectedpages' => 'Škitane strony',
 'protectedpages-indef' => 'Jenož strony z njewobmjezowanym škitom',
+'protectedpages-summary' => 'Tuta specialna strona naliči wšě strony, kotrež su přećiwo přesunjenju abo wobdźěłowanju škitane.',
 'protectedpages-cascade' => 'Jenož strony z kaskadowym škitom',
 'protectedpages-noredirect' => 'Dalesposrědkowanja schować',
 'protectedpagesempty' => 'Tuchwilu žane.',
+'protectedpages-timestamp' => 'Časowy kołk',
+'protectedpages-page' => 'Strona',
+'protectedpages-expiry' => 'Płaćiwy hač do',
+'protectedpages-performer' => 'Škitacy wužiwar',
+'protectedpages-params' => 'Škitowe parametry',
+'protectedpages-reason' => 'Přičina',
+'protectedpages-unknown-timestamp' => 'Njeznaty',
+'protectedpages-unknown-performer' => 'Njeznaty wužiwar',
 'protectedtitles' => 'Škitane titule',
 'protectedtitlesempty' => 'Žane titule njejsu tuchwilu z tutymi parametrami škitane.',
 'listusers' => 'Lisćina wužiwarjow',
@@ -2215,6 +2227,7 @@ Přichodne změny tuteje strony a přisłušneje diskusijneje strony budu so tam
 'watchmethod-list' => 'Wobkedźbowanki za aktualnymi změnami přepruwować',
 'watchlistcontains' => 'Maš $1 {{PLURAL:$1|stronu|stronje|strony|stronow}} w swojich wobkedźbowankach.',
 'iteminvalidname' => 'Problem ze zapiskom „$1“, njepłaćiwe mjeno.',
+'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.',
 'wlshowlast' => 'Poslednje $1 hodź. - $2 dnjow - $3 pokazać',
 'watchlist-options' => 'Opcije wobkedźbowankow',
 
@@ -2762,6 +2775,7 @@ $2',
 'thumbnail_image-type' => 'Wobrazowy typ so njepodpěruje',
 'thumbnail_gd-library' => 'Njedospołna konfiguracija GD-biblioteki: falowaca funkcija $1',
 'thumbnail_image-missing' => 'Zda so, zo dataja faluje: $1',
+'thumbnail_image-failure-limit' => 'Njedawno je přewjele pospytow było, kotrež je so nimokuliło ($1 abo wjace), zo by tutu miniaturu rysowało. Prošu spytajće pozdźišo hišće raz.',
 
 # Special:Import
 'import' => 'Strony importować',
@@ -2805,6 +2819,7 @@ $2',
 'import-error-special' => 'Strona "$1" so njeimportuje, dokelž k wosebitemu mjenowemu rumej słuša, kotryž strony njedowola.',
 'import-error-invalid' => 'Strona "$1" so njeimportuje, dokelž jeje mjeno je njepłaćiwe.',
 'import-error-unserialize' => 'Wersija $2 strony "$1" njeda so wotserializować. Wersija je so zdźěliła za wužiwanje wobsahoweho modela $3, kotryž je jako $4 serializowany.',
+'import-error-bad-location' => 'Wersija $2, kotraž wobsahowy model $3 wužiwa, njeda so pod "$1" w tutym wikiju składować, dokelž so model na tutej stronje njepodpěruje.',
 'import-options-wrong' => '{{PLURAL:$2|Wopačna opcija|Wopačnej opciji|Wopačne opcije|Wopačne opcije}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Podata korjenjowa strona je njepłaćiwa.',
 'import-rootpage-nosubpage' => 'Mjenowy rum "$1" korjenjoweje strony njedowola podstrony.',
index 0aa09fe..dd11e2f 100644 (file)
@@ -20,6 +20,7 @@
  * @author Dani
  * @author Dj
  * @author Dorgan
+ * @author Einstein2
  * @author Enbéká
  * @author Geitost
  * @author Glanthor Reviol
@@ -477,7 +478,6 @@ $messages = array(
 'vector-action-protect' => 'Lapvédelem',
 'vector-action-undelete' => 'Visszaállítás',
 'vector-action-unprotect' => 'Védelem módosítása',
-'vector-simplesearch-preference' => 'Egyszerűsített keresési sáv engedélyezése (csak Vector felületen)',
 'vector-view-create' => 'Létrehozás',
 'vector-view-edit' => 'Szerkesztés',
 'vector-view-history' => 'Laptörténet',
@@ -1665,7 +1665,7 @@ A műveletet nem lehet visszavonni.',
 'rclistfrom' => '$1 után történt változtatások megtekintése',
 'rcshowhideminor' => 'apró szerkesztések $1',
 'rcshowhidebots' => 'botok szerkesztéseinek $1',
-'rcshowhideliu' => '$1 bejelentkezett felhasználó',
+'rcshowhideliu' => 'bejelentkezett szerkesztők szerkesztéseinek $1',
 'rcshowhideanons' => 'névtelen szerkesztések $1',
 'rcshowhidepatr' => 'ellenőrzött szerkesztések $1',
 'rcshowhidemine' => 'saját szerkesztések $1',
index 6138e69..45bce2a 100644 (file)
@@ -437,7 +437,6 @@ $messages = array(
 'vector-action-protect' => 'Պաշտպանել',
 'vector-action-undelete' => 'Վերականգնել',
 'vector-action-unprotect' => 'Փոխել պաշտպանումը',
-'vector-simplesearch-preference' => 'Միացնել պարզեցված որոնման դաշտը (միայն Վեկտոր թեմայի դեպքում)',
 'vector-view-create' => 'Ստեղծել',
 'vector-view-edit' => 'Խմբագրել',
 'vector-view-history' => 'Դիտել պատմությունը',
@@ -912,9 +911,9 @@ $2',
 Համակարգ մուտք գործելուն պես կարող եք ''[[Special:ChangePassword|փոխել գաղտնաբառը]]''։",
 'newarticle' => '(Նոր)',
 'newarticletext' => "Դուք հղվել եք դեռևս գոյություն չունեցող էջի։ 
\86Õ¸Ö\80 Õ§Õ» Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ¸Ö\82 Õ°Õ¡Õ´Õ¡Ö\80 Õ¶Õ¥Ö\80Ö\84Ö\87Õ¸Ö\82Õ´ Õ£Õ¿Õ¶Õ¾Õ¸Õ² Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ´Õ¡Õ¶ Õ¤Õ¡Õ·Õ¿Õ¸Ö\82Õ´ Õ¡Õ¾Õ¥Õ¬Õ¡Ö\81Ö\80Õ¥Ö\84 Õ±Õ¥Ö\80 Õ¿Õ¥Ö\84Õ½Õ¿Õ¨, այնուհետև սեղմեք '''Հիշել էջը''' (այցելեք [[{{MediaWiki:Helppage}}|օգնության էջը]]՝ մանրամասն տեղեկությունների համար)։ 
\86Õ¸Ö\80 Õ§Õ» Õ½Õ¿Õ¥Õ²Õ®Õ¥Õ¬Õ¸Ö\82 Õ°Õ¡Õ´Õ¡Ö\80 Õ½Õ¿Õ¸Ö\80Ö\87 Õ£Õ¿Õ¶Õ¾Õ¸Õ² Õ­Õ´Õ¢Õ¡Õ£Ö\80Õ´Õ¡Õ¶ Õ¤Õ¡Õ·Õ¿Õ¸Ö\82Õ´ Õ¡Õ¾Õ¥Õ¬Õ¡Ö\81Ö\80Õ¥Ö\84 Õ¿Õ¥Ö\84Õ½Õ¿, այնուհետև սեղմեք '''Հիշել էջը''' (այցելեք [[{{MediaWiki:Helppage}}|օգնության էջը]]՝ մանրամասն տեղեկությունների համար)։ 
 
-ÔµÕ©Õ¥ Õ¤Õ¸Ö\82Ö\84 Õ½Õ­Õ¡Õ¬Õ´Õ¡Õ´Õ¢ Õ¥Ö\84 Õ¡ÕµÕ½Õ¿Õ¥Õ² Õ°Õ¡ÕµÕ¿Õ¶Õ¾Õ¥Õ¬, Õ¡ÕºÕ¡ Õ½Õ¥Õ²Õ´Õ¥Ö\84 Õ±Õ¥Ö\80 Õ¦Õ¶Õ¶Õ¡Ö\80Õ¯Õ«չի '''հետ''' (back) կոճակը։",
+ÔµÕ©Õ¥ Õ¤Õ¸Ö\82Ö\84 Õ½Õ­Õ¡Õ¬Õ´Õ¡Õ´Õ¢ Õ¥Ö\84 Õ¡ÕµÕ½Õ¿Õ¥Õ² Õ°Õ¡ÕµÕ¿Õ¶Õ¾Õ¥Õ¬, Õ¡ÕºÕ¡ Õ½Õ¥Õ²Õ´Õ¥Ö\84 Õ±Õ¥Ö\80 Õ¤Õ«Õ¿Õ¡Ö\80Õ¯չի '''հետ''' (back) կոճակը։",
 'anontalkpagetext' => "----
 ''Այս քննարկման էջը պատկանում է անանուն մասնակցին, որը դեռ չի ստեղծել մասնակցային հաշիվ կամ չի մտել համակարգ մասնակցի անունով։''
 Այդ իսկ պատճառով օգտագործվում է թվային IP-հասցեն։
@@ -1546,11 +1545,13 @@ $3 մասնակիցը տվել է հետևյալ պատճառը. ''$2''",
 'linkstoimage' => 'Հետևյալ {{PLURAL:$1|էջը հղվում է|$1 էջերը հղվում են}} այս նիշքին՝',
 'nolinkstoimage' => 'Այս նիշքին հղվող էջեր չկան։',
 'sharedupload' => 'Այս նիշքը $1 զետեղարանից է և կարող է օգտագործվել այլ նախագծերում։',
-'sharedupload-desc-here' => 'Այս նիշքը $1-ից է և թուլատրելի է այլ նախագծերի կողմից օգտագործվել։ [$2 Նիշքի նկարագրման էջի] նկարագրությունը ներկայացված է ներքո։',
+'sharedupload-desc-here' => 'Այս նիշքը տեղադրված է $1ում է և այն կարող է օգտագործվել այլ նախագծերի կողմից։
+$1ում [$2 նիշքի մասին տեղեկությունների] հիմնական մասը ներկայացված է ստորև։',
 'filepage-nofile' => 'Այս անունով նիշք գոյություն չունի։',
 'filepage-nofile-link' => 'Այս անունով նիշք գոյություն չունի, դուք կարող եք [$1 բեռնել այն]:',
 'uploadnewversion-linktext' => 'Բեռնել այս նիշքի նոր տարբերակ',
 'shared-repo-from' => '$1-ից',
+'shared-repo-name-wikimediacommons' => 'Վիքիպահեստ',
 
 # File reversion
 'filerevert' => 'Հետ շրջել $1-ը',
@@ -2469,7 +2470,7 @@ $1',
 'widthheightpage' => '$1 × $2, $3 էջեր',
 'file-info' => 'նիշքի չափ՝ $1, MIME-տեսակ՝ $2',
 'file-info-size' => '$1 × $2 փիքսել, նիշքի չափը՝ $3, MIME-տեսակը՝ $4',
-'file-nohires' => 'Ô²Õ¡Ö\80Õ±Ö\80 Õ©Õ¸Ö\82ÕµÕ¬Õ¡Õ¿Õ¾Õ¸Ö\82Õ©ÕµÕ¡Õ´Õ¢ տարբերակ չկա։',
+'file-nohires' => 'Ô±Õ¾Õ¥Õ¬Õ« Õ¢Õ¡Ö\80Õ±Ö\80 Õ¯Õ¥Õ¿Õ¡Õ¹Õ¡Ö\83Õ¸Õ¾ տարբերակ չկա։',
 'svg-long-desc' => 'SVG-նիշք, անվանապես $1 × $2 փիքսել, նիշքի չափը՝ $3',
 'show-big-image' => 'Լրիվ թույլատվությամբ',
 
index 0e024e7..30c11cd 100644 (file)
@@ -511,7 +511,6 @@ $messages = array(
 'vector-action-protect' => 'Lindungi',
 'vector-action-undelete' => 'Pembatalan penghapusan',
 'vector-action-unprotect' => 'Ubah perlindungan',
-'vector-simplesearch-preference' => 'Aktifkan bilah pencarian sederhana (hanya kulit Vector)',
 'vector-view-create' => 'Buat',
 'vector-view-edit' => 'Sunting',
 'vector-view-history' => 'Versi terdahulu',
@@ -860,7 +859,8 @@ Untuk menghindari penyalahgunaan, hanya satu kata sandi yang akan dikirimkan set
 'acct_creation_throttle_hit' => 'Pengunjung wiki ini dengan alamat IP yang sama dengan Anda telah membuat {{PLURAL:$1|1 akun|$1 akun}} dalam satu hari terakhir, hingga jumlah maksimum yang diijinkan.
 Karenanya, pengunjung dengan alamat IP ini tidak dapat lagi membuat akun lain untuk sementara.',
 'emailauthenticated' => 'Alamat surel Anda telah dikonfirmasi pada $3, $2.',
-'emailnotauthenticated' => 'Alamat surel Anda belum dikonfirmasi. Sebelum dikonfirmasi Anda tidak bisa menggunakan fitur surel.',
+'emailnotauthenticated' => 'Alamat surel Anda belum dikonfirmasi.
+Sebelum dikonfirmasi Anda tidak akan menerima surel dari fitur berikut.',
 'noemailprefs' => 'Anda harus memasukkan alamat surel di preferensi Anda untuk dapat menggunakan fitur-fitur ini.',
 'emailconfirmlink' => 'Konfirmasikan alamat surel Anda',
 'invalidemailaddress' => 'Alamat surel ini tidak dapat diterima karena formatnya tidak sesuai.
@@ -897,6 +897,8 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'retypenew' => 'Ketik ulang kata sandi baru:',
 'resetpass_submit' => 'Atur kata sandi dan masuk log',
 'changepassword-success' => 'Kata sandi Anda telah berhasil diubah!',
+'changepassword-throttled' => 'Anda terlalu sering mencoba masuk log.
+Mohon tunggu $1 sebelum mencoba lagi.',
 'resetpass_forbidden' => 'Kata sandi tidak dapat diubah',
 'resetpass-no-info' => 'Anda harus masuk log untuk mengakses halaman ini secara langsung.',
 'resetpass-submit-loggedin' => 'Ganti kata sandi',
@@ -1173,6 +1175,8 @@ karena telah ada.',
 'content-not-allowed-here' => 'Konten "$1" tidak diizinkan di halaman [[$2]]',
 'editwarning-warning' => 'Meninggalkan halaman ini dapat menyebabkan semua perubahan yang belum tersimpan hilang.
 Jika Anda telah masuk log, Anda dapat mematikan peringatan ini lewat bagian "Penyuntingan" pada halaman preferensi Anda.',
+'editpage-notsupportedcontentformat-title' => 'Format konten tidak didukung',
+'editpage-notsupportedcontentformat-text' => 'Format konten $1 tidak didukung oleh model konten $2.',
 
 # Content models
 'content-model-wikitext' => 'teks wiki',
@@ -1205,6 +1209,7 @@ Beberapa templat akan diabaikan.',
 'undo-success' => 'Suntingan ini dapat dibalikkan. Silakan periksa perbandingan di bawah untuk meyakinkan bahwa benar itu yang Anda ingin lakukan, lalu simpan perubahan tersebut untuk menyelesaikan pembalikkan suntingan.',
 'undo-failure' => 'Suntingan ini tidak dapat dibalikkan karena konflik penyuntingan antara.',
 'undo-norev' => 'Suntingan ini tidak dapat dibalikkan karena halaman tidak ditemukan atau telah dihapuskan.',
+'undo-nochange' => 'Suntingan ini nampaknya telah dibatalkan.',
 'undo-summary' => 'Membalikkan revisi $1 oleh [[Special:Contributions/$2|$2]] ([[User talk:$2|bicara]])',
 'undo-summary-username-hidden' => 'Batalkan revisi $1 oleh seorang pengguna tersembunyi',
 
@@ -1213,6 +1218,9 @@ Beberapa templat akan diabaikan.',
 'cantcreateaccount-text' => "Pembuatan akun dari alamat IP ini (<strong>$1</strong>) telah diblokir oleh [[User:$3|$3]].
 
 Alasan yang diberikan oleh $3 adalah ''$2''",
+'cantcreateaccount-range-text' => "Pembuatan akun dari alamat IP dalam rentang '''$1''', yang mencakup alamat IP anda ('''$4'''), telah diblokir oleh [[Pengguna:$3|$3]].
+
+Alasan yang diberikan oleh  $3  adalah ''$2''",
 
 # History pages
 'viewpagelogs' => 'Lihat log halaman ini',
@@ -1417,6 +1425,7 @@ Rinciannya dapat ditemukan di [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGE
 'search-result-score' => 'Relevansi: $1%',
 'search-redirect' => '(pengalihan $1)',
 'search-section' => '(bagian $1)',
+'search-file-match' => '(cocok dengan isi berkas)',
 'search-suggest' => 'Mungkin maksud Anda adalah: $1',
 'search-interwiki-caption' => 'Proyek lain',
 'search-interwiki-default' => 'Hasil $1:',
@@ -1747,6 +1756,7 @@ Jika Anda memberikannya, nama asli Anda akan digunakan untuk memberi pengenalan
 'recentchanges-label-bot' => 'Suntingan ini dilakukan oleh bot',
 'recentchanges-label-unpatrolled' => 'Suntingan ini belum terpatroli',
 'recentchanges-label-plusminus' => 'Perubahan ukuran halaman dalam bita',
+'recentchanges-legend-heading' => "'''Legenda:'''",
 'recentchanges-legend-newpage' => '(lihat pula [[Special:NewPages|daftar halaman baru]])',
 'rcnotefrom' => 'Di bawah ini adalah perubahan sejak <strong>$2</strong> (ditampilkan sampai <strong>$1</strong> perubahan).',
 'rclistfrom' => 'Perlihatkan perubahan terbaru sejak $1',
@@ -1867,6 +1877,8 @@ Jika Anda masih ingin memuat berkas Anda, silakan kembali dan gunakan nama baru.
 Jika Anda tetap ingin memuatkan berkas Anda, harap kembali dan gunakan nama lain. [[File:$1|thumb|center|$1]]',
 'file-exists-duplicate' => 'Berkas ini berduplikasi dengan {{PLURAL:$1|berkas|berkas-berkas}} berikut:',
 'file-deleted-duplicate' => 'Sebuah berkas yang identik dengan berkas ini ([[:$1]]) sudah pernah dihapuskan sebelumnya. Anda harus memeriksa sejarah penghapusan berkas tersebut sebelum melanjutkan memuat ulang berkas ini.',
+'file-deleted-duplicate-notitle' => 'Sebuah berkas yang identik dengan berkas ini sebelumnya telah dihapus, dan judul yang digunakan telah ditahan.
+Anda harus meminta bantuan seseorang dengan kemampuan untuk melihat data berkas yang ditahan untuk meninjau situasi sebelum anda mengunggah kembali.',
 'uploadwarning' => 'Peringatan pemuatan',
 'uploadwarning-text' => 'Mohon perbaiki keterangan berkas di bawah dan coba lagi.',
 'savefile' => 'Simpan berkas',
@@ -2247,7 +2259,16 @@ Nama yang telah <del>dicoret</del> berarti telah dibetulkan.',
 'protectedpages' => 'Halaman yang dilindungi',
 'protectedpages-indef' => 'Hanya untuk pelindungan dengan jangka waktu tak terbatas',
 'protectedpages-cascade' => 'Hanya pelindungan runtun',
+'protectedpages-noredirect' => 'Sembunyikan pengalihan',
 'protectedpagesempty' => 'Saat ini tidak ada halaman yang sedang dilindungi dengan parameter-parameter tersebut.',
+'protectedpages-timestamp' => 'Stempel waktu',
+'protectedpages-page' => 'Halaman',
+'protectedpages-expiry' => 'Kedaluwarsa',
+'protectedpages-performer' => 'Melindungi pengguna',
+'protectedpages-params' => 'Parameter perlindungan',
+'protectedpages-reason' => 'Alasan',
+'protectedpages-unknown-timestamp' => 'Tidak diketahui',
+'protectedpages-unknown-performer' => 'Pengguna yang tidak diketahui',
 'protectedtitles' => 'Judul yang dilindungi',
 'protectedtitlesempty' => 'Tidak ada judul yang dilindungi.',
 'listusers' => 'Daftar pengguna',
@@ -2979,6 +3000,7 @@ Silakan kunjungi [https://www.mediawiki.org/wiki/Localisation Pelokalan MediaWik
 'allmessages-prefix' => 'Saring dengan awalan:',
 'allmessages-language' => 'Bahasa:',
 'allmessages-filter-submit' => 'Tuju ke',
+'allmessages-filter-translate' => 'Terjemahkan',
 
 # Thumbnails
 'thumbnail-more' => 'Perbesar',
@@ -3030,7 +3052,7 @@ Simpan ke komputer Anda dan unggah ke sini.',
 'importuploaderrortemp' => 'Pemuatan berkas gagal. Sebuah direktori sementara dibutuhkan.',
 'import-parse-failure' => 'Proses impor XML gagal',
 'import-noarticle' => 'Tak ada halaman yang dapat diimpor!',
-'import-nonewrevisions' => 'Semua revisi telah pernah diimpor sebelumnya.',
+'import-nonewrevisions' => 'Tidak ada revisi yang diimpor (semua revisi telah ada atau dilewatkan karena kesalahan).',
 'xml-error-string' => '$1 pada baris $2, kolom $3 (bita $4): $5',
 'import-upload' => 'Memuat data XML',
 'import-token-mismatch' => 'Kehilangan data sesi. Silakan mencoba kembali.',
@@ -3041,6 +3063,7 @@ Simpan ke komputer Anda dan unggah ke sini.',
 'import-error-special' => 'Halaman " $1 " tidak diimpor karena milik ruang nama khusus yang tidak mengizinkan adanya halaman.',
 'import-error-invalid' => 'Halaman "$1" tidak diimpor karena namanya tidak valid.',
 'import-error-unserialize' => 'Revisi  $2  halaman " $1 " tidak bisa diurutkan. Revisi dilaporkan untuk menggunakan konten model $3 urutan sebagai $4 .',
+'import-error-bad-location' => 'Revisi $2 menggunakan konten model $3 tidak dapat disimpan di "$1" di wiki ini karena model tidak didukung pada halaman tersebut.',
 'import-options-wrong' => '{{PLURAL:$2|Opsi|Opsi}} salah: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Halaman turunan yang diberikan adalah judul yang salah.',
 'import-rootpage-nosubpage' => 'Ruang nama "$1" di halaman turunan tidak mengizinkan subhalaman.',
@@ -3935,6 +3958,7 @@ Silakan konfirmasi jika Anda ingin membuat ulang halaman ini.",
 'imgmultigoto' => 'Pergi ke halaman $1',
 
 # Language selector for translatable SVGs
+'img-lang-default' => '(bahasa default)',
 'img-lang-go' => 'Tuju ke',
 
 # Table pager
@@ -4060,7 +4084,17 @@ Anda juga dapat [[Special:EditWatchlist|menggunakan penyunting standar Anda]].',
 'version-hook-subscribedby' => 'Dilanggani oleh',
 'version-version' => '(Versi $1)',
 'version-svn-revision' => '(r$2)',
-'version-license' => 'Lisensi',
+'version-license' => 'Lisensi MediaWiki',
+'version-ext-license' => 'Lisensi',
+'version-ext-colheader-name' => 'Ekstensi',
+'version-ext-colheader-version' => 'Versi',
+'version-ext-colheader-license' => 'Lisensi',
+'version-ext-colheader-description' => 'Deskripsi',
+'version-ext-colheader-credits' => 'Pembuat',
+'version-license-title' => 'Lisensi untuk $1',
+'version-license-not-found' => 'Tidak ada detail informasi lisensi untuk ekstensi ini.',
+'version-credits-title' => 'Kredit untuk $1',
+'version-credits-not-found' => 'Tidak ada detail informasi kredit untuk ekstensi ini.',
 'version-poweredby-credits' => "Wiki ini didukung oleh '''[https://www.mediawiki.org/ MediaWiki]''', hak cipta © 2001-$1 $2.",
 'version-poweredby-others' => 'lainnya',
 'version-poweredby-translators' => 'penerjemah translatewiki.net',
@@ -4080,13 +4114,14 @@ Anda seharusnya telah menerima [{{SERVER}}{{SCRIPTPATH}}/COPYING salinan Lisensi
 'version-entrypoints-scriptpath' => '[https://www.mediawiki.org/wiki/Manual:$wgScriptPath Skrip path]',
 
 # Special:Redirect
-'redirect' => 'Pengalihan oleh berkas, pengguna atau ID revisi',
+'redirect' => 'Pengalihan berdasarkan ID berkas, pengguna, halaman atau revisi',
 'redirect-legend' => 'Pengalihan ke sebuah berkas atau halaman',
 'redirect-summary' => 'Halaman istimewa ini beralih ke berkas (sesuai nama berkasnya), halaman (sesuai ID revisinya), atau halaman pengguna (sesuai ID numerik penggunanya). Penggunaan: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], atau [[{{#Special:Redirect}}/user/101]].',
 'redirect-submit' => 'Lanjut',
 'redirect-lookup' => 'Pencarian:',
 'redirect-value' => 'Nilai:',
 'redirect-user' => 'ID pengguna',
+'redirect-page' => 'ID Halaman',
 'redirect-revision' => 'Revisi halaman',
 'redirect-file' => 'Nama berkas',
 'redirect-not-exists' => 'Nilai tidak ditemukan',
@@ -4279,6 +4314,7 @@ Jika tidak, Anda dapat menggunakan formulir mudah di bawah ini. Komentar Anda ak
 'api-error-overwrite' => 'Tidak diizinkan untuk menimpa berkas yang sudah ada.',
 'api-error-stashfailed' => 'Kesalahan internal: server gagal menyimpan berkas sementara.',
 'api-error-publishfailed' => 'Kesalahan internal: server gagal menyimpan berkas sementara.',
+'api-error-stasherror' => 'Terjadi kesalahan saat mengunggah berkas ke penyimpanan.',
 'api-error-timeout' => 'Peladen tidak merespons dalam waktu yang diharapkan.',
 'api-error-unclassified' => 'Terjadi galat yang tidak diketahui',
 'api-error-unknown-code' => 'Kesalahan tidak dikenal: "$1"',
@@ -4308,7 +4344,9 @@ Jika tidak, Anda dapat menggunakan formulir mudah di bawah ini. Komentar Anda ak
 'limitreport-walltime' => 'Penggunaan waktu riil',
 'limitreport-walltime-value' => '$1 {{PLURAL:$1|detik|detik}}',
 'limitreport-postexpandincludesize-value' => '$1/$2 {{PLURAL:$2|bita|bita}}',
+'limitreport-templateargumentsize' => 'Ukuran argumen temlat',
 'limitreport-templateargumentsize-value' => '$1/$2 {{PLURAL:$2|bita|bita}}',
+'limitreport-expansiondepth' => 'Kedalaman ekspansi tertinggi',
 'limitreport-expensivefunctioncount' => 'Perhitungan fungsi parser yang mahal',
 
 # Special:ExpandTemplates
@@ -4318,10 +4356,14 @@ Jika tidak, Anda dapat menggunakan formulir mudah di bawah ini. Komentar Anda ak
 'expand_templates_input' => 'Teks masukan:',
 'expand_templates_output' => 'Hasil',
 'expand_templates_xml_output' => 'Hasil XML',
+'expand_templates_html_output' => 'Keliaran HTML mentah',
 'expand_templates_ok' => 'OK',
 'expand_templates_remove_comments' => 'Buang komentar',
 'expand_templates_remove_nowiki' => 'Tidak menampilkan tag <nowiki> pada hasilnya',
 'expand_templates_generate_xml' => 'Tampilkan pohon parser XML',
+'expand_templates_generate_rawhtml' => 'Tampilkan HTML mentah',
 'expand_templates_preview' => 'Pratayang',
 
+# Unknown messages
+'uploadinvalidxml' => 'XML dalam berkas yang diunggah tidak bisa diuraikan.',
 );
index 6beb469..47484ac 100644 (file)
@@ -198,7 +198,6 @@ $messages = array(
 'vector-action-protect' => 'Salakniban',
 'vector-action-undelete' => 'Isubli ti inikkat',
 'vector-action-unprotect' => 'Sukatan ti salaknib',
-'vector-simplesearch-preference' => 'Pakabaelan ti napalaka a baras ti panagbiruk (Kudil a Vector laeng)',
 'vector-view-create' => 'Agaramid',
 'vector-view-edit' => 'Urnosen',
 'vector-view-history' => 'Kitaen ti pakasaritaan',
@@ -606,6 +605,8 @@ Tapno malpaska a makastrek, nasken a mangikabilka ti baro a kontrasenias ditoy:'
 'retypenew' => 'Imakinilya manen ti baro a kontrasenias:',
 'resetpass_submit' => 'Ikabil ti kontrasenias ken sumrek',
 'changepassword-success' => 'Balligi a nasukatan ti kontraseniasmo!',
+'changepassword-throttled' => 'Nakaaramidka kadagiti adu unay a nabiit a panangipadas ti panagserrek.
+Pangngaasi nga aguray ti $1 sakbay a padasen manen.',
 'resetpass_forbidden' => 'Saan a masukatan dagiti kontrasenias',
 'resetpass-no-info' => 'Masapul a nakastrekka tapno dagus a makapanka iti daytoy a panid.',
 'resetpass-submit-loggedin' => 'Sukatan ti kontrasenias',
@@ -664,6 +665,8 @@ Temporario a kontrasenias: $2',
 'changeemail-password' => 'Ti bukodmo a kontrasenias ti {{SITENAME}}:',
 'changeemail-submit' => 'Sukatan ti esurat',
 'changeemail-cancel' => 'Ukasen',
+'changeemail-throttled' => 'Adu unay ti panagpadasmo a sumrek.
+Pangngaasi nga aguray ti $1 sakbay a padasen manen.',
 
 # Special:ResetTokens
 'resettokens' => 'Iyasentar manen dagiti tandaan',
@@ -891,8 +894,10 @@ Adda met daytoyen.',
 'content-failed-to-parse' => 'Napaay a nausig ti $2 a linaon para iti $1 a modelo: $3',
 'invalid-content-data' => 'Imbalido a datos ti linaon',
 'content-not-allowed-here' => 'Ti "$1" a linaon ket saan a maipalubos idiay panid ti [[$2]]',
-'editwarning-warning' => 'Ti ipapanaw ti daytoy a panid ket makapataud ti panakapukaw kadagiti aniaman a binalbaliwam.
-No nakastrekka, mabalinmo nga ibaldado daytoy a ballaag idiay "Panagurnos" a paset kadagiti kakaykayatam.',
+'editwarning-warning' => 'Ti ipapanaw iti daytoy a panid ket makapataud ti pannakapukaw kadagiti aniaman a binalbaliwam.
+No nakastrekka, mabalinmo nga ibaldado daytoy a ballaag idiay "{{int:prefs-editing}}" a paset kadagiti kakaykayatam.',
+'editpage-notsupportedcontentformat-title' => 'Ti pormat ti linaon ket saan a nasuportaran',
+'editpage-notsupportedcontentformat-text' => 'Ti pormat ti linaon ti $1 ket saan a nasuportaran babaen ti modelo ti linaon ti $2.',
 
 # Content models
 'content-model-wikitext' => 'wikitext',
@@ -927,6 +932,7 @@ Dagitoy a panangipalawag ket naikkaten.",
 Pangngaasi a kitaen ti pagipadaan dita baba tapno maamuan no agpaypayso ti kayatmo nga aramiden, ken idulin dagiti sinukatan dita baba tapno malpas ti panagsubli ti inurnos.',
 'undo-failure' => 'Ti inurnos ket saan a maipasubli gaputa adda dagiti nakisinnungat a patingnga a naurnos.',
 'undo-norev' => 'Saan a maibabawi ti naurnos ngamin ket awan daytoy wenno mabalin a naikkaten.',
+'undo-nochange' => 'Ti inurnos ket kasla naibabawin.',
 'undo-summary' => 'Ibabawi ti $1 a binaliwan babaen ni [[Special:Contributions/$2|$2]] ([[User talk:$2|tungtungan]])',
 'undo-summary-username-hidden' => 'Isubli ti $1 a binaliwan babaen ti nailemmeng nga agar-aramat',
 
@@ -934,6 +940,9 @@ Pangngaasi a kitaen ti pagipadaan dita baba tapno maamuan no agpaypayso ti kayat
 'cantcreateaccounttitle' => 'Saan a makaaramid ti pakabilangan',
 'cantcreateaccount-text' => "Ti panagaramid ti pakabilangan manipud ti daytoy nga IP a pagtaengan ('''$1''') ket sinerraan babaen ni [[User:$3|$3]].
 
+Ti inted a rason babaen ni $3 ket ''$2''",
+'cantcreateaccount-range-text' => "Ti pannakapartuat ti pakabilangan manipud kadagiti pagtaengan ti IP iti sakop ti '''$1''', a mairaman ti IP a pagtaengam ('''$4'''), ket sinerraan babaen ni [[User:$3|$3]].
+
 Ti inted a rason babaen ni $3 ket ''$2''",
 
 # History pages
@@ -1105,6 +1114,8 @@ Usaren ti radio a buton a tukol ti pinagtipon iti laeng panagbaliw a naaramid id
 'showhideselectedversions' => 'Ipakita/ilemmeng dagiti napili a nabaliwan',
 'editundo' => 'ibabawi',
 'diff-empty' => '(Awan ti paggiddiatan)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Maysa nga agtengnga a panagbaliw|Dagiti $1 nga agtengnga a panagbaliw}} babaen ti isu met laeng nga agar-aramat a saan a naipakita)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Maysa nga agtengnga a panagbaliw|Dagiti $1 nga agtengnga a panagbaliw}} babaen {{PLURAL:$2|ti maysa a sabali nga agar-aramat|dagiti $2 nga agar-aramat}} a saan a naipakita)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Maysa nga agtengnga a panangbalbaliw|Dagiti $1 nga agtengnga a panangbalbaliw}} babaen ti ad-adu ngem $2 {{PLURAL:$2|nga agar-aramat|kadagiti agar-aramat}} ti saan a naipakita)',
 'difference-missing-revision' => '{{PLURAL:$2|Maysa a panagbalbaliw|$2 kadagiti panagbalbaliw}} iti daytoy a paggiddiatan ($1) {{PLURAL:$2|ket ti|ket dagiti}} saan a naburikan.
 
@@ -1125,7 +1136,7 @@ Dagiti salaysay ket mabalin a mabirukan idiay [{{fullurl:{{#Special:Log}}/delete
 'shown-title' => 'Ipakita ti $1 {{PLURAL:$1|a nagbanagan|kadagiti nagbanagan}}  ti tunggal maysa a panid',
 'viewprevnext' => 'Kitaen ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "'''Adda panid a nanaganan ti \"[[:\$1]]\" iti daytoy a wiki.'''",
-'searchmenu-new' => "'''Partuaten ti panid ti \"[[:\$1]]\" iti daytoy a wiki!'''",
+'searchmenu-new' => '<strong>Partuaten ti panid ti "[[:$1]]" iti daytoy a wiki!</strong> {{PLURAL:$2|0=|Kitaen pay ti panid a nabirukan ti panagbirukmo.|Kitaen pay dagiti resulta a nabirukan ti panagbiruk.}}',
 'searchprofile-articles' => 'Dagiti naglaon a panid',
 'searchprofile-project' => 'Tulong ken Gandat a pampanid',
 'searchprofile-images' => 'Sabsabali a midia',
@@ -1141,6 +1152,7 @@ Dagiti salaysay ket mabalin a mabirukan idiay [{{fullurl:{{#Special:Log}}/delete
 'search-result-score' => 'Kaitutopan: $1%',
 'search-redirect' => '(ibaw-ing ti $1)',
 'search-section' => '(paset $1)',
+'search-file-match' => '(maipada ti linaon a papeles)',
 'search-suggest' => 'Daytoy kadi: $1',
 'search-interwiki-caption' => 'Dagiti kakabsat a gandat',
 'search-interwiki-default' => '$1 dagiti nagbanagan:',
@@ -1150,6 +1162,7 @@ Dagiti salaysay ket mabalin a mabirukan idiay [{{fullurl:{{#Special:Log}}/delete
 'searchrelated' => 'mainaig',
 'searchall' => 'amin',
 'showingresults' => "Maiparang dita baba agingga {{PLURAL:$1|iti '''1''' a nagbanagan|dagiti '''$1''' a nagbanagan}} a mangrugi iti #'''$2'''.",
+'showingresultsinrange' => 'Mangipakpakita aginggana {{PLURAL:$1|iti <strong>1</strong> a resulta|dagiti <strong>$1</strong> a resulta}} iti sakop ti #<strong>$2</strong> aginggana ti #<strong>$3</strong>.',
 'showingresultsnum' => "Maipakpakita dita baba  {{PLURAL:$3|iti '''1''' a nagbanagan|dagiti '''$3''' a nagbanagan}} a mangrugi iti #'''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Nagbanagan a '''$1''' iti '''$3'''|Dagiti Nagbanagan a '''$1 - $2''' iti '''$3'''}} para iti '''$4'''",
 'search-nonefound' => 'Awan ti nagbanagan a kapadpada ti sinapul.',
@@ -1469,12 +1482,13 @@ Ti esurat a pagtaengam ket saan a maipakita kadagiti agar-aramat nga agkontak ke
 'recentchanges-label-bot' => 'Daytoy a panag-urnos ket inaramid babaen ti maysa a bot',
 'recentchanges-label-unpatrolled' => 'Daytoy a panag-urnos ket saan pay a napatruliaan',
 'recentchanges-label-plusminus' => 'Ti panagbaliw ti kadakkel ti panid babaen ti bilang dagiti byte',
+'recentchanges-legend-heading' => "'''Sarita:'''",
 'recentchanges-legend-newpage' => '(kitaen pay ti [[Special:NewPages|listaan ti baro a pampanid]])',
 'rcnotefrom' => "Dita baba ket dagiti sinukatan manipud idi '''$2''' (agingga iti '''$1''' a naipakita).",
 'rclistfrom' => 'Ipakita dagiti kabarbaro a sinukatan a mangrugi manipud idi $1',
 'rcshowhideminor' => '$1 dagiti bassit a panag-urnos',
 'rcshowhidebots' => '$1 dagiti bot',
-'rcshowhideliu' => '$1 dagiti nakastrek nga agar-aramat',
+'rcshowhideliu' => '$1 dagiti nakarehistro nga agar-aramat',
 'rcshowhideanons' => '$1 dagiti di am-ammo nga agar-aramat',
 'rcshowhidepatr' => '$1 dagiti napatrulian a panag-urnos',
 'rcshowhidemine' => '$1 dagiti inurnosko',
@@ -1598,6 +1612,8 @@ No kayatmo pay latta nga ipan ti papeles, pangngaasi nga agsublika ken usarem ti
 'file-exists-duplicate' => 'Daytoy a papeles ket duplikado kadagiti sumaganad a {{PLURAL:$1|papeles|pappapeles}}:',
 'file-deleted-duplicate' => 'Ti papeles a kapadpada ti papeles a ([[:$1]]) ket naikkat idin.
 Kitaem koma ti pakasaritaan a panakaikkat ti papeles sakbay a mangirugika ti pinag-ipan.',
+'file-deleted-duplicate-notitle' => 'Ti papales a kapada ti daytoy a papeles ket dati a naikkat, ken nalapdan ti titulo.
+Nasken nga agdamagka ti addaan ti abilidad a mangkita ti nalapdan a datos ti papeles tapno marepaso ti kasasaad sakbay a mapan nga ikarga manen daytoy.',
 'uploadwarning' => 'Ballaag iti pinag-ipan',
 'uploadwarning-text' => 'Pangngaasi a baliwam ti deskripsion ti papeles ken padasem manen.',
 'savefile' => 'Idulin ti papeles',
@@ -1970,7 +1986,16 @@ Tattan ket naibaw-ing idiay [[$2]].',
 'protectedpages' => 'Dagiti nasalakniban a panid',
 'protectedpages-indef' => 'Inggat ingana a salakniban laeng',
 'protectedpages-cascade' => 'Dagiti sariap a salaknib laeng',
+'protectedpages-noredirect' => 'Ilemmeng dagiti baw-ing',
 'protectedpagesempty' => 'Awan ti pampanid nga agdama a nasalakniban babaen kadagitoy a parametro.',
+'protectedpages-timestamp' => 'Petsa ken oras',
+'protectedpages-page' => 'Panid',
+'protectedpages-expiry' => 'Agpaso',
+'protectedpages-performer' => 'Salakniban ti agar-aramat',
+'protectedpages-params' => 'Dagiti parametro ti panagsalaknib',
+'protectedpages-reason' => 'Rason',
+'protectedpages-unknown-timestamp' => 'Di ammo',
+'protectedpages-unknown-performer' => 'Di ammo nga agar-aramat',
 'protectedtitles' => 'Dagiti nasalakniban a titulo',
 'protectedtitlesempty' => 'Awan dagiti titulo nga agdama a nasalakniban iti dagitoy a parametro.',
 'listusers' => 'Listaan dagiti agar-aramat',
@@ -2157,6 +2182,7 @@ Dagiti masakbayan a panagsukat iti daytoy a panid ken dagiti mainaig a tungtunga
 'watchmethod-list' => 'kitkitaen dagiti bambantayan a panid kadagiti kinaudi nga inurnos',
 'watchlistcontains' => 'Ti listaan ti bambantayam ket aglaon ti $1 {{PLURAL:$1|a panid|a pampanid}}.',
 'iteminvalidname' => "Parikut iti banag '$1', imbalido a nagan...",
+'wlnote2' => 'Dita baba ket dagiti binalbaliwan {{PLURAL:$1|iti napalabas nga oras|kadagiti napalabas a <strong>$1</strong> nga oras}}, manipud idi $2, $3.',
 'wlshowlast' => 'Ipakita dagiti naudi a $1 nga or-oras $2 nga al-aldaw $3',
 'watchlist-options' => 'Dagiti pagpilian ti listaan a bambantayan',
 
@@ -2245,6 +2271,7 @@ Ti panagikkat ti kastoy a pammpanid ket naparitan tapno mapawilan ti saan nga in
 'delete-warning-toobig' => 'Daytoy a panid ket adda ti dakkel unay a pakasaritaan ti panag-urnos, ti kaadu nga $1 {{PLURAL:$1|panagbaliw|dagiti panagbaliw}}.
 Ti panagikkat ket madisturbo ti panagpataray ti database ti {{SITNAME}};
 agal-aluadka a mangrugi.',
+'deleting-backlinks-warning' => "'''Ballaag:''' Dagiti dadduma a panid ket naisilpo wenno nailak-am manipud ti panid a gangani nga ikkatem.",
 
 # Rollback
 'rollback' => 'Isubli dagiti panag-urnos',
@@ -2487,6 +2514,7 @@ Ikkan ti naisangayan a rason dita baba (kas pagarigan, dakamaten ti maysa a pani
 Kitaen ti [[Special:BlockList|listaan ti lapden nga IP ]] tapno marepaso dagiti serra.',
 'ipb-blockingself' => 'Mangrugrugika nga agserra kenka! Sigurado a kayatmo nga aramiden daytoy?',
 'ipb-confirmhideuser' => 'Mangrugrugika ti mangserra ti agar-aramat nga adda ti napabalinna nga "ilemmeng ti agar-aramat". Iddeppenna ti nagan daytoy nga agar-aramat kadagiti amin a listaan ken dagiti naikabkabil ti listaan. Siguradoka a kasta ti kayatmo?',
+'ipb-confirmaction' => 'No segurado a kayatmo nga aramiden daytoy, pangngaasi a kitaen ti "{{int:ipb-confirm}}" a pagikabilan dita baba.',
 'ipb-edit-dropdown' => 'Urnosen dagiti rason ti panagserra',
 'ipb-unblock-addr' => 'Lukatan ti serra ni $1',
 'ipb-unblock' => 'Lukatan ti serra ti nagan ti agar-aramat wenno IP a pagtaengan',
@@ -2528,8 +2556,8 @@ Kitaen ti [[Special:BlockList|listaan ti lapden nga IP ]] tapno marepaso dagiti
 'change-blocklink' => 'baliwan  ti serra',
 'contribslink' => 'aramid',
 'emaillink' => 'ipatulod ti esurat',
-'autoblocker' => 'Automatiko a naserraan ngamin ket ti IP a pagtaengan ket damdama nga inusar ni "[[User:$1|$1]]".
-Ti rason nga inted ti $1\'s serra ket: "$2"',
+'autoblocker' => 'Automatiko a naserraan ngamin ket ti IP a pagtaengam ket naudi nga inusar babaen ni "[[User:$1|$1]]".
+Ti inted a rason para iti serra ni $1 ket: "$2"',
 'blocklogpage' => 'Listaan ti naserraan',
 'blocklog-showlog' => 'Daytoy nga agar-aramat ket dati a naserraan.
 Ti listaan ti serra ket naikabil dita baba tapno mausar a reperensia:',
@@ -2551,7 +2579,7 @@ Kitaen ti [[Special:BlockList|Listaan ti lapden nga IP]] para iti listaan kadagi
 'range_block_disabled' => 'Ti abilidad ti administrador nga agaramid ti nasakupan a serra ket naiddep.',
 'ipb_expiry_invalid' => 'Imbalido ti oras a panagpaso.',
 'ipb_expiry_temp' => 'Ti serra ti nagan ti agar-aramat ket masapul a permanente.',
-'ipb_hide_invalid' => 'Saan a mapasardeng daytoy a pakabilangan; adda ngata adu unay nga inurnosna.',
+'ipb_hide_invalid' => 'Saan a mapasardeng daytoy a pakabilangan; daytoy ket addaan ti ad-adu ngem {{PLURAL:$1|maysa nga inurnos|dagiti $1 nga inurnos}}.',
 'ipb_already_blocked' => ' "$1" ket naserraan',
 'ipb-needreblock' => '$1 ket naseraan. Kayatmo a sukatan ti serrana?',
 'ipb-otherblocks-header' => 'Sabali {{PLURAL:$1|a naserraan|kadagiti naserraan}}',
@@ -2724,6 +2752,7 @@ Pangngaasi a bisitaen ti [https://www.mediawiki.org/wiki/Localisation Lokalisasi
 'allmessages-prefix' => 'Sagaten babaen ti pasaruno:',
 'allmessages-language' => 'Pagsasao:',
 'allmessages-filter-submit' => 'Inkan',
+'allmessages-filter-translate' => 'Ipatarus',
 
 # Thumbnails
 'thumbnail-more' => 'Padakkelen',
@@ -2740,6 +2769,7 @@ $2',
 'thumbnail_image-type' => 'Daytoy a kita ti ladawan ket saan a nasuportaran.',
 'thumbnail_gd-library' => 'Saan a kompleto a GD biblioteka a pannakaaramid: Awan ti opisio ti $1',
 'thumbnail_image-missing' => 'Daytoy a papeles ket kasla napukaw: $1',
+'thumbnail_image-failure-limit' => 'Adu unayen dagiti nabiit a napaay a panagipadas ($1 wenno ad-adu) a panangiparamg daytoy bassit a ladawan. Pangngaasi a padasen manen intono madamdama.',
 
 # Special:Import
 'import' => 'Agala kadagiti panid',
@@ -2777,7 +2807,7 @@ Paset laeng ti papeles ti napag-ipan.',
 Awan ti saan nga agnayon a polder.',
 'import-parse-failure' => 'Napaay ti pinagala ti XML parse',
 'import-noarticle' => 'Awan ti panid a maaala!',
-'import-nonewrevisions' => 'Amin a panagbalbaliw ket dati a naala.',
+'import-nonewrevisions' => 'Awan dagiti naala panagbalbaliw (mabalin nga adda amin dagitoyen, wenno nalabsan gapu kadagiti biddut).',
 'xml-error-string' => '$1 iti linia $2, tukol $3 (byte $4): $5',
 'import-upload' => 'Ipan ti XML data',
 'import-token-mismatch' => 'Napukaw ti gimong ti datos.
@@ -2789,6 +2819,7 @@ Pangngaasi a padasem manen.',
 'import-error-special' => 'Ti panid ti "$1" ket saan a naala ngamin ket bukod ti  espesial a nagan a lugar a saan nga agpalubos ti pampanid.',
 'import-error-invalid' => 'Ti panid ti "$1" ket saan a naala ngamin ket ti nagan ket imbalido.',
 'import-error-unserialize' => 'Ti panagbaliw ti $2 iti panid ti "$1" ket di maipagsasaruno. Ti panagbalbaliw ket naireporta idi nga agus-usar ti modelo ti $3 a naipagsasaruno a kas $4.',
+'import-error-bad-location' => 'Ti panagbaliw ti $2 nga agus-usar ti modelo a linaon ti $3 ket saan a maipenpen iti "$1" iti daytoy a wiki, gapu ta dayta a modelo ket saan a nasuportaran iti dayta a panid.',
 'import-options-wrong' => 'Saan a husto {{PLURAL:$2|a pagpilian|a pagpilpilian}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Ti naited a ramut ti panid ket imbalido a titulo.',
 'import-rootpage-nosubpage' => 'Ti nagan ti lugar ti "$1" iti ramut ti panid ket saan amangpalubos kadagiti apo ti panid.',
@@ -3568,7 +3599,7 @@ Pangngaasi a pasingkedam nga agpayso a kayatmo a partuten manen daytoy a panid."
 
 # Language selector for translatable SVGs
 'img-lang-default' => '(kasisigud a pagsasao)',
-'img-lang-info' => 'Ipaay daytoy a ladawan iti $1 $2.',
+'img-lang-info' => 'Ipaay daytoy a ladawan iti $1. $2',
 'img-lang-go' => 'Inkan',
 
 # Table pager
@@ -3649,8 +3680,18 @@ Mabalinmo pay nga [[Special:EditWatchlist|usaren ti dati a panagurnos]].',
 'version-parser-function-hooks' => 'Parser a pamay-an dagiti kawit',
 'version-hook-name' => 'Nagan ti kawit',
 'version-hook-subscribedby' => 'Umanamong babaen ti',
-'version-version' => '(Bersion $1)',
-'version-license' => 'Lisensia',
+'version-version' => '($1)',
+'version-license' => 'Lisensia ti MediaWiki',
+'version-ext-license' => 'Lisensia',
+'version-ext-colheader-name' => 'Pagpaatiddog',
+'version-ext-colheader-version' => 'Bersion',
+'version-ext-colheader-license' => 'Lisensia',
+'version-ext-colheader-description' => 'Deskripsion',
+'version-ext-colheader-credits' => 'Dagiti mannurat',
+'version-license-title' => 'Lisensia para iti $1',
+'version-license-not-found' => 'Awan ti nabirukan a naisalaysay a pakaammo ti lisensia para iti daytoy a pagpaatiddog.',
+'version-credits-title' => 'Dagiti pammadayaw para iti $1',
+'version-credits-not-found' => 'Awan dagiti nabirukan a naisalaysay a pammadayaw para iti daytoy a pagpaatiddog.',
 'version-poweredby-credits' => "Daytoy a wiki ket pinaandar ti '''[https://www.mediawiki.org/ MediaWiki]''', karbengan a kopia © 2001-$1 $2.",
 'version-poweredby-others' => 'dadduma pay',
 'version-poweredby-translators' => 'agipatpatarus ti translatewiki.net',
@@ -3668,16 +3709,18 @@ Naka-awatka koman ti [{{SERVER}}{{SCRIPTPATH}}/COPYING kopia iti GNU Sapasap a
 'version-entrypoints-header-url' => 'URL',
 
 # Special:Redirect
-'redirect' => 'Ibaw-ing babaen ti papeles, agar-aramat, wenno ID ti panagbaliw',
+'redirect' => 'Ibaw-ing babaen ti papeles, agar-aramat, panid wenno ID ti panagbaliw',
 'redirect-legend' => 'Ibaw-ing iti papeles wenno panid',
-'redirect-summary' => 'Daytoy nga espesial a panid ket maibaw-ing iti papeles (iti nagan ti papeles), ti panid (iti ID ti panagbaliw), wenno ti panid ti agar-aramat (iti numeriko nga ID ti agar-aramat). Panag-usar:
+'redirect-summary' => 'Daytoy nga espesial a panid ket maibaw-ing iti papeles (iti nagan ti papeles), ti panid (iti ID wenno panid ti panagbaliw), wenno ti panid ti agar-aramat (iti numeriko nga ID ti agar-aramat). Panag-usar:
 [[{{#Special:Redirect}}/file/Example.jpg]], 
+[[{{#Special:Redirect}}/page/64308]], 
 [[{{#Special:Redirect}}/revision/328429]], wenno
 [[{{#Special:Redirect}}/user/101]].',
 'redirect-submit' => 'Inkan',
 'redirect-lookup' => 'Kitaen:',
 'redirect-value' => 'Pateg:',
 'redirect-user' => 'ID ti agar-aramat',
+'redirect-page' => 'ID ti panid',
 'redirect-revision' => 'Panagbaliw ti panid',
 'redirect-file' => 'Nagan ti papeles',
 'redirect-not-exists' => 'Saan a nabirukan ti pateg',
@@ -3871,6 +3914,7 @@ Nupay kasta, mau-sarmo ti nakabuklan dita baba. Ti komentario nga itedmo ket mai
 'api-error-overwrite' => 'Saan a mabalin a suratan manen iti papeles nga adda ditan.',
 'api-error-stashfailed' => 'Kinauneg a biddut: Napaay ti server ti agidulin ti temporario a papeles',
 'api-error-publishfailed' => 'Kinauneg a biddut: Napaay ti server a nagipablaak ti temporario a papeles.',
+'api-error-stasherror' => 'Adda maysa a biddut bayat nga agikarkarga ti papeles iti stash.',
 'api-error-timeout' => 'Saan a simmungbat ti server iti nanamnama nga oras.',
 'api-error-unclassified' => 'Adda di amammo a biddut a rumsua.',
 'api-error-unknown-code' => 'Di am-ammo a biddut: "$1".',
@@ -3920,10 +3964,14 @@ Iti kinapudno, palawaenna amin dagiti adda ti doble a tukol.',
 'expand_templates_input' => 'Maikabil a testo:',
 'expand_templates_output' => 'Nagbanagan',
 'expand_templates_xml_output' => 'XML a maiparang',
+'expand_templates_html_output' => 'Naata a maiparuar a HTML',
 'expand_templates_ok' => 'OK',
 'expand_templates_remove_comments' => 'Ikkaten dagiti komentario',
 'expand_templates_remove_nowiki' => 'Parmeken dagiti <nowiki> nga etiketa kadagiti nagbanagan',
 'expand_templates_generate_xml' => 'Iparang ti XML parse a kayo',
+'expand_templates_generate_rawhtml' => 'Ipakita ti naata a HTML',
 'expand_templates_preview' => 'Pamadasan',
 
+# Unknown messages
+'uploadinvalidxml' => 'Ti XML iti naikarga a papeles ket saan a maiwaswas.',
 );
index 93d4a8c..04522fa 100644 (file)
@@ -394,7 +394,6 @@ $messages = array(
 'vector-action-protect' => 'Vernda',
 'vector-action-undelete' => 'Hætta við eyðingu',
 'vector-action-unprotect' => 'Breyta verndunarstigi',
-'vector-simplesearch-preference' => 'Virkja einfaldaða leitarstiku (Vector-þemað eingöngu)',
 'vector-view-create' => 'Skapa',
 'vector-view-edit' => 'Breyta',
 'vector-view-history' => 'Breytingaskrá',
index 024efdd..5c90b4b 100644 (file)
@@ -11,6 +11,7 @@
  * @author Airon90
  * @author Amire80
  * @author Andria
+ * @author Ankabel
  * @author Aushulz
  * @author Beta16
  * @author Blaisorblade
@@ -457,7 +458,6 @@ $messages = array(
 'vector-action-protect' => 'Proteggi',
 'vector-action-undelete' => 'Recupera',
 'vector-action-unprotect' => 'Cambia la protezione',
-'vector-simplesearch-preference' => 'Abilita la barra per la ricerca semplificata (solo per la skin Vector)',
 'vector-view-create' => 'Crea',
 'vector-view-edit' => 'Modifica',
 'vector-view-history' => 'Cronologia',
@@ -2177,6 +2177,13 @@ I redirect <del>cancellati</del> sono stati corretti.',
 'protectedpages-cascade' => 'Solo protezioni ricorsive',
 'protectedpages-noredirect' => 'Nascondi redirect',
 'protectedpagesempty' => 'Al momento non vi sono pagine protette',
+'protectedpages-timestamp' => 'Data e ora',
+'protectedpages-page' => 'Pagina',
+'protectedpages-expiry' => 'Scadenza',
+'protectedpages-params' => 'Parametri di protezione',
+'protectedpages-reason' => 'Motivo',
+'protectedpages-unknown-timestamp' => 'Sconosciuto',
+'protectedpages-unknown-performer' => 'Utente sconosciuto',
 'protectedtitles' => 'Titoli protetti',
 'protectedtitlesempty' => 'Al momento non esistono titoli protetti con i parametri specificati.',
 'listusers' => 'Elenco degli utenti',
@@ -2915,6 +2922,7 @@ $2',
 'thumbnail_image-type' => 'Tipo di immagine non supportato',
 'thumbnail_gd-library' => 'Configurazione incompleta della libreria GD: funzione $1 mancante',
 'thumbnail_image-missing' => 'Sembra essere mancante il file: $1',
+'thumbnail_image-failure-limit' => 'Ci sono stati recentemente troppi tentativi falliti ($1 o più) di generare questa miniatura. Riprova più tardi.',
 
 # Special:Import
 'import' => 'Importa pagine',
index 48028df..7b82db3 100644 (file)
@@ -533,7 +533,6 @@ $messages = array(
 'vector-action-protect' => '保護',
 'vector-action-undelete' => '復元',
 'vector-action-unprotect' => '保護再設定',
-'vector-simplesearch-preference' => '簡素化した検索バーを有効にする (ベクター外装のみ)',
 'vector-view-create' => '作成',
 'vector-view-edit' => '編集',
 'vector-view-history' => '履歴表示',
@@ -2351,10 +2350,17 @@ contenttype/subtypeの形式で入力してください (例: <code>image/jpeg</
 'deadendpagestext' => '以下のページは、{{SITENAME}}の他のページにリンクしていません。',
 'protectedpages' => '保護されているページ',
 'protectedpages-indef' => '無期限保護のみ',
+'protectedpages-summary' => 'このページでは、現時点で保護されている既存のページを列挙します。新規作成が禁止されているページ名の一覧は、[[{{#special:ProtectedTitles}}]] を参照してください。',
 'protectedpages-cascade' => 'カスケード保護のみ',
 'protectedpages-noredirect' => 'リダイレクトを隠す',
 'protectedpagesempty' => '指定した条件で保護中のページは現在ありません。',
+'protectedpages-timestamp' => '日時',
+'protectedpages-page' => 'ページ',
+'protectedpages-expiry' => '有効期限',
+'protectedpages-reason' => '理由',
+'protectedpages-unknown-timestamp' => '不明',
 'protectedtitles' => '作成保護されているページ名',
+'protectedtitles-summary' => 'このページでは、現時点で新規作成が禁止されているページ名を列挙します。保護されている既存のページの一覧は、[[{{#special:ProtectedPages}}]] を参照してください。',
 'protectedtitlesempty' => 'これらの引数で現在保護されているページはありません。',
 'listusers' => '利用者一覧',
 'listusers-editsonly' => '投稿記録のある利用者のみを表示',
index 56787df..4908dca 100644 (file)
@@ -202,7 +202,6 @@ $messages = array(
 'vector-action-protect' => 'Bısevekne',
 'vector-action-undelete' => 'Esterıtene peyser bıcê',
 'vector-action-unprotect' => 'Rake',
-'vector-simplesearch-preference' => 'Tewsiyunê cıcêraişiê raverberdu rake (Teyna vector skin de)',
 'vector-view-create' => 'Vıraze',
 'vector-view-edit' => 'Bıvurne',
 'vector-view-history' => 'Tarixi basne',
@@ -790,11 +789,11 @@ Diqet kerê, beno ke tedeestê {{SITENAME}} uza endi rozane niyê.",
 'yourrealname' => 'Namo rastıkên:',
 'yourlanguage' => 'Zon:',
 'yourvariant' => 'Varyant:',
-'yournick' => 'İmza:',
+'yournick' => 'Leqeme:',
 'badsig' => "İmza kala nêvêrdiye.
 Etiketê ''HTML''i qontrol ke.",
 'badsiglength' => 'İmza to zaf derga.
-$1 gunê {{PLURAL:$1|herfe|herfu}} ra senık bo.',
+A gunê ebe $1 {{PLURAL:$1|herfe|herfu}} ra jêde mebo.',
 'yourgender' => 'Cınsiyet:',
 'gender-male' => 'Cüamêrd',
 'gender-female' => 'Cüanıke',
@@ -1250,7 +1249,7 @@ Tı şikina sewiya sevekiyaena na pele bıvurnê, hema yê nae sevekiyaena qedem
 'contribslink' => 'iştıraqi',
 'emaillink' => 'e-poste bırusne',
 'autoblocker' => 'Sıma otomatikmen kılit biy, çıke adresa sımawa \'\'IP\'\'y terefê "[[User:$1|$1]]" gurenina.
-Sebebê kılit-biyaena $1\'i: "$2"o',
+Sebebê kılitbiyaena $1\'i "$2"o',
 'blocklogpage' => 'Protokolê kilıti',
 'blocklogentry' => '[[$1]] hata peyê $2 $3ine kilıt bi',
 'reblock-logentry' => 'kilıt-kerdena [[$1]]i hata peyê $2 $3ine vurnê',
index c6285a8..e6329fc 100644 (file)
@@ -424,7 +424,6 @@ $messages = array(
 'vector-action-protect' => 'ការពារ',
 'vector-action-undelete' => 'ឈប់លុបចោល',
 'vector-action-unprotect' => 'ប្ដូរការការពារ',
-'vector-simplesearch-preference' => 'ប្រើរបារស្វែងរកសាមញ្ញ (សំរាប់តែសំបកវ៉ិចទ័រប៉ុណ្ណោះ)',
 'vector-view-create' => 'បង្កើត​',
 'vector-view-edit' => 'កែប្រែ​',
 'vector-view-history' => 'មើល​ប្រវត្តិ​',
@@ -1379,7 +1378,7 @@ $1",
 'prefs-labs' => 'មុខងារពិសេសថ្មីៗដែលស្ថិតក្រោមការពិសោធន៍នៅឡើយ',
 'prefs-user-pages' => 'ទំព័រអ្នកប្រើប្រាស់',
 'prefs-personal' => 'ប្រវត្តិរូប',
-'prefs-rc' => 'á\9e\94á\9f\86á\9e\9bá\9e¶á\9e\9fá\9f\8bá\9e\94á\9f\92á\9e\8aá\9e¼á\9e\9aថ្មីៗ',
+'prefs-rc' => 'á\9e\94á\9e\93á\9f\92á\9e\9bá\9e¶á\9e\9fá\9f\8bâ\80\8bá\9e\94á\9f\92á\9e\8aá\9e¼á\9e\9aâ\80\8bថ្មីៗ',
 'prefs-watchlist' => 'បញ្ជីតាមដាន',
 'prefs-watchlist-days' => 'ចំនួនថ្ងៃត្រូវបង្ហាញក្នុងបញ្ជីតាមដាន៖',
 'prefs-watchlist-days-max' => 'អតិបរមា $1 {{PLURAL:$1|ថ្ងៃ|ថ្ងៃ}}',
index 9a0db2c..fc44a79 100644 (file)
@@ -526,7 +526,6 @@ $messages = array(
 'vector-action-protect' => '보호',
 'vector-action-undelete' => '되살리기',
 'vector-action-unprotect' => '보호 설정 바꾸기',
-'vector-simplesearch-preference' => '단순한 검색 막대 사용하기 (벡터 스킨 전용)',
 'vector-view-create' => '만들기',
 'vector-view-edit' => '편집',
 'vector-view-history' => '역사',
@@ -731,7 +730,7 @@ URL을 잘못 입력하였거나, 잘못된 링크를 따라갔을 수 있습니
 'badtitletext' => '요청한 문서 제목이 잘못되었거나, 비어있거나, 잘못된 인터위키 제목으로 링크했습니다.
 문서 제목에 사용할 수 없는 문자를 사용했을 수 있습니다.',
 'perfcached' => '다음 자료는 캐시된 것이므로 새로 바뀐 내용을 반영하지 못할 수도 있습니다. 캐시에 최대 {{PLURAL:$1|$1개의 결과}}가 있습니다.',
-'perfcachedts' => '다음 자료는 캐시된 것으로, $1에 마지막으로 새로 고쳐졌습니다.  캐시에 최대 {{PLURAL:$4|결과 $4개}}가 있습니다.',
+'perfcachedts' => '다음 자료는 캐시된 것으로, $1에 마지막으로 새로 고쳐졌습니다. 캐시에 최대 {{PLURAL:$4|결과 $4개}}가 있습니다.',
 'querypage-no-updates' => '이 문서의 새로 고침이 현재 비활성화되어 있습니다.
 이 문서의 자료를 잠시 동안 새로 고치지 않을 것입니다.',
 'viewsource' => '원본 보기',
@@ -833,7 +832,7 @@ $2',
 'createacct-imgcaptcha-ph' => '위에 보이는 텍스트를 입력하세요',
 'createacct-submit' => '계정 만들기',
 'createacct-another-submit' => '다른 계정 만들기',
-'createacct-benefit-heading' => '{{SITENAME}}(은)는 여러분과 같은 사람으로 이루어집니다.',
+'createacct-benefit-heading' => '{{SITENAME}} 프로젝트는 여러분과 같은 사람들이 만듭니다.',
 'createacct-benefit-body1' => '{{PLURAL:$1|편집}}',
 'createacct-benefit-body2' => '{{PLURAL:$1|문서}}',
 'createacct-benefit-body3' => '최근 {{PLURAL:$1|기여자}}',
@@ -931,8 +930,8 @@ $1 기다렸다가 다시 시도하세요.',
 'retypenew' => '새 비밀번호 재입력:',
 'resetpass_submit' => '비밀번호를 설정하고 로그인하기',
 'changepassword-success' => '비밀번호가 성공적으로 바뀌었습니다!',
-'changepassword-throttled' => '로그인에 연속으로 실패하였습니다.
-$1 기다렸다가 다시 시도하세요.',
+'changepassword-throttled' => '최근 너무 많이 로그인을 시도했습니다.
+$1 뒤에 다시 시도하세요.',
 'resetpass_forbidden' => '비밀번호를 바꿀 수 없습니다',
 'resetpass-no-info' => '이 특수 문서에 직접 접근하려면 반드시 로그인해야 합니다.',
 'resetpass-submit-loggedin' => '비밀번호 바꾸기',
@@ -1012,7 +1011,7 @@ $1 기다렸다가 다시 시도하세요.',
 'italic_sample' => '기울인 글씨',
 'italic_tip' => '기울인 글씨',
 'link_sample' => '링크 제목',
-'link_tip' => 'ë\82´ë¶\80 ê³ ë¦¬',
+'link_tip' => 'ì\95\88쪽 ë§\81í\81¬',
 'extlink_sample' => 'http://www.example.com 사이트 이름',
 'extlink_tip' => '바깥 링크 (주소 앞에 http://가 있어야 합니다)',
 'headline_sample' => '제목',
@@ -1192,7 +1191,7 @@ IP 주소는 여러 사용자가 공유할 수 있습니다.
 'nocreatetext' => '{{SITENAME}}에서 새로운 문서를 만드는 것은 제한되어 있습니다.
 이미 존재하는 다른 문서를 편집하거나, [[Special:UserLogin|로그인하거나 계정을 만들]] 수 있습니다.',
 'nocreate-loggedin' => '새 문서를 만들 권한이 없습니다.',
-'sectioneditnotsupported-title' => '부분 편집 지원 안 됨',
+'sectioneditnotsupported-title' => '부분 편집이 지원되지 않음',
 'sectioneditnotsupported-text' => '이 문서에서는 문단 편집을 지원하지 않습니다.',
 'permissionserrors' => '권한 오류',
 'permissionserrorstext' => '해당 명령을 수행할 권한이 없습니다. 다음 {{PLURAL:$1|이유}}를 확인해보세요:',
@@ -1219,8 +1218,8 @@ IP 주소는 여러 사용자가 공유할 수 있습니다.
 'content-not-allowed-here' => '"$1" 내용은 [[$2]] 문서예 허용하지 않습니다',
 'editwarning-warning' => '이 페이지에서 벗어나면 저장하지 않은 바뀜이 모두 사라집니다.
 로그인을 했다면, 환경 설정의 "{{int:편집 상자}}"에서 이 경고를 띄우지 않도록 설정할 수 있습니다.',
-'editpage-notsupportedcontentformat-title' => '지원하지 않는 컨텐츠 형식',
-'editpage-notsupportedcontentformat-text' => '컨텐츠 모델 $2 에서는 컨텐츠형식 $1을 지원하지 않습니다.',
+'editpage-notsupportedcontentformat-title' => '지원하지 않는 내용 형식',
+'editpage-notsupportedcontentformat-text' => '내용 형식 $1(은)는 $2 내용 모델에서 지원하지 않습니다.',
 
 # Content models
 'content-model-wikitext' => '위키텍스트',
@@ -1255,6 +1254,7 @@ $2개 보다 적게 {{PLURAL:$2|써야}} 하지만 {{PLURAL:$1|지금은 $1개
 편집 되돌리기를 완료하려면 이 편집을 되돌리려면 아래의 바뀐 내용을 확인한 후 저장해주세요.',
 'undo-failure' => '중간의 다른 편집과 충돌하여 이 편집을 되돌릴 수 없습니다.',
 'undo-norev' => '문서가 없거나 삭제되었기 때문에 편집을 되돌릴 수 없습니다.',
+'undo-nochange' => '편집이 이미 되돌려진 것으로 나타납니다.',
 'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|토론]])의 $1판 편집을 되돌림',
 'undo-summary-username-hidden' => '숨겨진 사용자가 $1 판을 되돌림',
 
@@ -1347,7 +1347,7 @@ $2개 보다 적게 {{PLURAL:$2|써야}} 하지만 {{PLURAL:$1|지금은 $1개
 * 부적절한 개인 정보
 *: 집 주소, 전화번호, 주민등록번호 등",
 'revdelete-legend' => '보이기 제한을 설정',
-'revdelete-hide-text' => 'í\8c\90 ë\82´ì\9a©',
+'revdelete-hide-text' => 'í\8c\90 ë¬¸ì\9e\90ì\97´',
 'revdelete-hide-image' => '파일을 숨기기',
 'revdelete-hide-name' => '명령 내용과 대상을 숨기기',
 'revdelete-hide-comment' => '편집 요약',
@@ -1468,7 +1468,7 @@ $1",
 'searchprofile-articles-tooltip' => '$1에서 검색',
 'searchprofile-project-tooltip' => '$1에서 검색',
 'searchprofile-images-tooltip' => '파일 검색',
-'searchprofile-everything-tooltip' => '모ë\93  ë¬¸ì\84\9c ê²\80ì\83\89\86 ë¡  ë¬¸ì\84\9c를 í\8f¬í\95¨)',
+'searchprofile-everything-tooltip' => '모ë\93  ë\82´ì\9a© (í\86 ë¡  ë¬¸ì\84\9c를 í\8f¬í\95¨) ê²\80ì\83\89',
 'searchprofile-advanced-tooltip' => '다음 설정한 이름공간에서 검색',
 'search-result-size' => '$1 ({{PLURAL:$2|1 단어|$2 단어}})',
 'search-result-category-size' => '{{PLURAL:$1|문서 1개|문서 $1개}}, {{PLURAL:$2|하위 분류 1개|하위 분류 $2개}}, {{PLURAL:$3|파일 1개|파일 $3개}}',
@@ -1485,7 +1485,8 @@ $1",
 'searchrelated' => '관련',
 'searchall' => '모두',
 'showingresults' => "'''$2'''번 부터의 {{PLURAL:$1|결과 '''1'''개|결과 '''$1'''개}}입니다.",
-'showingresultsnum' => "'''$2'''번 부터의 {{PLURAL:$3|결과 '''1'''개|결과 '''$3'''개}} 입니다.",
+'showingresultsinrange' => '#<strong>$2</strong>부터 #<strong>$3</strong>까지의 범위에서 <strong>$1</strong>개의 {{PLURAL:$1|결과}}가 아래에 보입니다.',
+'showingresultsnum' => "'''$2'''번 부터의 {{PLURAL:$3|결과 '''1'''개|결과 '''$3'''개}}입니다.",
 'showingresultsheader' => "'''$4''' 검색어에 대한 {{PLURAL:$5|결과 '''$3'''개 중 '''$1'''개|결과 '''$3'''개 중 '''$1 - $2'''번째}}",
 'search-nonefound' => '검색어와 일치하는 결과가 없습니다.',
 'powersearch-legend' => '고급 검색',
@@ -1544,7 +1545,7 @@ $1",
 'savedprefs' => '설정을 저장했습니다.',
 'timezonelegend' => '시간대:',
 'localtime' => '현지 시각:',
-'timezoneuseserverdefault' => '위키 기본 값($1)을 사용',
+'timezoneuseserverdefault' => '위키 기본값 사용 ($1)',
 'timezoneuseoffset' => '기타 (시차를 입력해주세요)',
 'servertime' => '서버 시각:',
 'guesstimezone' => '웹 브라우저 설정에서 가져오기',
@@ -1562,7 +1563,7 @@ $1",
 'prefs-searchoptions' => '검색',
 'prefs-namespaces' => '이름공간',
 'defaultns' => '다음 이름공간에서 검색:',
-'default' => '기본 값',
+'default' => '기본값',
 'prefs-files' => '파일',
 'prefs-custom-css' => '사용자 CSS',
 'prefs-custom-js' => '사용자 자바스크립트',
@@ -1586,7 +1587,7 @@ HTML 태그를 확인하세요.',
 'badsiglength' => '서명이 너무 깁니다.
 서명은 $1 {{PLURAL:$1|글자}}보다 짧아야 합니다.',
 'yourgender' => '어떤 성별로 표시되는 것을 선호합니까?',
-'gender-unknown' => '밝히고 싶지 않습니다.',
+'gender-unknown' => '밝히고 싶지 않습니다',
 'gender-male' => '위키 문서를 편집하는 남자입니다',
 'gender-female' => '위키 문서를 편집하는 여자입니다',
 'prefs-help-gender' => '이 항목은 선택 사항입니다.
@@ -1682,7 +1683,7 @@ HTML 태그를 확인하세요.',
 'right-move-subpages' => '문서와 하위 문서 이동하기',
 'right-move-rootuserpages' => '최상위 사용자 문서 이동',
 'right-movefile' => '파일 옮기기',
-'right-suppressredirect' => '문서 이동할 때 이전 이름으로 된 넘겨주기를 만들지 않기',
+'right-suppressredirect' => '문서을 옮길 때 원래 문서 이름으로 된 넘겨주기를 만들지 않기',
 'right-upload' => '파일 올리기',
 'right-reupload' => '이미 존재하는 파일을 다시 올리기',
 'right-reupload-own' => '자신이 이미 올린 파일 덮어쓰기',
@@ -1757,7 +1758,7 @@ HTML 태그를 확인하세요.',
 'action-createaccount' => '새 계정 만들기',
 'action-minoredit' => '이 편집을 사소한 편집으로 표시하기',
 'action-move' => '이 문서 옮기기',
-'action-move-subpages' => '하위 문서를 함께 옮길',
+'action-move-subpages' => '이 문서와 하위 문서를 함께 옮기기',
 'action-move-rootuserpages' => '최상위 사용자 문서를 이동할',
 'action-movefile' => '이 파일을 옮기기',
 'action-upload' => '이 파일을 올리기',
@@ -1799,7 +1800,7 @@ HTML 태그를 확인하세요.',
 'recentchanges-summary' => '위키의 최근 바뀜이 나와 있습니다.',
 'recentchanges-noresult' => '지정한 조건과 일치하는 주어진 기간 동안 바뀜이 없습니다.',
 'recentchanges-feed-description' => '위키의 최근 바뀜이 나와 있습니다.',
-'recentchanges-label-newpage' => '새 문서',
+'recentchanges-label-newpage' => '새로 만든 문서',
 'recentchanges-label-minor' => '사소한 편집',
 'recentchanges-label-bot' => '봇의 편집',
 'recentchanges-label-unpatrolled' => '아직 순찰하지 않은 편집',
@@ -2254,7 +2255,7 @@ URL이 맞고 해당 웹사이트가 작동하는지 확인해주세요.',
 'pageswithprop-legend' => '문서 속성이 있는 문서',
 'pageswithprop-text' => '이 문서는 특정 문서 속성을 사용한 문서를 나타냅니다.',
 'pageswithprop-prop' => '속성 이름:',
-'pageswithprop-submit' => '기',
+'pageswithprop-submit' => '기',
 'pageswithprop-prophidden-long' => '숨겨진 긴 텍스트 속성 값 ($1)',
 'pageswithprop-prophidden-binary' => '숨겨진 이진 속성 값 ($1)',
 
@@ -2324,8 +2325,16 @@ URL이 맞고 해당 웹사이트가 작동하는지 확인해주세요.',
 'protectedpages' => '보호된 문서 목록',
 'protectedpages-indef' => '오른쪽 조건에 맞는 보호만 보기',
 'protectedpages-cascade' => '연쇄적 보호만 보기',
-'protectedpages-noredirect' => '넘겨주기 숨김',
+'protectedpages-noredirect' => '넘겨주기를 숨기기',
 'protectedpagesempty' => '보호되어 있는 문서가 없습니다.',
+'protectedpages-timestamp' => '시간 기록',
+'protectedpages-page' => '문서',
+'protectedpages-expiry' => '만료 기한',
+'protectedpages-performer' => '사용자를 보호',
+'protectedpages-params' => '보호 매개변수',
+'protectedpages-reason' => '이유',
+'protectedpages-unknown-timestamp' => '알 수 없음',
+'protectedpages-unknown-performer' => '알 수 없는 사용자',
 'protectedtitles' => '만들기 보호된 표제어 목록',
 'protectedtitlesempty' => '해당 조건에 맞는 만들기 금지 표제어가 없습니다.',
 'listusers' => '사용자 목록',
@@ -2515,7 +2524,7 @@ URL이 맞고 해당 웹사이트가 작동하는지 확인해주세요.',
 'watchmethod-list' => '최근 편집을 확인하고자 주시된 문서 확인',
 'watchlistcontains' => '{{PLURAL:$1|문서 $1개}}를 주시하고 있습니다.',
 'iteminvalidname' => "'$1' 항목에 문제가 발생했습니다. 이름이 잘못되었습니다...",
-'wlnote2' => '아래는 $2, $3 기준으로 지난 {{PLURAL:$1|hour|<strong>$1</strong> 시간}} 동안의 바뀜입니다.',
+'wlnote2' => '아래는 $2, $3 기준으로 지난 {{PLURAL:$1|한 시간|<strong>$1</strong>시간}} 동안의 바뀜입니다.',
 'wlshowlast' => '최근 $1시간 $2일 또는 $3 동안에 바뀐 문서 보기',
 'watchlist-options' => '주시문서 목록 설정',
 
@@ -3101,6 +3110,8 @@ $2',
 'thumbnail_image-type' => '그림 형식이 지원되지 않습니다',
 'thumbnail_gd-library' => 'GD 라이브러리 설정이 잘못되었습니다: $1 함수를 찾을 수 없습니다.',
 'thumbnail_image-missing' => '파일을 찾을 수 없습니다: $1',
+'thumbnail_image-failure-limit' => '여기에 이 섬네일을 렌더하는 데 최근에 너무 많이 실패한 시도($1 이상)가 있습니다.
+나중에 다시 시도하세요.',
 
 # Special:Import
 'import' => '문서 가져오기',
@@ -4013,7 +4024,7 @@ $5
 
 # Friendlier slave lag warnings
 'lag-warn-normal' => '최근 $1{{PLURAL:$1|초}} 안에 바뀐 문서는 이 목록에서 빠졌을 수 있습니다.',
-'lag-warn-high' => 'ë\8d°ì\9d´í\84°ë² ì\9d´ì\8a¤ ì\84\9cë²\84ì\9d\98 ê³¼ë\8f\84í\95\9c ë¶\80í\95\98 ë\95\8c문ì\97\90 ìµ\9cê·¼ $1{{PLURAL:$1|ì´\88}} ì\95\88ì\97\90 ë°\94ë\80\90 ë¬¸ì\84\9c ëª©ë¡\9dì\9d\80 ë³´ì\97¬ì§\80지 않을 수 있습니다.',
+'lag-warn-high' => 'ë\8d°ì\9d´í\84°ë² ì\9d´ì\8a¤ ì\84\9cë²\84ì\9d\98 ê³¼ë\8f\84í\95\9c ë¶\80í\95\98 ë\95\8c문ì\97\90 ìµ\9cê·¼ $1{{PLURAL:$1|ì´\88}} ì\95\88ì\97\90 ë°\94ë\80\90 ë¬¸ì\84\9c ëª©ë¡\9dì\9d\80 ë³´ì\9d´지 않을 수 있습니다.',
 
 # Watchlist editor
 'watchlistedit-numitems' => '토론 문서를 제외하고 {{PLURAL:$1|문서 1개|문서 $1개}}를 주시하고 있습니다.',
@@ -4312,7 +4323,7 @@ $5
 'duration-hours' => '$1{{PLURAL:$1|시간}}',
 'duration-days' => '$1{{PLURAL:$1|일}}',
 'duration-weeks' => '$1{{PLURAL:$1|주}}',
-'duration-years' => '$1{{PLURAL:$1|년}}',
+'duration-years' => '$1',
 'duration-decades' => '$1{{PLURAL:$1|0년}}',
 'duration-centuries' => '$1{{PLURAL:$1|세기}}',
 'duration-millennia' => '$1{{PLURAL:$1|천년}}',
index 7a846a6..b4cfc0b 100644 (file)
@@ -375,7 +375,6 @@ $messages = array(
 'vector-action-protect' => 'Schöze!',
 'vector-action-undelete' => 'Zerökholle!',
 'vector-action-unprotect' => 'Schoz ändere!',
-'vector-simplesearch-preference' => 'Donn et eijfachere Söke aanschallde (bloß mem Ußsinn „Vektor“ zesamme ze hann)',
 'vector-view-create' => 'Neu Schriive!',
 'vector-view-edit' => 'Ändere!',
 'vector-view-history' => 'Versione zeije!',
@@ -571,6 +570,7 @@ un doht em och de URL vun dä Sigg heh sage.',
 'cannotdelete-title' => 'Mer künne di Sigg „$1“ nit fott schmiiße.',
 'delete-hook-aborted' => 'Et Fottschmiiße wood affjebroche övver ene sujenannte „Hoke“ en de ẞoffwäer.
 Ene Jrond weße mer nit.',
+'no-null-revision' => 'Mer kunnte kein onveränderte neue Väsjohn vun dä Sigg „$1“ aanlääje.',
 'badtitle' => 'Verkihrte Üvverschreff',
 'badtitletext' => 'De Üvverschreff es esu nit en Odenung. Et muss jet dren stonn.
 Et künnt sin, dat ein vun de speziell Zeiche dren steiht,
@@ -623,7 +623,7 @@ Dä Wiki_Köbes dovun hät beim Deeschmaache als Jrond aanjejovve: „$3“',
 'invalidtitle-knownnamespace' => '„$3“ es ene onjöltijje Tittel för em Appachtemang „$2“',
 'invalidtitle-unknownnamespace' => '„$2“ es ene onjöltijje Tittel för e Appachtemang met dä verkehte Nommer $1.',
 'exception-nologin' => 'Nit enjelogg',
-'exception-nologin-text' => 'Heh di Sigg udder heh dä Opdraach jeiht blooß, wann De heh em Wiki enjelogg bes.',
+'exception-nologin-text' => 'Heh di Sigg udder heh dä Opdraach jeiht blooß, wann De heh [[Special:Userlogin|em Wiki enjelogg]] bes.',
 'exception-nologin-text-manual' => 'De mööds ald $1, öm heh di Sigg udder di Axjuhn zohjriife ze dörve.',
 
 # Virus scanner
@@ -674,7 +674,7 @@ Wann De wells, künnts De Ding [[Special:Preferences|Enschtällonge aanpaße]].'
 'userlogin-resetpassword-link' => 'Paßwoot verjäße?',
 'helplogin-url' => 'Help:Övver et Enlogge',
 'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Hölp bem Enlogge]]',
-'userlogin-loggedin' => 'Do bes ald als {{GENDER:$1|Metmaacher|Metmaacherėn|Metmaacher|Metmaacherėn|Metmaacher}} [[User:$1]] enjelogg. Met heh dämm Fommolaa kanns De jäz onger enem andere Nahme enlogge.',
+'userlogin-loggedin' => 'Do bes ald als {{GENDER:$1|dä Metmaacher|de Metmaacherėn|dä Metmaacher|de Metmaacherėn|däMetmaacher}} [[User:$1]] enjelogg. Met heh dämm Fommolaa kanns De jäz onger enem andere Nahme enlogge.',
 'userlogin-createanother' => 'Donn ene zohsäzlejje Zohjang aanlääje',
 'createacct-join' => 'Jiv Ding Daate en:',
 'createacct-another-join' => 'Maach de nüüdeje Aanjaabe för dä neue Zohjaang.',
@@ -817,6 +817,7 @@ Wann dä aanjejovve es, weet_e jebruch, öm öffentlesch de Schriiver för Beidr
 'retypenew' => 'Noch ens dat neue Passwood:',
 'resetpass_submit' => 'E neu Zweschepasswood övvermeddele un aanmellde',
 'changepassword-success' => 'Et Paßwood es jeändert.',
+'changepassword-throttled' => 'Do häs zoh öff versöhk, enzelogge. Waat $1 Ih dat De es widder probeers.',
 'resetpass_forbidden' => 'E Passwoot kann nit jeändert wääde.',
 'resetpass-no-info' => 'Do mööts ad enjelogg sin, öm tiräk op di Sigg jonn ze dörve',
 'resetpass-submit-loggedin' => 'Passwood tuusche',
@@ -882,9 +883,20 @@ Do moß Ding Paßwoot enjävve, öm Ding Änderong ze bschtäätejje.',
 'changeemail-password' => 'Ding Passwoot {{GRAMMAR:en 3|{{ucfirst:{{SITENAME}}}}}}:',
 'changeemail-submit' => 'Lohß jonn!',
 'changeemail-cancel' => 'Ophüre',
+'changeemail-throttled' => 'Do häs zoh öff versöhk, enzelogge. Waat $1 Ih dat De es widder probeers.',
 
 # Special:ResetTokens
+'resettokens' => 'Neue Schlößel maache',
+'resettokens-text' => 'Do kanns neue Schlößel maache lohße för op beschtemmpte päsöhnlesche Daate uohjriife ze künne, di met Dingem Zohjang heh ze donn han.
+
+Donn dat op jeede Fall, wann se enem Andere bikannt jewoode sin, udder wann Dinge Zohjang jeknack woode es.',
+'resettokens-no-tokens' => 'Et sin kein Schlößele doh, för neu ze maache.',
+'resettokens-legend' => 'Neue Schlößel maache',
+'resettokens-tokens' => 'Schlößele:',
 'resettokens-token-label' => '$1 (Em Momang es et: $2)',
+'resettokens-watchlist-token' => 'ä schlößel för dä <i lang="en" xml:lang="en">Atom</i>- udder <i lang="en" xml:lang="en">RSS</i>-Kanaal met de [[Special:Watchlist|Änderonge aan Sigge en Dinger Oppaßleß]]',
+'resettokens-done' => 'Schlößel neu jemaat.',
+'resettokens-resetbutton' => 'Lohß Jonn!',
 
 # Edit page toolbar
 'bold_sample' => 'Fätte Schreff',
@@ -1137,6 +1149,8 @@ Ene Jrond weße mer nit.',
 'content-not-allowed-here' => 'Ene Enhalld vun dä Zoot „$1“ es op dä Sigg „[[$2]]“ nit zohjelohße.',
 'editwarning-warning' => 'Wann de vun hee dä Sigg fott jeihß, doh künnte all Ding Änderonge aan dä Sigg verschött jonn.
 Do kanns heh di Warnung affschallde, wann de aanjemelldt un enjelogg bes, dann kriß de se nieh mieh wider. Jangk doför en dä Afschnett „{{int:prefs-editing}}“ en Dinge Enschtellonge.',
+'editpage-notsupportedcontentformat-title' => 'Dat Fommat vun enem Enhalld künne mer nit.',
+'editpage-notsupportedcontentformat-text' => 'Dat Fommat $1 vun enem Enhalld künne mer nit mem Modäll $2.',
 
 # Content models
 'content-model-wikitext' => 'Wikitäx',
@@ -1168,6 +1182,7 @@ Do kanns heh di Warnung affschallde, wann de aanjemelldt un enjelogg bes, dann k
 'undo-success' => 'De Änderung könnte mer zeröck nämme. Beloor Der de Ungerscheid un dann donn di Sigg avspeichere, wann De dengks, et es en Oodenung esu.',
 'undo-failure' => 'Dat kunnt mer nit zeröck nämme, dä Afschnedd wood enzwesche ald widder beärbeidt.',
 'undo-norev' => "Do ka'mer nix zeröck nämme. Di Version jidd_et nit, odder se es verstoche odder fottjeschmesse woode.",
+'undo-nochange' => 'Di Änderong schingk ald retuur jemaat woode ze sin.',
 'undo-summary' => 'De Änderung $1 fum [[Special:Contributions/$2|$2]] ([[User talk:$2|Klaaf]]) zeröck jenomme.',
 'undo-summary-username-hidden' => 'Nemm di Väsjohn $1 vun enem verschtoche Metmaacher widder retuur.',
 
@@ -1176,6 +1191,10 @@ Do kanns heh di Warnung affschallde, wann de aanjemelldt un enjelogg bes, dann k
 'cantcreateaccount-text' => "Dä [[User:$3|$3]] hät verbodde, dat mer sich vun dä IP-Adress '''$1''' uß als ene neue Metmaacher aanmelde könne soll.
 
 Als Jrund för et Sperre es enjedraare: ''$2''",
+'cantcreateaccount-range-text' => 'Ne neue Metmacher aanmälde vun <i lang="en" xml:lang="en">IP</i>-Adräße em Berett vun <strong>$1</strong>, woh de Dinge dren es, wood vum {{GENDER:$3|vum|vum|vumm Metmaacher|vun dä|vum}} [[User:$3|$3]] verbodde.
+Der Jrond: <em><$2</em>
+
+Ding <i lang="en" xml:lang="en">IP</i>-Adräß es: <strong>$4</strong>',
 
 # History pages
 'viewpagelogs' => 'De Logböcher för heh di Sigg beloore',
@@ -1264,11 +1283,11 @@ dem Wiki singe Installation dat anders fassjelaht woode es.",
 * unjenehmesch persöhnlesch Daate
 *: ''Aanschreffte, Tellefoon- un ander Nummere, <span lang=\"en\" xml:lang=\"en\">e-mail</span> Adräß, uew.''",
 'revdelete-legend' => 'Dä öffentlije Zojang enschränke',
-'revdelete-hide-text' => 'Dä Tex vun dä Version versteiche',
+'revdelete-hide-text' => 'dä Täx vun dä Väsjohn',
 'revdelete-hide-image' => 'De Enhallt vun däm Beld versteiche',
 'revdelete-hide-name' => 'Der Förjang, un och der Enndraach uss_em Logboch, versteiche',
-'revdelete-hide-comment' => 'Dä Enhald vun „Koot Zosammejefass, Quell“ ußblände',
-'revdelete-hide-user' => 'Däm Bearbeider sing IP Adress oder Metmaacher Name versteiche',
+'revdelete-hide-comment' => 'dä Enhald vun „Koot Zosammejefass, Quell“',
+'revdelete-hide-user' => 'däm Bearbeider sing <i lang="en" xml:lang="en"IP</i>-Adress oder Metmaacher-Name',
 'revdelete-hide-restricted' => 'Dun dat och för de Wiki-Köbesse esu maache wie för jede Andere',
 'revdelete-radio-same' => '(lohß wi_t eß)',
 'revdelete-radio-set' => 'Jo',
@@ -1346,6 +1365,8 @@ Donn de Version makeere bes wohen (inklusive) dat övverdraare wäde sull. Donn
 'showhideselectedversions' => 'De ußjewählte Versione aanzeije udder vershteiche',
 'editundo' => 'De letzte Änderung zeröck nämme',
 'diff-empty' => '(Keine Ongerscheid)',
+'diff-multi-sameuser' => '(Mer don hee {{PLURAL:$1|eij Väsjohn|$1 Väsjohne|keij Väsjohn}} dozwesche nit zeije.   Se {{PLURAL:$1|es|sin|wöhr}} vum sällve Metmaacher)',
+'diff-multi-otherusers' => '(Mer don hee {{PLURAL:$1|eij Väsjohn|$1 Väsjohne|keij Väsjohn}} dozwesche vun {{PLURAL:$1|einem|$1 ongerscheidlijje|keinem}} Metmaacher nit zeije)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Ein Version|$1 Versione|kei Version}} dozwesche vun mieh wi {{PLURAL:$2|einem Metmaacher|$2 Metmaachere|keinem Metmaacher}} wääde nit jezeish)',
 'difference-missing-revision' => '{{PLURAL:$2|Ein Version|$2 Versione}} vun heh däm Verjlisch zwesche Versione ($1) {{PLURAL:$2|hammer}} nit jefonge.
 
@@ -1366,7 +1387,8 @@ Mieh doh drövver fengk mer em [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAG
 'shown-title' => 'Zeisch {{PLURAL:$1|ein|$1|nix}} pro Sigg',
 'viewprevnext' => 'Bläddere: ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "*Sigg '''[[$1]]'''",
-'searchmenu-new' => "'''Donn de Sigg „[[:$1|$1]]“ hee em Wiki aanlääje'''",
+'searchmenu-new' => '<strong>Donn de Sigg „[[:$1|$1]]“ hee em Wiki aanlääje.</strong>
+{{PLURAL:$2|Beloor Der ävver och die Sigg, di beim Söhke jefonge wood.|Beloor Der ävver och die Sigge, di beim Söhke jefonge woode sin.|}}',
 'searchprofile-articles' => 'Sigge vum Enhalt',
 'searchprofile-project' => 'Hülp- ov Projäk-Sigge',
 'searchprofile-images' => 'Dateie met Medije',
@@ -1382,6 +1404,7 @@ Mieh doh drövver fengk mer em [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAG
 'search-result-score' => 'Jeweesch: $1%',
 'search-redirect' => '(Ömleitung $1)',
 'search-section' => '(Avschnett $1)',
+'search-file-match' => '(en dä Dattei dren)',
 'search-suggest' => 'Häß De „$1“ jemeint?',
 'search-interwiki-caption' => 'Schwesterprojekte',
 'search-interwiki-default' => '$1 hät heh di Träffer jefonge:',
@@ -1391,6 +1414,7 @@ Mieh doh drövver fengk mer em [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAG
 'searchrelated' => 'ähnlesch',
 'searchall' => 'all',
 'showingresults' => 'Onge {{PLURAL:$1|weed <strong>eine</strong>|wääde bes <strong>$1</strong>|weed <strong>keine</strong>}} vun de jefonge Endrähsch jezeisch, vun de Nommer <strong>$2</strong> av.',
+'showingresultsinrange' => '{{PLURAL:$1|<strong>Ein</strong> Saachjropp|<strong>$1</strong> Saachjroppe|Kein Saachjropp}}, vun Nommer <strong>$2</strong> bes Nommer <strong>$3</strong> {{PLURAL:$1|weed|wääde|weed}} heh opjeleß.',
 'showingresultsnum' => 'Onge {{PLURAL:$3|es ein|sin <strong>$3</strong>|sin <strong>kein</strong>}} vun de jefonge Endrähsch opjeleß, vun de Nommer <strong>$2</strong> av.',
 'showingresultsheader' => "Jefonge un aanjezeisch: {{PLURAL:$5|'''$1''' vun '''$3'''|'''$1''' beß '''$2''' vun '''$3'''|nix}} för '''$4'''",
 'search-nonefound' => 'Mer han nix zopaß jefonge för Ding Aanfrohch.',
@@ -1450,6 +1474,9 @@ dat dänne ehr Daate topaktoell sin,
 'recentchangesdays-max' => '(Nit mieh wie {{PLURAL:$1|eine Daach|$1 Dääsh|keine Daach}})',
 'recentchangescount' => 'Aanzahl Änderunge en de Leß, als Shtandad:',
 'prefs-help-recentchangescount' => 'Dat ömfaß de „{{int:recentchanges}}“, de Versione uß de Fojangeheit, un de Logbööcher.',
+'prefs-help-watchlist-token2' => 'Dat heh es dä jeheime Schlößel för dä <i lang="en" xml:lang="en">Atom</i>- udder <i lang="en" xml:lang="en">RSS</i>-Kanaal met de Änderonge aan Sigge en Dinger Oppaßleß
+Wä dä kännt, kann Ding Oppaßleß lässe, alsu halld_en för Desch.
+Do kann Der [[Special:ResetTokens|ene neue Schlößel maache lohße]], wann nüüdesch.',
 'savedprefs' => 'Ding Enstellunge sin jetz jesechert.',
 'timezonelegend' => 'Ziggzohn:',
 'localtime' => 'De Zigg op Dingem Kompjuter:',
@@ -1517,8 +1544,10 @@ dat dänne ehr Daate topaktoell sin,
 'prefs-displayrc' => 'Ußwahle för et Leßte Aanzeje',
 'prefs-displaysearchoptions' => 'Enstellunge för et Aanzeje',
 'prefs-displaywatchlist' => 'Enstellunge för et Aanzeje',
+'prefs-tokenwatchlist' => 'Schlößel',
 'prefs-diffs' => 'Ongerscheide un Verjliische',
 'prefs-help-prefershttps' => 'Di Enschtällong kütt eets zom drahre, wann De nähksde Mohl enloggs.',
+'prefs-tabs-navigation-hint' => 'Opjepaß: Met dä Piel-Knöppe kanns de noh rääds un lenks op de Rigger jonn un se ußsöhke.',
 
 # User preference: email validation using jQuery
 'email-address-validity-valid' => 'De Addräß fö de <i lang="en">e-mail</i> schingk en Odenung',
@@ -1546,7 +1575,8 @@ dat dänne ehr Daate topaktoell sin,
 'userrights-changeable-col' => '{{PLURAL:$1:Di Jropp|Jroppe|kein Jropp doh}}, di De ändere kanns',
 'userrights-unchangeable-col' => '{{PLURAL:$1:Di Jropp|Jroppe|kein Jropp doh}}, di De nit ändere kanns',
 'userrights-irreversible-marker' => '$1 *',
-'userrights-conflict' => 'Ene Andere hät di Rääschde ald verändert. Loor, wad_eruß kohm un versöhg_et norr-ens, wann nüüdesch.',
+'userrights-conflict' => 'Ene Andere hät di Rääschde ald verändert. Loor, wad_eruß kohm un versöhg_et norr_ens, wann nüüdesch.',
+'userrights-removed-self' => 'Do häs Dng Rääsch dohzoh jraad drannjejovve, dröm kanns De heh di Sigg nit mieh oproofe.',
 
 # Groups
 'group' => 'Jrupp:',
@@ -1844,6 +1874,7 @@ Jangk zeröck un lad Ding Datei unger enem andere Name huh,
 wann De se noch han wells.',
 'file-exists-duplicate' => 'Di Dattei hät dersellve Enhallt wi hee di {{PLURAL:$1|Datei|Dateie|}}:',
 'file-deleted-duplicate' => 'En Datei mem sellve Enhallt wi „[[:$1]]“ es ens fottjeschmeße woode. Donn dä Zosammehang em „{{int:dellogpage}}“ nokike, ih dat De se widder huhläds.',
+'file-deleted-duplicate-notitle' => 'En Datei mem sellve Enhallt wi di heh es ens fottjeschmeße woode, un dä iehre Tettel es verschtoche. Donn en däm Zosammehang eine froore, dä fottjeschmeße un verstoche Datteije beloore kann, ih dat De se widder huhläds.',
 'uploadwarning' => 'Warnung beim Huhlade',
 'uploadwarning-text' => 'Donn onge dä Täx övver di Dattei ändere, un versöhg_et norr_ens.',
 'savefile' => 'Datei avspeichere',
@@ -2203,6 +2234,7 @@ Tipp: Merk Der dä Tittel vun dä Sigg dovör.',
 'ninterwikis' => '{{PLURAL:$1|Eine Engerwikilengk|$1 Engerwikilengks|Keine Engerwikilengk}}',
 'nlinks' => '{{PLURAL:$1|eine Link|$1 Links}}',
 'nmembers' => 'met {{PLURAL:$1|ein Sigg|$1 Sigge}} dren',
+'nmemberschanged' => 'met&nbsp;$1&nbsp;→&nbsp;{{PLURAL:$2|eine Sigg|$2&nbsp;Sigge|keine Sigg}}',
 'nrevisions' => '{{PLURAL:$1|Ein Änderung|$1 Änderunge|Keij Änderung}}',
 'nviews' => '{{PLURAL:$1|Eine Avrof|$1 Avrofe|Keine Avrof}}',
 'nimagelinks' => 'Weed op {{PLURAL:$1|eine Sigg|$1 Sigge|keine Sigg}} jebruch',
@@ -2238,16 +2270,27 @@ Di sin dann <del>dorschjeschtresche</del>.',
 'mostrevisions' => 'Atikkele met de miehste Änderunge',
 'prefixindex' => 'All Sigge, dänne ehr Name met enem bestemmte Wood oder Tex aanfängk',
 'prefixindex-namespace' => 'All Sigge med enem beschtemmpte Aanfang (Appachtemang $1 )',
+'prefixindex-strip' => 'Donn der jemeinsamme Aanfang vun dä Tetelle en dä Leß fottlohße.',
 'shortpages' => 'Atikele zoteet vun koot noh lang',
 'longpages' => 'Atikele zoteet vun lang noh koot',
 'deadendpages' => 'Atikele ohne Links dren',
 'deadendpagestext' => 'De Atikele hee han kein Links op ander Atikele em Wiki.',
 'protectedpages' => 'Jeschötzte Sigge',
 'protectedpages-indef' => 'Nor de Sigge zeije, woh alleins de Wiki-Köbesse draan dörrve',
+'protectedpages-summary' => 'He sin Sigge opjeliss, wo jäje Veränderunge un/odde jäje et Ömnenne jeschötz sin, su dat nit einfach Jede jet draan don kann.',
 'protectedpages-cascade' => 'Nur Sigge en ener Schotz-Kaskad',
 'protectedpages-noredirect' => 'Ömleidonge verschteische',
 'protectedpagesempty' => 'Op di Aat sin jrad kein Sigge jeschötz.',
+'protectedpages-timestamp' => 'Dattum un Zigg',
+'protectedpages-page' => 'Sigg',
+'protectedpages-expiry' => 'Bes',
+'protectedpages-performer' => 'Jeschöz vum Metmaacher',
+'protectedpages-params' => 'De Zoot Schpär',
+'protectedpages-reason' => 'Der Jrond',
+'protectedpages-unknown-timestamp' => 'Onbikannt',
+'protectedpages-unknown-performer' => 'Onbikannte Metmaacher',
 'protectedtitles' => 'Verbodde Titele för Sigge',
+'protectedtitles-summary' => "Hee sin verbodde Sigge-Tittele opjelis, unger dä Name ka'mer kein neu Sigge aanläje.",
 'protectedtitlesempty' => 'Op di Aat sin jrad kein Sigge jäje et neu Aanlääje jeschötz.',
 'listusers' => 'De Metmaacherleß',
 'listusers-editsonly' => 'Donn nor Metmaacher zeije, di och ens jät jeschrevve han.',
@@ -2455,6 +2498,7 @@ Wann di Sigg udder ier Klaafsigg verändert weed, kütt dat af jäz heh en di Op
 'watchmethod-list' => 'Ben de Oppassliss am pröfe, noh de letzte Änderung',
 'watchlistcontains' => 'En dä Oppassliss {{PLURAL:$1|es ein Sigg|sinner <strong>$1</strong> Sigge|sinner <strong>kein</strong> Sigge}}.',
 'iteminvalidname' => 'Dä Endrach „$1“ hät ene kapodde Name.',
+'wlnote2' => 'Heh sin de Änderonge us de läzde {{PLURAL:$1|Schtond|<strong>$1</strong> Schtonde|kein Schtond}} bes zom $2 öm $3 Uhr.',
 'wlshowlast' => 'Zeich de letzte | $1 | Stunde | $2 | Dage | $3 | aan, dun',
 'watchlist-options' => 'Eijeschaffte fun de Oppassless',
 
@@ -2485,27 +2529,30 @@ $PAGEINTRO $NEWPAGE
 
 {{int:summary}} „$PAGESUMMARY“ $PAGEMINOREDIT
 
-Do kanns dä Metmaacher „$PAGEEDITOR“ aanspreche:
+Do kanns dä Metmaacher „$PAGEEDITOR“ aanspräsche:
 * Övver e-mail: $PAGEEDITOR_EMAIL
 * Em Wiki: $PAGEEDITOR_WIKI
 
-Do kriss vun jetz aan kein e-mail mieh, bes dat Do Der di Sigg aanjeluurt häs,
-och wann se norr_ens verändert weed. Do kanns ävver och all die Merker för 
-e-mail för die Sigge en Dinger Oppassliss op eimol ändere.
+Do kreß vun jetz aan kein e-mail mieh, bes dat Do
+Der di Sigg aanjeluurt häs wann De enjelogg bes,
+och wann se norr_ens verändert weed. Do kanns ävver
+och all die Merker för e-mail för die Sigge en Dinger
+Oppaßleß op eimol ändere.
 
-Ene schöne Jroß {{GRAMMAR:vun|{{SITENAME}}}}.
+Ene schöne Jrohß {{GRAMMAR:vun|{{SITENAME}}}}.
 
 -- 
-Öm de Enshtällonge för Nohreeschet aan Desch ze ändere, jangk op:
+Öm de Enschtällonge för Nohreeschte aan Desch ze ändere,
+jangk op:
 {{canonicalurl:{{#special:Preferences}}}}
 
-Do kanns hee Ding Oppassleß ändere:
+Do kanns heh Ding Oppaßleß ändere:
 {{canonicalurl:{{#special:EditWatchlist}}}}
 
-Öm di Sigg vun Dinger Oppassleß ze schmieße:
+Öm di Sigg vun Dinger Oppaßleß ze schmieße:
 $UNWATCHURL
 
-Do kanns hee noh Hölp luure:
+Do kanns heh noh Hölp luure:
 {{canonicalurl:{{MediaWiki:Helppage}}}}',
 'created' => 'neu aanjelaht',
 'changed' => 'jeändert',
@@ -2541,6 +2588,7 @@ Do kanns hee noh Hölp luure:
 'delete-edit-reasonlist' => 'De Jrönde för et Fottschmieße beärbeide',
 'delete-toobig' => 'Di Sigg hät {{PLURAL:$1|ein Version|$1 Versione|jaa kein Version}}. Dat sinn_er ärsch fill. Domet unsere ẞööver do nit draan en de Kneen jeit, dom_mer esu en Sigg nit fottschmieße.',
 'delete-warning-toobig' => 'Di Sigg hät {{PLURAL:$1|ein Version|$1 Versione|jakein Version}}. Dat sinn_er ärsch fill. Wann De die all fottschmieße wells, dat kann dem Wiki sing Datenbangk schwer ußbremse.',
+'deleting-backlinks-warning' => '<strong>Opjepaß:</strong> Es jitt Sigge met Lenks noh heh doh, udder Sigge, di heh di Sigg enbenge!',
 
 # Rollback
 'rollback' => 'Em Letzte sing Änderunge zeröcknemme',
@@ -2782,6 +2830,7 @@ un och, wann De se ändere wells.',
 'ipb-confirmhideuser' => 'Do bes om bäßte Wääsch ene Metaacher ze sperre met „Vershteishe“ ußjewählt.
 Domet weed dä Name vun däm Metmaacher uß alle Leßte un Logbööscher eruß jelohße.
 Wells De dat?',
+'ipb-confirmaction' => 'Wann De sescher bes, dat De dat donn wells, donn e Krüzje nävve <em>{{int:ipb-confirm}}</em> maache.',
 'ipb-edit-dropdown' => 'De Jründ för et Sperre beärrbejde',
 'ipb-unblock-addr' => '„$1“ widder zohlohße',
 'ipb-unblock' => 'En IP-Addräß ov ene Metmaacher widder zohlohße',
@@ -2823,7 +2872,7 @@ Wells De dat?',
 'change-blocklink' => 'Sperr ändere',
 'contribslink' => 'Beidräch',
 'emaillink' => 'Scheck en <span lang="en">e-mail</span>',
-'autoblocker' => 'Automattisch jesperrt. Ding IP_Adress wood vör kootem vun däm Metmaacher „[[User:$1|$1]]“ jebruch. Dä es jesperrt woode wäje: „$2“',
+'autoblocker' => 'Bes automattisch jesperrt. Ding <i lang="en" xml:lang="en">IP</i>_Adress wood vör kootem noch vun däm Metmaacher „[[User:$1|$1]]“ jebruch. Dä es jesperrt woode wäje: „$2“',
 'blocklogpage' => 'Logboch met Metmaacher-Sperre',
 'blocklog-showlog' => 'Heh dä Metmaacher es ald fröjer jeshperrt woode. Dat Logbooch vum Metmaacher-Sperre onge künnt doh jät mieh zoh saare.',
 'blocklog-showsuppresslog' => 'Heh dä Metmaacher es ald fröjer jeshperrt un vershtoche woode. Dat Logbooch vum Metmaacher-Vershteishe onge künnt doh jät mieh zoh saare.',
@@ -2842,7 +2891,7 @@ Automattesch jesperrte <i lang="en>IP</i>-Addräße sin nit heh, ävver en de [[
 'range_block_disabled' => 'Adresse Jebeede ze sperre, es nit erlaub.',
 'ipb_expiry_invalid' => 'De Duur es Dress. Jevv se richtich aan.',
 'ipb_expiry_temp' => 'Sperre för Metmaacher met verstoche Name mößße för iewish doore.',
-'ipb_hide_invalid' => 'Kann dä Metmaacher nit vershteishe. Müjjelesch, dat dä zoh vill Änderunge jemaat hät.',
+'ipb_hide_invalid' => 'Mer künne dä Metmaacher nit verschteische. Dä hät övver {{PLURAL:$1|ein Änderong|$1 Änderong|kein Änderong}} jemaat.',
 'ipb_already_blocked' => '„$1“ es ald jesperrt',
 'ipb-needreblock' => 'Dä Metmaacher „$1“ es ald jesperrt. Wellß De de Enstellunge för di Spär ändere?',
 'ipb-otherblocks-header' => 'Ander {{PLURAL:$1|Sperr|Sperre|-nix-}}',
@@ -3021,6 +3070,7 @@ Wenn De jenerell aan [https://www.mediawiki.org/wiki/Localisation MediaWiki sing
 'allmessages-prefix' => 'Name fängk aan met:',
 'allmessages-language' => 'Schprooch:',
 'allmessages-filter-submit' => 'Lohß Jonn!',
+'allmessages-filter-translate' => 'Övversäze!',
 
 # Thumbnails
 'thumbnail-more' => 'Jrößer aanzeije',
@@ -3037,6 +3087,7 @@ $2',
 'thumbnail_image-type' => 'Di Zoot Beld künne mer nit met ömjonn',
 'thumbnail_gd-library' => 'Vun dä <i lang="en">GD</i> Projramm_Biplijotheek fäählt en Funkßuhn: „$1“',
 'thumbnail_image-missing' => 'Di Datei schingk nit doh ze sin: <code>$1</code>',
+'thumbnail_image-failure-limit' => 'Mieh wi {{PLURAL:$1|eine Versohch|$1 Versohche|keine Versohch}} dat Minnibelldsche ze zeije. Versöhg_et schpääder widder.',
 
 # Special:Import
 'import' => 'Sigge Emporteere',
@@ -3072,7 +3123,7 @@ Dat ahle Versione Huhlade es avjeschalt, un es nit müjjelich.',
 'importuploaderrortemp' => 'De Import-Datei huhzelade jingk scheif, weil e Zwescheverzeichnis fäählt.',
 'import-parse-failure' => 'Fäähler bem Import per XML:',
 'import-noarticle' => 'Kein Sigge do, för ze Emporteere!',
-'import-nonewrevisions' => 'Et sin kein neue Versione do, för ze Importeere, weil all de Versione vun heh ald fröjer empotteet wodte.',
+'import-nonewrevisions' => 'Et sin kein neue Väsjohne för ze emporteere doh, weil alle Väsjonhe vun heh ald fröjer empotteet wodte.',
 'xml-error-string' => '$1 — en {{PLURAL:$2|eetz|$2-}}te Reih en de {{PLURAL:$3|eetz|$3-}}te Spalde, dat ess_et {{PLURAL:$4|eetz|$4-}}te Byte: $5',
 'import-upload' => 'En XML-Datei impochteere',
 'import-token-mismatch' => 'Schadt. Et senn nit alle Date heh aanjekumme.
@@ -3175,6 +3226,7 @@ fun dä Sigg op, zom Beärbeide un widder Afspeichere.
 Esu kam_mer noch en Aanmärkong en „{{int:summary}}“ maache.',
 'tooltip-preferences-save' => 'Enstellunge faßhallde',
 'tooltip-summary' => 'Jif en koote Zesammefassung en',
+'interlanguage-link-title' => '$1 ($2)',
 
 # Stylesheets
 'common.css' => '/* CSS heh aan dä Stell hät Uswirkunge op all Ovverflääsche */',
@@ -3237,6 +3289,7 @@ Esu kam_mer noch en Aanmärkong en „{{int:summary}}“ maache.',
 'pageinfo-length' => 'Bytes en dä Sigg',
 'pageinfo-article-id' => 'Dä Sigg ier Nommer en dä Daatebangk',
 'pageinfo-language' => 'De Schprooch vum Sigge-Enhallt',
+'pageinfo-content-model' => 'Et Modäll för der Enhalld vun dä Sigg',
 'pageinfo-robot-policy' => 'Et opnämme es för Söhkmaschiine',
 'pageinfo-robot-index' => 'zohjelohße',
 'pageinfo-robot-noindex' => 'verbodde',
@@ -4068,6 +4121,9 @@ Dä Shtanndat-Zoot-Schlößel „$1“ övverschriif dä älldere Zoot-Schlöße
 'version-ext-colheader-description' => 'Beschrevve',
 'version-ext-colheader-credits' => 'Schriiver',
 'version-license-title' => '‎Lėzänz för $1',
+'version-license-not-found' => 'Mer han kein Lezänzenfommazjuhne för heh dat Zohsazprojramm jefonge.',
+'version-credits-title' => 'Dank för dat Projramm „$1“',
+'version-credits-not-found' => 'Schahd, mer han kein Aanjaabe drövver, wämm mer heh för ze danke hätte.',
 'version-poweredby-credits' => "Dat Wiki heh löp met '''[https://www.mediawiki.org/ MediaWiki]''', copyright © 2001–$1 $2.",
 'version-poweredby-others' => 'sönß wää',
 'version-poweredby-translators' => 'de Övversäzer em translatewiki.net',
@@ -4089,11 +4145,12 @@ Do sullts en [{{SERVER}}{{SCRIPTPATH}}/COPYING Kopie vun dä <i lang="en">GNU Ge
 # Special:Redirect
 'redirect' => 'Ömleide op en Dattei, ene Metmaacher udder de Väsjohn vun ener Sigg',
 'redirect-legend' => 'Ömleide ob_en Dattei udder Sigg',
-'redirect-summary' => 'Heh di {{int:specialpage}} leidt öm ob_en Dattei — doh mößd_Er ene Nahme aanjävve — udder en Sigg — doh mößd_Er en Kännong för en Väsjoh aanjävve — udder en Metmaachersigg — doh mößd_Er enem Metmaacher sing Kännong aanjävve.',
+'redirect-summary' => 'Heh di {{int:specialpage}} leidt öm ob_en Dattei — doh mößd_Er ene Nahme aanjävve, för e Beischpell:[[{{#Special:Redirect}}/file/Example.jpg]] — udder en Sigg — doh mößd_Er en Kännong för, udder en Väsjuhn aanjävve, för e Beischpell esu: [[{{#Special:Redirect}}/page/64308]] udder [[{{#Special:Redirect}}/revision/328429]] — udder en Metmaachersigg — doh mößd_Er enem Metmaacher sing Kännong aanjävve, för e Beischpell: [[{{#Special:Redirect}}/user/101]].',
 'redirect-submit' => 'Lohß Jonn!',
 'redirect-lookup' => 'Söhk noh:',
 'redirect-value' => 'Kännong udder Nahme:',
 'redirect-user' => 'Enem Metmaacher sing Kännong',
+'redirect-page' => 'Dä Sigg ier Nummer en de Datebank',
 'redirect-revision' => 'Ener Sigg ier Väsjohn ier Kännong',
 'redirect-file' => 'Ener Dattei iehre Nahme',
 'redirect-not-exists' => 'Nit jefonge',
@@ -4112,9 +4169,8 @@ Do sullts en [{{SERVER}}{{SCRIPTPATH}}/COPYING Kopie vun dä <i lang="en">GNU Ge
 # Special:SpecialPages
 'specialpages' => '{{int:nstab-special}}e',
 'specialpages-note-top' => 'Lejänd',
-'specialpages-note' => '* {{int:nstab-special}}e för jede Metmaacher.
-* <span class="mw-specialpagerestricted">{{int:nstab-special}}e för Metmaacher met besönder Räächde.</span>
-* <span class="mw-specialpagecached">Em Zwescheshpeisher jehallde {{int:nstab-special}}e. Di künnte ovverhollt sind.</span>',
+'specialpages-note' => '* Jewöhnlejje {{int:nstab-special}}e för jede Metmaacher.
+* <span class="mw-specialpagerestricted">{{int:nstab-special}}e bloß för Metmaacher met besönder Räächde.</span>',
 'specialpages-group-maintenance' => 'Waadungsleste',
 'specialpages-group-other' => 'Ander {{int:nstab-special}}e',
 'specialpages-group-login' => 'Enlogge udder Aanmälde',
@@ -4331,9 +4387,9 @@ Wat De doh enjiß, kütt met Dingem Metmaachername un Dingem Brauser op die Sigg
 'limitreport-walltime-value' => '{{PLURAL:$1|ein&nbsp;Sekond|$1&nbsp;Sekonde|kein&nbsp;Sekond}}',
 'limitreport-ppvisitednodes-value' => '$1 vun $2',
 'limitreport-ppgeneratednodes-value' => '$1 vun $2',
-'limitreport-postexpandincludesize-value' => '$1 vun $2 {{PLURAL:$2|Byte|Bytes|Bytes}}',
+'limitreport-postexpandincludesize-value' => '{{PLURAL:$1|ein|$1|kein}} vun {{PLURAL:$2|einem Byte|$2 Bytes|keinem Byte}}',
 'limitreport-templateargumentsize' => 'Der Ömvang vun de Parrameeterre vun Schablohne',
-'limitreport-templateargumentsize-value' => '$1 vun $2 {{PLURAL:$2|Byte|Bytes|Bytes}}',
+'limitreport-templateargumentsize-value' => '{{PLURAL:$1|ein|$1|kein}} vun {{PLURAL:$2|einem Byte|$2 Bytes|keinem Byte}}',
 'limitreport-expansiondepth-value' => '$1 vun $2',
 'limitreport-expensivefunctioncount' => 'Oproofe vun „düüre“ Fonxjuhne em Paaser',
 'limitreport-expensivefunctioncount-value' => '$1 vun $2',
@@ -4357,4 +4413,6 @@ Derbei jehüüere enschtalleete Paaserfunxjuhne, alsu esu jät wi
 'expand_templates_generate_rawhtml' => 'Donn de Röh HTML Ußjaav aanzeije',
 'expand_templates_preview' => 'Vör-Aansich',
 
+# Unknown messages
+'uploadinvalidxml' => 'Dat <i lang="en" xml:lang="en">XML</i> en dä huh jelaade Dattei kunnt wohr nit en Oodenong beim Ongersöhke.',
 );
index 4d43882..d01d31a 100644 (file)
@@ -349,7 +349,6 @@ $messages = array(
 'vector-action-protect' => 'Spären',
 'vector-action-undelete' => 'Restauréieren',
 'vector-action-unprotect' => 'Spär änneren',
-'vector-simplesearch-preference' => 'Vereinfacht Sichleescht aktivéieren (nëmme beim Ausgesinn Vector)',
 'vector-view-create' => 'Uleeën',
 'vector-view-edit' => 'Änneren',
 'vector-view-history' => 'Versioune weisen',
@@ -2083,10 +2082,19 @@ An all Rei sti Linken zur éischter an zweeter Viruleedung, souwéi d\'Zil vun d
 'deadendpagestext' => 'Dës Säite si mat kenger anerer Säit op {{SITENAME}} verlinkt.',
 'protectedpages' => 'Gespaart Säiten',
 'protectedpages-indef' => 'Nëmme onbegrenzt-gespaarte Säite weisen',
+'protectedpages-summary' => 'Op dëser Spezialsäit stinn all déi Säiten déi esou protegéiert sinn, datt se net vun alle Benotzer geréckelt oder geännert kënne ginn.',
 'protectedpages-cascade' => 'Nëmme Säiten déi duerch Kaskade gespaart sinn',
 'protectedpages-noredirect' => 'Viruleedunge verstoppen',
 'protectedpagesempty' => 'Elo si keng Säite mat dëse Parameteren gespaart.',
+'protectedpages-timestamp' => 'Zäitstempel',
+'protectedpages-page' => 'Säit',
+'protectedpages-expiry' => 'Spär bis',
+'protectedpages-params' => 'Parameter vun der Spär',
+'protectedpages-reason' => 'Grond',
+'protectedpages-unknown-timestamp' => 'Onbekannt',
+'protectedpages-unknown-performer' => 'Onbekannte Benotzer',
 'protectedtitles' => 'Gespaarten Titel',
+'protectedtitles-summary' => 'Dës Titele goufe gespaart an et ka keng Säit mat esou engem Titel gemaach ginn.',
 'protectedtitlesempty' => 'Zur Zäit si mat de Parameteren déi Dir uginn hutt keng Säite fir neit Uleeë gespaart.',
 'listusers' => 'Benotzerlëscht',
 'listusers-editsonly' => 'Nëmme Benotzer mat Ännerunge weisen',
index 233205a..0924c39 100644 (file)
@@ -517,7 +517,6 @@ $messages = array(
 'vector-action-protect' => 'Заштити',
 'vector-action-undelete' => 'Врати',
 'vector-action-unprotect' => 'Измени заштита',
-'vector-simplesearch-preference' => 'Овозможи упростено поле за пребарување (само за рувото „Векторско“)',
 'vector-view-create' => 'Создај',
 'vector-view-edit' => 'Уреди',
 'vector-view-history' => 'Историја',
@@ -1524,7 +1523,7 @@ $1",
 'stub-threshold' => 'Праг за <a href="#" class="stub">никулци</a> (бајти):',
 'stub-threshold-disabled' => 'Оневозможено',
 'recentchangesdays' => 'Денови за приказ во скорешните промени:',
-'recentchangesdays-max' => '(највеќе $1 {{PLURAL:$1|ден|дена}})',
+'recentchangesdays-max' => '(највеќе {{PLURAL:$1|еден ден|$1 дена}})',
 'recentchangescount' => 'Број на уредувања кои ќе се прикажуваат по основно:',
 'prefs-help-recentchangescount' => 'Подразбира скорешни промени, истории на страници и дневници.',
 'prefs-help-watchlist-token2' => 'Ова е тајна шифра за вашиот канализиран список на набљудувања.
@@ -2313,6 +2312,14 @@ $1',
 'protectedpages-cascade' => 'Само каскадни заштити',
 'protectedpages-noredirect' => 'Скриј пренасочувања',
 'protectedpagesempty' => 'Во моментов нема заштитени страници со параметрите кои ги зададовте.',
+'protectedpages-timestamp' => 'Време и датум',
+'protectedpages-page' => 'Страница',
+'protectedpages-expiry' => 'Истекува',
+'protectedpages-performer' => 'Заштитувач',
+'protectedpages-params' => 'Параметри на заштитата',
+'protectedpages-reason' => 'Причина',
+'protectedpages-unknown-timestamp' => 'Непознато',
+'protectedpages-unknown-performer' => 'Непознат корисник',
 'protectedtitles' => 'Заштитени наслови',
 'protectedtitlesempty' => 'Во овој момент нема заштитени наслови кои ги задоволуваат наведените критериуми.',
 'listusers' => 'Список на корисници',
@@ -2411,7 +2418,7 @@ $1',
 
 # Special:ActiveUsers
 'activeusers' => 'Список на активни корисници',
-'activeusers-intro' => 'Ова е список на корисници кои биле на некој начин активни во последните $1 {{PLURAL:$1|ден|дена}}.',
+'activeusers-intro' => 'Ова е список на корисници кои биле на некој начин активни во последните {{PLURAL:$1|еден ден|$1 дена}}.',
 'activeusers-count' => '$1 {{PLURAL:$1|дејство|дејства}} {{PLURAL:$3|денес|во последните $3 дена}}',
 'activeusers-from' => 'Прикажи корисници почнувајќи од:',
 'activeusers-hidebots' => 'Скриј ботови',
@@ -2668,6 +2675,7 @@ $UNWATCHURL
 ** Зачестен спам
 ** Непродуктивна уредувачка војна
 ** Страница со зачестена посета
+** Сеприсутност на шаблонот/превметнувањето
 ** Административна постапка',
 'protect-edit-reasonlist' => 'Уреди причини за заштита',
 'protect-expiry-options' => '1 час: 1 hour,1 ден:1 day,1 недела:1 week,2 недели:2 weeks,1 месец:1 month,3 месеци:3 months,6 месеци:6 months,1 година:1 year,бесконечно:infinite',
@@ -3089,6 +3097,7 @@ $2',
 'thumbnail_image-type' => 'Неподдржан тип на слика',
 'thumbnail_gd-library' => 'Нецелосни поставки на графичката библиотека: недостасува функцијата $1',
 'thumbnail_image-missing' => 'Изгледа дека податотеката недостасува: $1',
+'thumbnail_image-failure-limit' => 'Направив премногу обиди ($1 или повеќе) за да ја прикажам минијатурава. Обидете се подоцна.',
 
 # Special:Import
 'import' => 'Увезување на страници',
@@ -3414,10 +3423,10 @@ $1',
 'minutes-abbrev' => '$1 м',
 'hours-abbrev' => '$1 ч',
 'days-abbrev' => '$1 д',
-'seconds' => '{{PLURAL:$1|$1 секунда|$1 секунди}}',
-'minutes' => '{{PLURAL:$1|$1 минута|$1 минути}}',
-'hours' => '{{PLURAL:$1|$1 час|$1 часа}}',
-'days' => '{{PLURAL:$1|$1 ден|$1 дена}}',
+'seconds' => '{{PLURAL:$1|една секунда|$1 секунди}}',
+'minutes' => '{{PLURAL:$1|една минута|$1 минути}}',
+'hours' => '{{PLURAL:$1|еден час|$1 часа}}',
+'days' => '{{PLURAL:$1|еден ден|$1 дена}}',
 'weeks' => '{{PLURAL:$1|$1 недела|$1 недели}}',
 'months' => '{{PLURAL:$1|$1 месец|$1 месеци}}',
 'years' => '{{PLURAL:$1|$1 година|$1 години}}',
@@ -3425,9 +3434,9 @@ $1',
 'just-now' => 'Штотуку',
 
 # Human-readable timestamps
-'hours-ago' => 'пред $1 {{PLURAL:$1|час|часа}}',
-'minutes-ago' => 'пред $1 {{PLURAL:$1|минута|минути}}',
-'seconds-ago' => 'пред $1 {{PLURAL:$1|секунда|секунди}}',
+'hours-ago' => 'пред {{PLURAL:$1|еден час|$1 часа}}',
+'minutes-ago' => 'пред {{PLURAL:$1|една минута|$1 минути}}',
+'seconds-ago' => 'пред {{PLURAL:$1|една секунда|$1 секунди}}',
 'monday-at' => 'понеделникот во $1',
 'tuesday-at' => 'вторникот во $1',
 'wednesday-at' => 'средата во $1',
@@ -4079,7 +4088,7 @@ $5
 
 # Friendlier slave lag warnings
 'lag-warn-normal' => 'Промените во {{PLURAL:$1|последната секунда|последните $1 секунди}} може да не бидат прикажани во списокот.',
-'lag-warn-high' => 'Поради преоптовареност на податочниот опслужувач, промените понови од $1 {{PLURAL:$1|секунда|секунди}}
+'lag-warn-high' => 'Поради преоптовареност на податочниот опслужувач, промените понови од {{PLURAL:$1|една секунда|$1 секунди}}
 може да не бидат прикажани во списокот.',
 
 # Watchlist editor
@@ -4433,10 +4442,10 @@ $5
 'api-error-verification-error' => 'Податотеката е оштетена или има погрешна наставка.',
 
 # Durations
-'duration-seconds' => '$1 {{PLURAL:$1|секунда|секунди}}',
-'duration-minutes' => '$1 {{PLURAL:$1|минута|минути}}',
-'duration-hours' => '$1 {{PLURAL:$1|час|часа}}',
-'duration-days' => '$1 {{PLURAL:$1|ден|дена}}',
+'duration-seconds' => '{{PLURAL:$1|една секунда|$1 секунди}}',
+'duration-minutes' => '{{PLURAL:$1|една минута|$1 минути}}',
+'duration-hours' => '{{PLURAL:$1|еден час|$1 часа}}',
+'duration-days' => '{{PLURAL:$1|еден ден|$1 дена}}',
 'duration-weeks' => '$1 {{PLURAL:$1|недела|недели}}',
 'duration-years' => '{{PLURAL:$1|година|години}}',
 'duration-decades' => '$1 {{PLURAL:$1|деценија|децении}}',
@@ -4449,9 +4458,9 @@ $5
 # Limit report
 'limitreport-title' => 'Профилни парсерски податоци:',
 'limitreport-cputime' => 'Употреба на обработувачко време',
-'limitreport-cputime-value' => '$1 {{PLURAL:$1|секунда|секунди}}',
+'limitreport-cputime-value' => '{{PLURAL:$1|една секунда|$1 секунди}}',
 'limitreport-walltime' => 'Употреба на вистинско време',
-'limitreport-walltime-value' => '$1 {{PLURAL:$1|секунда|секунди}}',
+'limitreport-walltime-value' => '{{PLURAL:$1|една секунда|$1 секунди}}',
 'limitreport-ppvisitednodes' => 'Бр. на пројдени јазли од предобработувачот',
 'limitreport-ppgeneratednodes' => 'Бр. на создадени јазли од предобработувачот',
 'limitreport-postexpandincludesize' => 'Големина на вклученото по проширувањето',
index f121a41..7ce622f 100644 (file)
@@ -517,7 +517,6 @@ $messages = array(
 'vector-action-protect' => 'സം‌രക്ഷിക്കുക',
 'vector-action-undelete' => 'മായ്ക്കപ്പെട്ടത് പുനഃസ്ഥാപിക്കുക',
 'vector-action-unprotect' => 'സംരക്ഷണത്തിൽ മാറ്റംവരുത്തുക',
-'vector-simplesearch-preference' => 'ലളിതമായ തിരച്ചിൽ സൗകര്യം സജ്ജമാക്കുക (വെക്റ്റർ ദൃശ്യരൂപത്തിൽ മാത്രം)',
 'vector-view-create' => 'സൃഷ്ടിക്കുക',
 'vector-view-edit' => 'തിരുത്തുക',
 'vector-view-history' => 'നാൾവഴി കാണുക',
@@ -2241,6 +2240,14 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization കാണുക.',
 'protectedpages-cascade' => 'നിർഝരിത സംരക്ഷണങ്ങൾ മാത്രം',
 'protectedpages-noredirect' => 'തിരിച്ചുവിടലുകൾ മറയ്ക്കുക',
 'protectedpagesempty' => 'ഈ ചരങ്ങൾ ഉപയോഗിച്ചു താളുകൾ ഒന്നും തന്നെ സം‌രക്ഷിക്കപ്പെട്ടിട്ടില്ല.',
+'protectedpages-timestamp' => 'സമയമുദ്ര',
+'protectedpages-page' => 'താൾ',
+'protectedpages-expiry' => 'കാലാവധി',
+'protectedpages-performer' => 'ഉപയോക്താവിനെ സംരക്ഷിക്കുന്നു',
+'protectedpages-params' => 'സംരക്ഷണ ചരങ്ങൾ',
+'protectedpages-reason' => 'കാരണം',
+'protectedpages-unknown-timestamp' => 'അജ്ഞാതം',
+'protectedpages-unknown-performer' => 'അജ്ഞാത ഉപയോക്താവ്',
 'protectedtitles' => 'സംരക്ഷിക്കപ്പെട്ടിരിക്കുന്ന തലക്കെട്ടുകൾ',
 'protectedtitlesempty' => 'ഈ ചരങ്ങൾ ഉപയോഗിച്ചു തലക്കെട്ടുകൾ ഒന്നും തന്നെ സം‌രക്ഷിക്കപ്പെട്ടിട്ടില്ല.',
 'listusers' => 'ഉപയോക്താക്കളുടെ പട്ടിക',
@@ -3001,6 +3008,7 @@ $1',
 'thumbnail_image-type' => 'ചിത്രത്തിന്റെ തരം പിന്തുണക്കപ്പെട്ടതല്ല',
 'thumbnail_gd-library' => 'അപൂർണ്ണമായ ജി.ഡി. ലൈബ്രറി ക്രമീകരണം: ഫങ്ഷൻ $1 ലഭ്യമല്ല',
 'thumbnail_image-missing' => 'പ്രമാണം ലഭ്യമല്ലെന്നു കാണുന്നു: $1',
+'thumbnail_image-failure-limit' => 'ഈ ലഘുചിത്രം സൃഷ്ടിക്കാൻ നിരവധി പരാജയപ്പെട്ട ശ്രമങ്ങൾ ($1 അല്ലെങ്കിൽ കൂടുതൽ) നടന്നിട്ടുണ്ട്. ദയവായി പിന്നീട് ശ്രമിക്കുക.',
 
 # Special:Import
 'import' => 'താളുകൾ ഇറക്കുമതി ചെയ്യുക',
index 49338d7..78288b5 100644 (file)
@@ -205,7 +205,6 @@ $messages = array(
 'vector-action-protect' => 'Хамгаалах',
 'vector-action-undelete' => 'Үл устгах',
 'vector-action-unprotect' => 'Хамгаалалтаа солих',
-'vector-simplesearch-preference' => 'Хялбарчилсан хайлтын талбарыг идэвхижүүлэх (зөвхөн Вектор скин)',
 'vector-view-create' => 'Үүсгэх',
 'vector-view-edit' => 'Засварлах',
 'vector-view-history' => 'Түүхийг үзэх',
index ffac1b3..59fcdbe 100644 (file)
@@ -492,7 +492,6 @@ $messages = array(
 'vector-action-protect' => 'सुरक्षित करा',
 'vector-action-undelete' => 'वगळलेले पुनर्स्थापित करा',
 'vector-action-unprotect' => 'सुरक्षितता बदला',
-'vector-simplesearch-preference' => 'सोपा शोधपट्टी विकल्प सक्रिय करा (फक्त व्हेक्टर त्वचेसाठी)',
 'vector-view-create' => 'तयार करा',
 'vector-view-edit' => 'संपादन',
 'vector-view-history' => 'इतिहास पहा',
@@ -725,6 +724,7 @@ $2',
 'invalidtitle-unknownnamespace' => 'अनोळखी नामविश्वाच्या आकड्यासह अवैध मथळा $1 व मजकूर "$2"',
 'exception-nologin' => 'सनोंद-प्रवेशित नाही',
 'exception-nologin-text' => 'हे पान किंवा क्रिया करण्यासाठी आपल्याला या विकिवर [[Special:Userlogin|सनोंद- प्रवेशित]] असावयास हवे.',
+'exception-nologin-text-manual' => 'हे पान किंवा क्रियेस पोचण्यास कृपया $1 करा.',
 
 # Virus scanner
 'virus-badscanner' => "खराब विन्यास (कॉन्फिगरेशन): अनोळखी व्हायरस स्कॅनर: ''$1''",
@@ -873,6 +873,8 @@ $2',
 'retypenew' => 'पुन्हा एकदा परवलीचा शब्द टंका:',
 'resetpass_submit' => 'परवलीचा शब्द टाका आणि सनोंद-प्रवेश करा',
 'changepassword-success' => 'तुमचा परवलीचा शब्द यशस्वीरित्या बदललेला आहे!',
+'changepassword-throttled' => 'तुम्ही नुकतेच सनोंद- प्रवेशासाठी अनेकानेक प्रयत्न केले आहेत.
+कृपया, पुन्हा प्रयत्न करण्याआधी $1 थोडी उसंत घ्या.',
 'resetpass_forbidden' => 'परवलीचे शब्द बदलता येत नाहीत.',
 'resetpass-no-info' => 'या पानामध्ये थेट जाण्यासाठी तुम्हास  सनोंद-प्रवेशित असावयास हवे.',
 'resetpass-submit-loggedin' => 'परवलीचा शब्द बदला',
@@ -922,6 +924,8 @@ $2',
 'changeemail-password' => 'तुमचा {{SITENAME}} संकेतांक:',
 'changeemail-submit' => 'ईमेल बदला',
 'changeemail-cancel' => 'रद्द करा',
+'changeemail-throttled' => 'तुम्ही नुकतेच सनोंद- प्रवेशासाठी अनेक प्रयत्न केले आहेत.
+कृपया, पुन्हा प्रयत्न करण्याआधी $1 थोडी उसंत घ्या.',
 
 # Special:ResetTokens
 'resettokens' => 'ओळखचिन्ह(टोकन) पुनर्स्थापित करा',
@@ -1120,7 +1124,7 @@ $2',
 'invalid-content-data' => 'अवैध माहिती',
 'content-not-allowed-here' => '"$1" हा आशय [[$2]] लेखावर टाकण्याची अनुमती नाही.',
 'editwarning-warning' => "या पानावरुन दुसर्‍या पानावर गेल्यास, तुम्ही येथे केलेले बदल जतन होणार नाहीत.
-जर आपण सनोंद-प्रवेशित असाल तर, ही सूचना घालवण्यासाठी ''माझ्या पसंती'' मधील संपादनपसंतीत बदल करा.",
+जर आपण सनोंद-प्रवेशित असाल तर, ही सूचना घालवण्यासाठी ''{{int:prefs-editing}}'' मधील संपादनपसंतीत बदल करा.",
 
 # Content models
 'content-model-wikitext' => 'विकिमजकूर',
@@ -1133,10 +1137,10 @@ $2',
 
 ते $2{{PLURAL:$2|कॉल|कॉल्स}} पेक्षा कमी असायला हवेत, सध्या $1{{PLURAL:$1| $1 कॉल| $1 कॉल्स}} एवढे आहेत.',
 'expensive-parserfunction-category' => 'खूप सारे खर्चीक पार्सर क्रिया कॉल्स असणारी पाने',
-'post-expand-template-inclusion-warning' => 'सूचना: साचे वाढविण्याची मर्यादा संपलेली आहे.
+'post-expand-template-inclusion-warning' => '<strong>ईशारा:</strong> साचे वाढविण्याची मर्यादा संपलेली आहे.
 काही साचे वगळले जातील.',
 'post-expand-template-inclusion-category' => 'अशी पाने ज्यांच्यावर साचे चढविण्याची मर्यादा संपलेली आहे',
-'post-expand-template-argument-warning' => 'सूचना: या पानावर असा एकतरी साचा आहे जो वाढविल्यास खूप मोठा होईल.
+'post-expand-template-argument-warning' => '<strong>ईशारा:</strong> या पानावर असा एकतरी साचा आहे जो वाढविल्यास खूप मोठा होईल.
 असे साचे वगळण्यात आलेले आहेत.',
 'post-expand-template-argument-category' => 'अशी पाने ज्यांच्यामध्ये साचे वगळलेले आहेत',
 'parser-template-loop-warning' => 'साचा चक्र मिळाले: [[$1]]',
@@ -1154,6 +1158,7 @@ $2',
 'undo-success' => 'संपादन परतवले जाऊ शकते.कृपया, आपण नेमके हेच करू इच्छिता तर ते खाली दिलेली तुलना पाहू निश्चित करा,आणि नंतर संपादन परतवण्याचे काम पूर्ण करण्याकरिता इच्छित बदल जतन करा.',
 'undo-failure' => 'विसंवादी आंतरवर्ती संपादने झाल्यामुळे आपण हे संपादन परतवू शकत नाही.',
 'undo-norev' => 'हे संपादन परतविता आलेले नाही कारण ते अगोदरच उलटविलेले किंवा वगळलेले आहे.',
+'undo-nochange' => 'असे दिसते कि हे संपादन पूर्ववत केल्या गेले आहे.',
 'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|चर्चा]])यांची आवृत्ती $1 परतवली.',
 'undo-summary-username-hidden' => 'अज्ञात सदस्याची $1 आवृत्ती परतवा',
 
@@ -1347,7 +1352,7 @@ $1",
 'shown-title' => '$1 {{PLURAL:$1|निकाल}} प्रतिपान पहा',
 'viewprevnext' => 'पहा ($1 {{int:pipe-separator}} $2) ($3).',
 'searchmenu-exists' => "'''या विकिवर \"[[:\$1]]\" या नावाचे पान आहे.'''",
-'searchmenu-new' => "'''या विकिवर \"[[:\$1]]\" हे पान तयार करा!'''",
+'searchmenu-new' => '<strong>या विकिवर "[[:$1]]" हे पान तयार करा!</strong> {{PLURAL:$2|0=|See also the page found with your search.|सापडलेले शोध निकालही पहा.}}',
 'searchprofile-articles' => 'आशय-पाने',
 'searchprofile-project' => 'साहाय्य व प्रकल्प पाने',
 'searchprofile-images' => 'बहुमाध्यमे',
@@ -1372,6 +1377,7 @@ $1",
 'searchrelated' => 'संबंधित',
 'searchall' => 'सर्व',
 'showingresults' => "#'''$2'''पासून {{PLURAL:$1|'''1'''पर्यंतचा निकाल|'''$1'''पर्यंतचे निकाल}} खाली दाखवले आहे.",
+'showingresultsinrange' => 'खाली #<strong>$2</strong> ते #<strong>$3</strong> पर्यंतच्या कक्षेतील {{PLURAL:$1|<strong>१</strong> निकाल दाखविला आहे|<strong>$1</strong> निकाल दाखविले आहेत}}.',
 'showingresultsnum' => "खाली दिलेले #'''$2'''पासून सुरू होणारे  {{PLURAL:$3|'''1''' निकाल|'''$3''' निकाल}}.",
 'showingresultsheader' => "'''$4''' साठी {{PLURAL:$5|'''$3'''पैकी '''$1''' निकाल|'''$3''' पैकी '''$1 - $2''' निकाल}}",
 'search-nonefound' => 'दिलेल्या पृच्छेशी जुळणारे निकाल नाहीत.',
@@ -1859,7 +1865,7 @@ $1',
 'backend-fail-read' => '$1 ही संचिका वाचता आली नाही.',
 'backend-fail-create' => '$1 ही संचिका लिहिता आली नाही.',
 'backend-fail-maxsize' => '$1 ही संचिका लिहिता आली नाही कारण ती {{PLURAL:$2|एक बाइट|$2 बाइट्स}} पेक्षा मोठी आहे.',
-'backend-fail-readonly' => 'पारà¥\8dशà¥\8dवभà¥\8cमà¥\80à¤\95 à¤¸à¤¾à¤ à¤µà¤£ "$1" â\80\9cफà¤\95à¥\8dत à¤µà¤¾à¤\9aाâ\80\9d à¤\85सà¥\87 à¤\86हà¥\87. à¤¦à¤¿à¤²à¥\87लà¥\87 à¤\95ारण "$2" à¤\86हà¥\87.',
+'backend-fail-readonly' => 'पारà¥\8dशà¥\8dवभà¥\8cमà¥\80à¤\95 à¤¸à¤¾à¤ à¤µà¤£ "$1" â\80\9cफà¤\95à¥\8dत à¤µà¤¾à¤\9aाâ\80\9d à¤\85शà¥\80 à¤\86हà¥\87. à¤¦à¤¿à¤²à¥\87लà¥\87 à¤\95ारण à¤\86हà¥\87: "<em>$2</em>"',
 'backend-fail-synced' => 'अंतर्गत पार्श्वभौमीक साठवणीतील फाईल "$1" विसंगत आहे.',
 'backend-fail-connect' => 'पार्श्वभौमीक साठा "$1"शी संबंध जोडू शकत नाही.',
 'backend-fail-internal' => 'पार्श्वभौमीक साठा "$1" यात अज्ञात चूक झाली आहे.',
@@ -2002,24 +2008,24 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization कृपया हे
 # File reversion
 'filerevert' => '$1 पूर्वपद',
 'filerevert-legend' => 'संचिका पूर्वपदास',
-'filerevert-intro' => 'तुम्ही [$3, $2 प्रमाणे आवर्तन$4 कडे] [[Media:$1|$1]]  उलटवत आहात.',
+'filerevert-intro' => 'तुम्ही [$3, $2 प्रमाणे आवर्तन$4 कडे]<strong>[[Media:$1|$1]]</strong>  उलटवत आहात.',
 'filerevert-comment' => 'कारण:',
 'filerevert-defaultcomment' => '$2, $1 च्या आवृत्तीत पूर्वपदास',
 'filerevert-submit' => 'पूर्वपद',
-'filerevert-success' => "[$3, $2 प्रमाणे आवर्तन $4]कडे '''[[Media:$1|$1]]''' उलटवण्यात आली.",
+'filerevert-success' => '[$3, $2 प्रमाणे आवर्तन $4]कडे<strong>[[Media:$1|$1]]</strong>उलटवण्यात आली.',
 'filerevert-badversion' => 'दिलेलेल्या वेळ मापनानुसार,या संचिकेकरिता कोणतीही पूर्वीची स्थानिक आवृत्ती नाही.',
 
 # File deletion
 'filedelete' => '$1 वगळा',
 'filedelete-legend' => 'संचिका वगळा',
-'filedelete-intro' => "तुम्ही '''[[Media:$1|$1]]''' वगळत आहात.",
-'filedelete-intro-old' => "[$4 $3, $2]च्या वेळेचे '''[[Media:$1|$1]]'''चे आवर्तन तुम्ही वगळत आहात.",
+'filedelete-intro' => 'तुम्ही<strong>[[Media:$1|$1]]</strong>त्याच्या सर्व इतिहासासह,वगळण्याच्या तयारीत आहात.',
+'filedelete-intro-old' => '[$4 $3, $2]च्या वेळेचे<strong>[[Media:$1|$1]]</strong>चे आवर्तन तुम्ही वगळत आहात.',
 'filedelete-comment' => 'कारण:',
 'filedelete-submit' => 'वगळा',
-'filedelete-success' => "'''$1'''वगळण्यात आले.",
-'filedelete-success-old' => '<span class="plainlinks">$3, $2 वेळी \'\'\'[[Media:$1|$1]]\'\'\' चे आवर्तन वगळण्यात आले आहे .</span>',
-'filedelete-nofile' => "'''$1''' अस्तित्वात नाही.",
-'filedelete-nofile-old' => "सांगितलेल्या गुणधर्मानुसार  '''$1'''चे कोणतेही विदा आवर्तन संचित नाही.",
+'filedelete-success' => '<strong>$1</strong>वगळण्यात आले.',
+'filedelete-success-old' => '$3चे<strong>[[Media:$1|$1]]</strong> आवर्तन, $2वगळण्यात आले आहे .',
+'filedelete-nofile' => '<strong>$1</strong>अस्तित्वात नाही.',
+'filedelete-nofile-old' => 'सांगितलेल्या गुणधर्मानुसार<strong>$1</strong>चे कोणतेही विदा आवर्तन संचित नाही.',
 'filedelete-otherreason' => 'दुसरे/अतिरिक्त कारण:',
 'filedelete-reason-otherlist' => 'इतर कारण',
 'filedelete-reason-dropdown' => '*वगळण्याची सामान्य कारणे
@@ -2157,10 +2163,20 @@ Input:contenttype/subtype, e.g. <code>image/jpeg</code>.',
 'deadendpagestext' => 'या पानांवर या विकिवरील इतर कुठल्याही पानाला जोडणारा दुवा नाही.',
 'protectedpages' => 'सुरक्षित पाने',
 'protectedpages-indef' => 'फक्त अनंत काळासाठी सुरक्षित केलेले',
+'protectedpages-summary' => 'या पानात,अस्तित्वात असणाऱ्या संरक्षित अशा पानाची यादी आहे.नवनिर्माणापासून संरक्षित शीर्षकांच्या यादीसाठी [[{{#special:ProtectedTitles}}]] बघा.',
 'protectedpages-cascade' => 'केवळ एकामेकांवर अवलंबून कास्केडींग सुरक्षा (सुरक्षा शिडी)',
 'protectedpages-noredirect' => 'पुनर्निर्देशने लपवा',
 'protectedpagesempty' => 'सध्या या नियमावलीने कोणतीही पाने सुरक्षित केलेली नाहीत.',
+'protectedpages-timestamp' => 'वेळशिक्का',
+'protectedpages-page' => 'पान',
+'protectedpages-expiry' => 'संपण्याचा कालावधी',
+'protectedpages-performer' => 'सदस्याचे रक्षण करीत आहे',
+'protectedpages-params' => 'रक्षणाची प्राचले',
+'protectedpages-reason' => 'कारण',
+'protectedpages-unknown-timestamp' => 'अज्ञात',
+'protectedpages-unknown-performer' => 'अनामिक सदस्य',
 'protectedtitles' => 'सुरक्षीत शीर्षके',
+'protectedtitles-summary' => 'या पानात अशा शीर्षकांची यादी आहे, जी नविन तयार करता येउ  शकणार नाहीत.अस्तित्वात असणाऱ्या संरक्षित पानांच्या यादीसाठी [[{{#special:ProtectedPages}}]] बघा.',
 'protectedtitlesempty' => 'या नियमावलीने सध्या कोणतीही शीर्षके सुरक्षित केलेली नाहीत.',
 'listusers' => 'सदस्यांची यादी',
 'listusers-editsonly' => 'फक्त संपादनांसहित सदस्य दाखवा',
@@ -2406,7 +2422,7 @@ $UNWATCHURL
 'exblank' => 'पान रिकामे होते',
 'delete-confirm' => '"$1" वगळा',
 'delete-legend' => 'वगळा',
-'historywarning' => 'सूचना: तुम्ही वगळत असलेल्या पानाला $1 {{PLURAL:$1|आवर्तनाचा|आवर्तनांचा}} इतिहास आहे:',
+'historywarning' => '<strong>ईशारा:</strong> तुम्ही वगळत असलेल्या पानाला $1 {{PLURAL:$1|आवर्तनाचा|आवर्तनांचा}} इतिहास आहे:',
 'confirmdeletetext' => 'तुम्ही एक लेखपान त्याच्या सर्व इतिहासासोबत वगळण्याच्या तयारीत आहात.
 कृपया, तुम्ही करीत असलेली कृती ही मीडियाविकीच्या [[{{MediaWiki:Policy-url}}|नीतीनुसार]] आहे ह्याची खात्री करा. तसेच, तुम्ही करीत असलेल्या कृतीचे परिणाम, कृती करण्यापूर्वी जाणून घ्या.',
 'actioncomplete' => 'काम पूर्ण',
@@ -2471,11 +2487,11 @@ $UNWATCHURL
 'protect_expiry_invalid' => 'संपण्याचा कालावधी चुकीचा आहे.',
 'protect_expiry_old' => 'संपण्याचा कालावधी उलटून गेलेला आहे.',
 'protect-unchain-permissions' => 'पुढील संरक्षित विकल्प उघडा.',
-'protect-text' => "'''$1''' या पानाची सुरक्षापातळी तुम्ही इथे पाहू शकता अथवा बदलू शकता.",
-'protect-locked-blocked' => "तुम्ही प्रतिबंधित असताना सुरक्षा पातळी बदलू शकत नाही.येथे '''$1''' पानाकरिता सध्याची मांडणावळ आहे:",
-'protect-locked-dblock' => "विदागारास ताळे लागलेले असताना सुरक्षा पातळी बदलता येत नाही.येथे '''$1''' पानाकरिता सध्याची मांडणावळ आहे:",
-'protect-locked-access' => "तुम्हाला या पानाची सुरक्षा पातळी बदलण्याचे अधिकार नाहीत.
-'''$1''' या पानाची सुरक्षा पातळी पुढीलप्रमाणे:",
+'protect-text' => '<strong>$1</strong> या पानाची सुरक्षापातळी तुम्ही इथे पाहू शकता अथवा बदलू शकता.',
+'protect-locked-blocked' => 'तुम्ही प्रतिबंधित असताना सुरक्षा पातळी बदलू शकत नाही.येथे <strong>$1</strong> पानाकरिता सध्याची मांडणावळ आहे:',
+'protect-locked-dblock' => 'विदागारास ताळे लागलेले असताना सुरक्षा पातळी बदलता येत नाही.येथे <strong>$1</strong> पानाकरिता सध्याची मांडणावळ आहे:',
+'protect-locked-access' => 'तुम्हाला या पानाची सुरक्षा पातळी बदलण्याचे अधिकार नाहीत.
+<strong>$1</strong> या पानाची सुरक्षा पातळी पुढीलप्रमाणे:',
 'protect-cascadeon' => 'हे पान सध्या सुरक्षित आहे कारण ते {{PLURAL:$1|या पानाच्या|या पानांच्या}} सुरक्षा शिडीवर आहे. तुम्ही या पानाची सुरक्षा पातळी बदलू शकता, पण त्याने सुरक्षाशिडी मध्ये बदल होणार नाहीत.',
 'protect-default' => 'सर्व सदस्यांना परवानगी द्या',
 'protect-fallback' => 'फक्त "$1" परवानगी असणाऱ्यांनाच परवानगी द्या',
@@ -2519,7 +2535,7 @@ $UNWATCHURL
 # Undelete
 'undelete' => 'वगळलेली पाने पहा',
 'undeletepage' => 'वगळलेली पाने पहा आणि पुनर्स्थापित करा',
-'undeletepagetitle' => "'''खाली [[:$1]] च्या वगळलेल्या आवृत्त्या समाविष्ट केलेल्या आहेत'''.",
+'undeletepagetitle' => '<strong>खाली [[:$1]] च्या वगळलेल्या आवृत्त्या समाविष्ट केलेल्या आहेत</strong>.',
 'viewdeletedpage' => 'काढून टाकलेले लेख पहा',
 'undeletepagetext' => 'खालील {{PLURAL:$1|पान वगळले आहे तरीसुद्धा विदागारात जतन आहे आणि पुनर्स्थापित करणे शक्य आहे|$1 पाने वगळली आहेत तरी सुद्धा विदागारात जतन आहेत आणि पुनर्स्थापित करणे शक्य आहेत}}. विदागारातील साठवण ठरावीक कालावधीने स्वच्छ करता येते.',
 'undelete-fieldset-title' => 'आवर्तने पुनर्स्थापित करा',
@@ -2543,9 +2559,9 @@ $UNWATCHURL
 'undeletedrevisions-files' => '{{PLURAL:$1|1 आवर्तन|$1 आवर्तने}}आणि {{PLURAL:$2|1 संचिका|$2 संचिका}} पुनर्स्थापित',
 'undeletedfiles' => '{{PLURAL:$1|1 संचिका|$1 संचिका}} पुनर्स्थापित',
 'cannotundelete' => 'उलटवणे फसले:$1',
-'undeletedpage' => "'''$1ला पुनर्स्थापित केले'''
+'undeletedpage' => '<strong>$1ला पुनर्स्थापित केले</strong>
 
-अलिकडिल वगळलेल्या आणि पुनर्स्थापितांच्या नोंदीकरिता [[Special:Log/delete|वगळल्याच्या नोंदी]] पहा .",
+अलिकडिल वगळलेल्या आणि पुनर्स्थापितांच्या नोंदीकरिता [[Special:Log/delete|वगळल्याच्या नोंदी]] पहा .',
 'undelete-header' => 'अलीकडील वगळलेल्या पानांकरिता [[Special:Log/delete|वगळलेल्या नोंदी]] पहा.',
 'undelete-search-title' => 'वगळलेली पाने शोधा',
 'undelete-search-box' => 'वगळलेली पाने शोधा',
@@ -2606,7 +2622,7 @@ $1',
 'whatlinkshere-page' => 'पान:',
 'linkshere' => "खालील लेख '''[[:$1]]''' या पानाशी जोडले आहेत:",
 'nolinkshere' => "'''[[:$1]]''' येथे कोणत्याही पानांचे दुवे नाहीत.",
-'nolinkshere-ns' => "निवडलेल्या नामविश्वातील कोणतीही पाने '''[[:$1]]'''ला दुवा देत नाहीत .",
+'nolinkshere-ns' => 'निवडलेल्या नामविश्वातील कोणतीही पाने <strong>[[:$1]]</strong>ला दुवा देत नाहीत .',
 'isredirect' => 'पुनर्निर्देशित पान',
 'istemplate' => 'मिळवा',
 'isimage' => 'संचिका दुवा',
@@ -2784,7 +2800,7 @@ $1',
 
 जर नवीन शीर्षकाचा लेख अस्तित्वात असेल तर स्थानांतरण होणार '''नाही'''.
 पण जर नवीन शीर्षकाचा लेख हा रिकामा असेल अथवा पुनर्निर्देशन असेल (म्हणजेच त्या लेखाला जर संपादन इतिहास नसेल) तर स्थानांतरण होईल. याचा अर्थ असा की जर काही चूक झाली तर तुम्ही पुन्हा जुन्या शीर्षकाकडे स्थानांतरण करू शकता.
-'''सूचना!'''
+<strong>ईशारा!</strong>
 असे केल्याने एखाद्या महत्वाच्या/लोकप्रीय लेखामध्ये अनपेक्षित आणि महत्वाचे बदल होऊ शकतात. तुम्हाला विनंती आहे की तुम्ही पूर्ण काळजी घ्या व होणारे परिणाम समजावून घ्या.
 जर तुम्हाला शंका असेल तर प्रचालक/प्रबंधकांशी संपर्क करा.",
 'movepagetalktext' => "संबंधित चर्चा पृष्ठ याबरोबर स्थानांतरीत होणार नाही '''जर:'''
@@ -2804,7 +2820,7 @@ $1',
 'move-watch' => 'स्रोत पान व लक्ष  पानांवर निगराणी ठेवा',
 'movepagebtn' => 'स्थानांतरण करा',
 'pagemovedsub' => 'स्थानांतरण यशस्वी',
-'movepage-moved' => '\'\'\'"$1" ला "$2" मथळ्याखाली स्थानांतरीत केले\'\'\'',
+'movepage-moved' => '<strong>"$1" ला "$2" मथळ्याखाली स्थानांतरीत केले</strong>',
 'movepage-moved-redirect' => 'एक पुनर्निर्देशन तयार केले आहे.',
 'movepage-moved-noredirect' => 'पुनर्निर्देशन तयार करणे दडपण्यात आले आहे.',
 'articleexists' => 'त्या नावाचे पृष्ठ अगोदरच अस्तित्वात आहे, किंवा तुम्ही निवडलेले नाव योग्य नाही.
@@ -2844,9 +2860,9 @@ $1',
 'imageinvalidfilename' => 'लक्ष्यसंचिका अवैध आहे',
 'fix-double-redirects' => 'मुळ शीर्षक दर्शविणारे फेरे अद्ययावत करा',
 'move-leave-redirect' => 'मागे एक पुनर्निर्देशन ठेवा',
-'protectedpagemovewarning' => "'''सूचना:''' हे पान सुरक्षित आहे. फक्त प्रशासकीय अधिकार असलेले सदस्य याच्यात बदल करू शकतात.",
-'semiprotectedpagemovewarning' => "'''सूचना:''' हे पान सुरक्षित आहे. फक्त नोंदणीकृत सदस्य याच्यात बदल करू शकतात.
-सरà¥\8dवाà¤\82त à¤¤à¤¾à¤\9cà¥\80 à¤¯à¤¾à¤¦à¥\80 à¤\96ालà¥\80 à¤¸à¤\82दरà¥\8dभासाठà¥\80 à¤¦à¤¿à¤²à¥\80 à¤\86हà¥\87:",
+'protectedpagemovewarning' => '<strong>ईशारा:</strong> हे पान सुरक्षित आहे. फक्त प्रशासकीय अधिकार असलेले सदस्य याच्यात बदल करू शकतात.',
+'semiprotectedpagemovewarning' => '<strong>नोंद:</strong> हे पान सुरक्षित आहे. फक्त नोंदणीकृत सदस्य याचे स्थानांतरण करू शकतात.
+सरà¥\8dवाà¤\82त à¤¤à¤¾à¤\9cà¥\80 à¤¨à¥\8bà¤\82द à¤\96ालà¥\80 à¤¸à¤\82दरà¥\8dभासाठà¥\80 à¤¦à¤¿à¤²à¥\80 à¤\86हà¥\87:',
 'move-over-sharedrepo' => '== संचिका अस्तित्वात आहे ==
 सामायिक भांडारात [[:$1]] नाव आधी पासून अस्तित्वात आहे. संचिका या नावावर स्थानांतरीत केल्यास सामायिक संचिकेवर चढेल.',
 'file-exists-sharedrepo' => 'धीरिकेसाठी तुम्ही निवडलेले नाव हे सामूहिक संग्राहलयात आधीपासून वापरात असल्याने कृपया दुसरे नाव निवडा.',
@@ -2860,8 +2876,8 @@ $1',
 तुम्ही नंतरच्या बाबतीत एखादा दुवा सुद्धा वापरू शकता, उदाहरणार्थ "[[{{MediaWiki:Mainpage}}]]" पाना करिता [[{{#Special:Export}}/{{MediaWiki:Mainpage}}]] .',
 'exportall' => 'सर्व पान एक्सपोर्ट करा',
 'exportcuronly' => 'संपूर्ण इतिहास नको,केवळ आताचे आवर्तन आंर्तभूत करा',
-'exportnohistory' => "----
-'''सूचना:''' या फॉर्मचा वापर करून पानाचा पूर्ण इतिहास निर्यात करण्याची सुविधा कार्यकुशलतेच्या कारणंनी अनुपल्ब्ढ ठेवली आहे.",
+'exportnohistory' => '----
+<strong>नोंद:</strong> या फॉर्मचा वापर करून पानाचा पूर्ण इतिहास निर्यात करण्याची सुविधा कार्यकुशलतेच्या कारणांनी अनुपलब्ध ठेवली आहे.',
 'exportlistauthors' => 'प्रत्येक पानासाठी योगदात्यांच्या  पूर्ण सूचीचा(यादीचा) समावेश करावा',
 'export-submit' => 'निर्यात करा',
 'export-addcattext' => 'वर्गीकरणातून पाने भरा:',
@@ -2878,7 +2894,7 @@ $1',
 'allmessagesdefault' => 'अविचल संदेश मजकूर',
 'allmessagescurrent' => 'सध्याचा मजकूर',
 'allmessagestext' => 'मीडियाविकी नामविश्वातील सर्व प्रणाली संदेशांची यादी',
-'allmessagesnotsupportedDB' => "हे पान संपादित करता येत नाही कारण'''\$wgUseDatabaseMessages''' मालवला आहे.",
+'allmessagesnotsupportedDB' => 'हे पान संपादित करता येत नाही कारण<strong>$wgUseDatabaseMessages</strong>अक्षम  आहे.',
 'allmessages-filter-legend' => 'गाळक',
 'allmessages-filter' => 'कस्टमायझेशन स्टेटनुसार गाळणी लावा :',
 'allmessages-filter-unmodified' => 'असंपादित',
@@ -2903,6 +2919,7 @@ $1',
 'thumbnail_image-type' => 'चित्रप्रकार समर्थित नाही',
 'thumbnail_gd-library' => '$1 जी.डी. ग्रंथालयाची बांधणी अपूर्ण आहे.',
 'thumbnail_image-missing' => 'संचिका सापडत नाही: $1',
+'thumbnail_image-failure-limit' => 'हे नखुले देण्यासाठी नुकतेच अनेक अयशस्वी प्रयत्न($1 किंवा अधिक) केल्या गेले आहेत.कृपया नंतर पुन्हा प्रयत्न करा.',
 
 # Special:Import
 'import' => 'पाने आयात करा',
@@ -3154,8 +3171,8 @@ $1',
 'nextdiff' => 'पुढील संपादन →',
 
 # Media information
-'mediawarning' => "'''सावधान''': या संचिकेत डंखी संकेत असू शकतो, जो वापरल्याने तुमच्या संचालन प्रणालीस नाजूक परिस्थितीस सामोरे जावे लागू शकते.",
-'imagemaxsize' => 'सà¤\82à¤\9aिà¤\95ा à¤µà¤°à¥\8dणन à¤ªà¤¾à¤¨à¤¾à¤\82वरà¥\80ल à¤\9aितà¥\8dराà¤\82ना à¤®à¤°à¥\8dयादा à¤\98ाला:',
+'mediawarning' => '<strong>सावधान</strong>: या संचिकेत डंखी संकेत असू शकतो, जो वापरल्याने तुमच्या संचालन प्रणालीस नाजूक परिस्थितीस सामोरे जावे लागू शकते.',
+'imagemaxsize' => 'सà¤\82à¤\9aिà¤\95ा à¤\86à¤\95ार à¤®à¤°à¥\8dयादा:<br /><em>(सà¤\82à¤\9aिà¤\95ा à¤µà¤°à¥\8dणन à¤ªà¤¾à¤¨à¤¾à¤\82साठà¥\80)</em>',
 'thumbsize' => 'इवलासा आकार:',
 'widthheightpage' => '$1 × $2, $3 {{PLURAL:$3|पान|पाने}}',
 'file-info' => 'संचिकेचा आकार:$1,विविधामापमाईमप्रकार: $2',
@@ -3179,7 +3196,7 @@ $1',
 
 # Special:NewFiles
 'newimages' => 'नवीन संचिकांची यादी',
-'imagelisttext' => "खाली '''$1''' संचिका {{PLURAL:$1|दिली आहे.|$2 क्रमाने दिल्या आहेत.}}",
+'imagelisttext' => 'खाली <strong>$1</strong> संचिका {{PLURAL:$1|दिली आहे.|$2 क्रमाने दिल्या आहेत.}}',
 'newimages-summary' => 'हे विशेष पान शेवटी चढविलेल्या संचिका दर्शविते.',
 'newimages-legend' => 'गाळक',
 'newimages-label' => 'संचिकानाम (किंवा त्याचा भाग):',
@@ -3699,10 +3716,10 @@ $5
 'scarytranscludetoolong' => '[आंतरजालपत्ता खूप लांब आहे]',
 
 # Delete conflict
-'deletedwhileediting' => '”’सूचना:”’ तुम्ही संपादन सुरू केल्यानंतर हे पान वगळले गेले आहे.',
-'confirmrecreate' => "तुम्ही संपादन सुरू केल्यानंतर सदस्य [[User:$1|$1]] ([[User talk:$1|चर्चा]])ने हे पान पुढील कारणाने वगळले:
-: ''$2''
-कृपया हे पान खरेच पुन्हा निर्मित करून हवे आहे का हे निश्चित करा.",
+'deletedwhileediting' => '<strong>सूचना:</strong> तुम्ही संपादन सुरू केल्यानंतर हे पान वगळले गेले आहे.',
+'confirmrecreate' => 'तुम्ही संपादन सुरू केल्यानंतर सदस्य [[User:$1|$1]] ([[User talk:$1|चर्चा]])ने हे पान पुढील कारणाने वगळले:
+: <em>$2</em>
+कृपया हे पान खरेच पुन्हा निर्मित करून हवे आहे का हे निश्चित करा.',
 'confirmrecreate-noreason' => 'तुम्ही संपादन सुरू केल्यानंतर सदस्य [[User:$1|$1]] ([[User talk:$1|चर्चा]])ने हे पान  वगळले. तुम्हाला हे पान खरेच पुन्हा निर्मित करून हवे आहे का हे निश्चित करा.',
 'recreate' => 'पुनर्निर्माण',
 
index 893be59..52c50ac 100644 (file)
@@ -481,7 +481,6 @@ $messages = array(
 'vector-action-protect' => 'Beskytt',
 'vector-action-undelete' => 'Gjenopprett',
 'vector-action-unprotect' => 'Endre beskyttelse',
-'vector-simplesearch-preference' => 'Aktiver forenklet søkefelt (kun for drakten Vector)',
 'vector-view-create' => 'Opprett',
 'vector-view-edit' => 'Rediger',
 'vector-view-history' => 'Vis historikk',
@@ -1188,6 +1187,7 @@ Disse parameterne har blitt utelatt.',
 'undo-success' => 'Redigeringen kan omgjøres. Sjekk sammenligningen under for å bekrefte at du vil gjøre dette, og lagre endringene for å fullføre omgjøringen.',
 'undo-failure' => 'Redigeringen kunne ikke omgjøres på grunn av konflikterende etterfølgende redigeringer.',
 'undo-norev' => 'Redigeringen kunne ikke fjernes fordi den ikke eksisterer eller ble slettet',
+'undo-nochange' => 'Det ser ut til at redigeringen allerede er tilbakestilt.',
 'undo-summary' => 'Fjerner revisjon $1 av [[Special:Contributions/$2|$2]] ([[User talk:$2|diskusjon]])',
 'undo-summary-username-hidden' => 'Fjern revisjon $1 av en skjult bruker',
 
@@ -1366,6 +1366,8 @@ Forsikre deg om at denne endringen vil opprettholde historisk sidekontinuitet.',
 'showhideselectedversions' => 'Vis/skjul valgte versjoner',
 'editundo' => 'fjern',
 'diff-empty' => '(Ingen forskjell)',
+'diff-multi-sameuser' => '({{PLURAL:$1|En midlertidig revisjon|$1 midlertidige revisjoner}} av samme bruker vises ikke)',
+'diff-multi-otherusers' => '({{PLURAL:$1|En midlertidig revisjon|$1 midlertidige revisjoner}} av {{PLURAL:$2|en annen bruker|$2 brukere}} er ikke vist)',
 'diff-multi-manyusers' => '({{PLURAL:$1|Én mellomrevisjon|$1 mellomrevisjoner}} av mer enn $2 {{PLURAL:$2|bruker|brukere}} vises ikke)',
 'difference-missing-revision' => '{{PLURAL:$2|En revisjon|$2 revisjoner}} av denne forskjellen ($1) {{PLURAL:$2|ble|ble}} ikke funnet.
 
@@ -1386,7 +1388,8 @@ Detaljer kan finnes i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'shown-title' => 'Vis $1 {{PLURAL:$1|resultat|resultater}} per side',
 'viewprevnext' => 'Vis ($1 {{int:pipe-separator}} $2) ($3)',
 'searchmenu-exists' => "* Siden '''[[$1]]'''",
-'searchmenu-new' => "'''Opprett siden ''[[:$1]]'' på denne wikien.'''",
+'searchmenu-new' => "'''Opprett siden ''[[:\$1]]'' på denne wikien.'''
+<strong>Opprett siden \"[[:\$1]]\" på denne wikien!</strong> {{PLURAL:\$2|0=|Se også siden oppnådd gjennom søket ditt.|Se også de oppnådde søkeresultatene.}}",
 'searchprofile-articles' => 'Innholdssider',
 'searchprofile-project' => 'Hjelp- og prosjektsider',
 'searchprofile-images' => 'Multimedia',
@@ -1412,6 +1415,7 @@ Detaljer kan finnes i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'searchrelated' => 'relatert',
 'searchall' => 'alle',
 'showingresults' => "Nedenfor vises opptil {{PLURAL:$1|'''ett''' resultat|'''$1''' resultater}} fra og med nummer <b>$2</b>.",
+'showingresultsinrange' => 'Nedenfor vises opptil {{PLURAL:$1|<strong>1</strong> resultat|<strong>$1</strong> resulter}} i området #<strong>$2</strong> til #<strong>$3</strong>.',
 'showingresultsnum' => "Nedenfor vises {{PLURAL:$3|'''ett''' resultat|'''$3''' resultater}} fra og med nummer '''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Resultat '''$1''' av '''$3'''|Resultat '''$1 - $2''' av '''$3'''}} for '''$4'''",
 'search-nonefound' => 'Ingen resultater passet til søket.',
@@ -2229,6 +2233,14 @@ Hver rad inneholder lenker til første og andre omdirigering, samt målet for de
 'protectedpages-cascade' => 'Kun dypbeskyttelse',
 'protectedpages-noredirect' => 'Skjul omdirigeringer',
 'protectedpagesempty' => 'Ingen sider er for øyeblikket låst med disse paramterne.',
+'protectedpages-timestamp' => 'Tidsstempel',
+'protectedpages-page' => 'Side',
+'protectedpages-expiry' => 'Utløper',
+'protectedpages-performer' => 'Beskytter bruker',
+'protectedpages-params' => 'Beskyttelsesparametre',
+'protectedpages-reason' => 'Årsak',
+'protectedpages-unknown-timestamp' => 'Ukjent',
+'protectedpages-unknown-performer' => 'Ukjent bruker',
 'protectedtitles' => 'Beskyttede titler',
 'protectedtitlesempty' => 'Ingen titler beskyttes med disse parameterne for øyeblikket.',
 'listusers' => 'Brukerliste',
@@ -2772,7 +2784,7 @@ Se [[Special:BlockList|blokkeringslisten]] for alle blokkeringer.',
 'change-blocklink' => 'endre blokkering',
 'contribslink' => 'bidrag',
 'emaillink' => 'send e-post',
-'autoblocker' => 'Du ble automatisk blokkert fordi du deler IP-adresse med «[[User:$1|$1]]». Grunnen som ble gitt til at «$1» ble blokkert var: «$2».',
+'autoblocker' => 'Du ble automatisk blokkert fordi din IP-adresse nylig ble brukt av «[[User:$1|$1]]». Grunnen som ble gitt til at «$1» ble blokkert var: «$2».',
 'blocklogpage' => 'Blokkeringslogg',
 'blocklog-showlog' => 'Denne brukeren har blitt blokkert før.
 Blokkeringsloggen vises nedenfor.',
@@ -2979,6 +2991,7 @@ $2',
 'thumbnail_image-type' => 'Bildetypen støttes ikke',
 'thumbnail_gd-library' => 'Ufullstendig konfigurering av GD library: mangler funksjonen $1',
 'thumbnail_image-missing' => 'Filen ser ut til å mangle: $1',
+'thumbnail_image-failure-limit' => 'Det har vært for mange nylige forsøk ($1 eller flere) på å gjengi dette miniatyrbildet. Vennligst prøv igjen senere.',
 
 # Special:Import
 'import' => 'Importer sider',
@@ -3012,7 +3025,7 @@ Lagre den på din egen datamaskin og last den opp her.',
 'importuploaderrortemp' => 'Importfilopplasting mislyktes. En midlertidig mappe mangler.',
 'import-parse-failure' => 'Tolkningsfeil ved XML-import',
 'import-noarticle' => 'Ingen side å importere!',
-'import-nonewrevisions' => 'Alle revisjoner var importert fra før.',
+'import-nonewrevisions' => 'Ingen revisjoner ble importert: De var enten allerede på plass, eller hoppet over pga. feil.',
 'xml-error-string' => '$1 på linje $2, kolonne $3 (byte: $4): $5',
 'import-upload' => 'Last opp XML-data',
 'import-token-mismatch' => 'Sesjonsdata mistet. Venligst prøv igjen.',
@@ -3023,6 +3036,7 @@ Lagre den på din egen datamaskin og last den opp her.',
 'import-error-special' => 'Siden «$1» ble ikke importert fordi den tilhører et spesialnavnerom som ikke tillater sider.',
 'import-error-invalid' => 'Siden «$1» ble ikke importert fordi navnet er ugyldig.',
 'import-error-unserialize' => 'Revisjon $2 av siden «$1» kunne ikke serialiseres. Det ble rapportert at revisjonen bruker innholdsmodellen $3 serialisert som $4.',
+'import-error-bad-location' => 'Revisjon $2 som bruker innholdsmodell $3 kan ikke lagres til "$1" på denne wikien siden denne modellen ikke støttes på den siden.',
 'import-options-wrong' => 'Feil {{PLURAL:$2|opsjon|opsjoner}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'Den angitte grunnsiden har en ugyldig tittel.',
 'import-rootpage-nosubpage' => 'Navnerommet "$1" til grunnsiden tillater ikke undersider.',
@@ -3113,6 +3127,7 @@ Du kan se på kildeteksten',
 'tooltip-undo' => '«Angre» tilbakestiller denne endringen og åpner redigeringsskjemaet i forhåndsvisningsmodus. Det tillater en å legge til en begrunnelse i redigeringsforklaringen.',
 'tooltip-preferences-save' => 'Lagre innstillinger',
 'tooltip-summary' => 'Skriv et kort sammendrag',
+'interlanguage-link-title' => '$1 &ndash; $2',
 
 # Stylesheets
 'common.css' => '/* CSS plassert i denne fila vil gjelde for alle utseender. */',
index 7bd2cea..b02d2b9 100644 (file)
@@ -55,6 +55,7 @@
  * @author Troefkaart
  * @author Tvdm
  * @author User555
+ * @author Vogone
  * @author WTM
  * @author Wiki13
  * @author Wikiklaas
@@ -542,7 +543,6 @@ $messages = array(
 'vector-action-protect' => 'Beveiligen',
 'vector-action-undelete' => 'Terugplaatsen',
 'vector-action-unprotect' => 'Beveiliging wijzigen',
-'vector-simplesearch-preference' => 'Vereenvoudigd zoeken inschakelen (alleen voor het uiterlijk Vector)',
 'vector-view-create' => 'Aanmaken',
 'vector-view-edit' => 'Bewerken',
 'vector-view-history' => 'Geschiedenis weergeven',
@@ -1276,6 +1276,7 @@ Hieronder staat de tekst waarin de wijziging ongedaan is gemaakt.
 Controleer voor het opslaan of het resultaat gewenst is.',
 'undo-failure' => 'De wijziging kan niet ongedaan gemaakt worden vanwege andere strijdige wijzigingen.',
 'undo-norev' => 'De bewerking kon niet ongedaan gemaakt worden, omdat die niet bestaat of is verwijderd.',
+'undo-nochange' => 'De bewerking lijkt al ongedaan te zijn gemaakt.',
 'undo-summary' => 'Versie $1 van [[Special:Contributions/$2|$2]] ([[User talk:$2|overleg]]) ongedaan gemaakt',
 'undo-summary-username-hidden' => 'Versie $1 door een verborgen gebruiker ongedaan gemaakt',
 
@@ -1457,7 +1458,7 @@ Let op dat het gebruiken van de navigatiekoppelingen deze kolom opnieuw instelt.
 'showhideselectedversions' => 'Geselecteerde versies weergeven/verbergen',
 'editundo' => 'ongedaan maken',
 'diff-empty' => '(geen verschil)',
-'diff-multi-sameuser' => '({{PLURAL:$1|Een tussenliggende revisie|$1 tussenliggende revisies}} door dezelfde gebruiken niet weergegeven)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Een tussenliggende revisie|$1 tussenliggende revisies}} door dezelfde gebruiker niet weergegeven)',
 'diff-multi-otherusers' => '({{PLURAL:$1|Een tussenliggende revisie|$1 tussenliggende revisies}} door {{PLURAL:$2|een andere gebruiker|$2 gebruikers}} niet weergegeven)',
 'diff-multi-manyusers' => '($1 tussenliggende {{PLURAL:$1|versie|versies}} door meer dan $2 {{PLURAL:$2|gebruiker|gebruikers}}  worden niet weergegeven)',
 'difference-missing-revision' => '{{PLURAL:$2|Eén versie|$2 versies}} van deze verschillen ($1) {{PLURAL:$2|is|zijn}} niet aangetroffen.
@@ -2354,6 +2355,12 @@ De pagina's zijn ook niet als sjabloon opgenomen.",
 'protectedpages-cascade' => 'Alleen beveiligingen met de cascade-optie',
 'protectedpages-noredirect' => 'Doorverwijzingen verbergen',
 'protectedpagesempty' => "Er zijn momenteel geen pagina's beveiligd die aan deze voorwaarden voldoen.",
+'protectedpages-page' => 'Pagina',
+'protectedpages-expiry' => 'Verloopt',
+'protectedpages-params' => 'Beveiligingsopties',
+'protectedpages-reason' => 'Reden',
+'protectedpages-unknown-timestamp' => 'Onbekend',
+'protectedpages-unknown-performer' => 'Onbekende gebruiker',
 'protectedtitles' => 'Beveiligde paginanamen',
 'protectedtitlesempty' => 'Er zijn geen paginanamen beveiligd die aan deze voorwaarden voldoen.',
 'listusers' => 'Gebruikerslijst',
@@ -2916,7 +2923,8 @@ Zie de [[Special:BlockList|blokkadelijst]] voor recente blokkades.',
 'change-blocklink' => 'blokkade wijzigen',
 'contribslink' => 'bijdragen',
 'emaillink' => 'e-mail verzenden',
-'autoblocker' => "Automatisch geblokkeerd omdat het IP-adres overeenkomt met dat van [[User:\$1|\$1]], die geblokkeerd is om de volgende reden: \"'''\$2'''\"",
+'autoblocker' => 'Automatisch geblokkeerd omdat uw IP-adres onlangs gebruikt is door "[[User:$1|$1]]".
+De reden voor blokkade van $1 is: \'\'$2\'\'',
 'blocklogpage' => 'Blokkeerlogboek',
 'blocklog-showlog' => 'Deze gebruiker is voorheen geblokkeerd geweest.
 Het blokkeerlogboek wordt hieronder ter referentie weergegeven:',
index baf86f0..2ec50a0 100644 (file)
@@ -479,7 +479,6 @@ $messages = array(
 'vector-action-protect' => 'Zabezpiecz',
 'vector-action-undelete' => 'Odtwórz',
 'vector-action-unprotect' => 'Zmień zabezpieczenie',
-'vector-simplesearch-preference' => 'Włącz uproszczony pasek wyszukiwania (tylko dla skórki Wektor)',
 'vector-view-create' => 'Utwórz',
 'vector-view-edit' => 'Edytuj',
 'vector-view-history' => 'Wyświetl historię',
@@ -1375,6 +1374,8 @@ Użycie linków nawigacyjnych kasuje wybór w kolumnie.',
 'showhideselectedversions' => 'Pokaż lub ukryj zaznaczone wersje',
 'editundo' => 'anuluj edycję',
 'diff-empty' => '(Brak różnic)',
+'diff-multi-sameuser' => '(Nie pokazano $1 {{PLURAL:$1|pośredniej wersji utworzonej|pośrednich wersji utworzonych}} przez tego samego użytkownika)',
+'diff-multi-otherusers' => '(Nie pokazano $1 wersji {{PLURAL:$1|utworzonej|utworzonych}} przez {{PLURAL:$2|jednego użytkownika|$2 użytkowników}})',
 'diff-multi-manyusers' => '(Nie pokazano $1 {{PLURAL:$1|pośredniej wersji utworzonej|pośrednich wersji utworzonych}} przez {{PLURAL:$2|jednego użytkownika|$2 użytkowników}})',
 'difference-missing-revision' => '{{PLURAL:$2|Wersja|$2 wersje|$2 wersji}} #$1 strony "{{PAGENAME}}" nie {{PLURAL:$2|została znaleziona|zostały znalezione|zostało znalezionych}}.
 
@@ -1419,7 +1420,7 @@ Zazwyczaj jest to spowodowane przestarzałym linkiem do usuniętej strony. Powó
 'searchrelated' => 'pokrewne',
 'searchall' => 'wszystkie',
 'showingresults' => "Poniżej znajduje się lista {{PLURAL:$1|z '''1''' wynikiem|'''$1''' wyników}}, rozpoczynając od wyniku numer '''$2'''.",
-'showingresultsinrange' => 'Poniżej wyświetlono {{PLURAL:$1|<strong>1</strong> wynik|<strong>$1</strong> wyniki|<strong>$1</strong> wyników}} w zakresie # od <strong>$2</strong> # do <strong>$3</strong>.',
+'showingresultsinrange' => 'Poniżej wyświetlono co najwyżej {{PLURAL:$1|<strong>1</strong> wynik|<strong>$1</strong> wyniki|<strong>$1</strong> wyników}} w zakresie od <strong>$2</strong> do <strong>$3</strong>.',
 'showingresultsnum' => "Poniżej znajduje się lista {{PLURAL:$3|z '''1''' wynikiem|'''$3''' wyników}}, rozpoczynając od wyniku numer '''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Wynik '''$1''' z '''$3'''|Wyniki '''$1 – $2''' z '''$3'''}} dla '''$4'''",
 'search-nonefound' => 'Brak wyników spełniających kryteria podane w zapytaniu.',
@@ -1641,7 +1642,7 @@ Jeśli zdecydujesz się je podać, zostaną użyte, by udokumentować Twoje auto
 'right-ipblock-exempt' => 'Obejście blokad, automatycznych blokad i blokad zakresów adresów IP',
 'right-proxyunbannable' => 'Obejście automatycznych blokad proxy',
 'right-unblockself' => 'Odblokowanie samego siebie',
-'right-protect' => 'Zmiana stopnia zabezpieczenia i dostęp do edycji stron zabezpieczonych kaskadowo',
+'right-protect' => 'Zmiana poziomu zabezpieczenia i edycja stron zabezpieczonych kaskadowo',
 'right-editprotected' => 'Edycja stron zabezpieczonych na poziomie „{{int:protect-level-sysop}}”',
 'right-editsemiprotected' => 'Edycja stron zabezpieczonych na poziomie „{{int:protect-level-autoconfirmed}}”',
 'right-editinterface' => 'Edycja interfejsu użytkownika',
@@ -1655,7 +1656,7 @@ Jeśli zdecydujesz się je podać, zostaną użyte, by udokumentować Twoje auto
 'right-viewmyprivateinfo' => 'Podgląd swoich prywatnych danych (np. adres e-mail, prawdziwe imię i nazwisko)',
 'right-editmyprivateinfo' => 'Edycja swoich prywatnych danych (np. adres e-mail, prawdziwe imię i nazwisko)',
 'right-editmyoptions' => 'Edycja swoich preferencji',
-'right-rollback' => 'Szybkie wycofanie zmian wprowadzonych przez użytkownika, który jako ostatni edytował jakąś stronę',
+'right-rollback' => 'Szybkie wycofanie zmian wprowadzonych przez użytkownika, który jako ostatni edytował stronę',
 'right-markbotedits' => 'Oznaczanie rewertu jako edycji bota',
 'right-noratelimit' => 'Brak ograniczeń przepustowości',
 'right-import' => 'Importowanie stron z innych wiki',
@@ -2249,6 +2250,14 @@ Każdy wiersz zawiera linki do pierwszego i drugiego przekierowania oraz link, d
 'protectedpages-cascade' => 'Tylko strony zabezpieczone rekursywnie',
 'protectedpages-noredirect' => 'Ukryj przekierowania',
 'protectedpagesempty' => 'Żadna strona nie jest obecnie zabezpieczona z podanymi parametrami.',
+'protectedpages-timestamp' => 'Sygnatura czasowa',
+'protectedpages-page' => 'Strona',
+'protectedpages-expiry' => 'Wygasa',
+'protectedpages-performer' => 'Użytkownik zabezpieczający',
+'protectedpages-params' => 'Parametry zabezpieczenia',
+'protectedpages-reason' => 'Powód',
+'protectedpages-unknown-timestamp' => 'Nieznane',
+'protectedpages-unknown-performer' => 'Użytkownik nieznany',
 'protectedtitles' => 'Zabezpieczone nazwy stron',
 'protectedtitlesempty' => 'Dla tych ustawień dopuszczalne jest utworzenie stron o dowolnej nazwie.',
 'listusers' => 'Lista użytkowników',
@@ -2760,6 +2769,7 @@ Podaj powód (np. umieszczając nazwy stron, na których dopuszczono się wandal
 Przejdź do [[Special:BlockList|listy blokad]], by przejrzeć blokady.',
 'ipb-blockingself' => 'Usiłujesz zablokować siebie samego! Czy na pewno chcesz to zrobić?',
 'ipb-confirmhideuser' => 'Zamierzasz zablokować użytkownika z włączoną opcją „ukryj użytkownika”. Spowoduje to pominięcie nazwy użytkownika we wszystkich listach i rejestrach. Czy na pewno chcesz to zrobić?',
+'ipb-confirmaction' => 'Jeśli naprawdę chcesz to zrobić, zaznacz pole „{{int:ipb-confirm}}” poniżej.',
 'ipb-edit-dropdown' => 'Edytuj listę przyczyn blokady',
 'ipb-unblock-addr' => 'Odblokuj $1',
 'ipb-unblock' => 'Odblokuj użytkownika lub adres IP',
@@ -3010,6 +3020,7 @@ $2',
 'thumbnail_image-type' => 'Grafika tego typu nie jest obsługiwana',
 'thumbnail_gd-library' => 'Niekompletna konfiguracja biblioteki GD – brak funkcji $1',
 'thumbnail_image-missing' => 'Chyba brakuje pliku $1',
+'thumbnail_image-failure-limit' => 'Ostatnio było zbyt wielu nieudanych prób ($1 lub więcej) utworzenia miniaturki. Spróbuj ponownie później.',
 
 # Special:Import
 'import' => 'Import stron',
index 221301e..42b2131 100644 (file)
@@ -206,7 +206,6 @@ $messages = array(
 'vector-action-protect' => 'Protege',
 'vector-action-undelete' => 'Arcuperé',
 'vector-action-unprotect' => 'Cangé la protession',
-'vector-simplesearch-preference' => "Abilité la bara d'arserca semplificà (mach për la pel Vector)",
 'vector-view-create' => 'Creé',
 'vector-view-edit' => 'Modifiché',
 'vector-view-history' => 'Smon-e la stòria',
@@ -1136,7 +1135,7 @@ Sòn a l'é normalment causà da l'andèje dapress a na veja liura stòrica a na
 'searchrelated' => 'corelà',
 'searchall' => 'tuti',
 'showingresults' => "Ambelessì-sota a treuva fin a {{PLURAL:$1|'''1'''|'''$1'''}} arzultà, a parte dal nùmer #'''$2'''.",
-'showingresultsinrange' => 'Smon-e sì-sota fin-a a {PLURAL:$1|<strong>1</strong>|<strong>$1</strong>}} arzultà ant la serie da #<strong>$2</strong> a #<strong>$3</strong>.',
+'showingresultsinrange' => 'Smon-e sì-sota fin-a a {{PLURAL:$1|<strong>1</strong>|<strong>$1</strong>}} arzultà ant la serie da #<strong>$2</strong> a #<strong>$3</strong>.',
 'showingresultsnum' => "Ambelessì-sota a treuva {{PLURAL:$3|'''1'''|'''$3'''}} arzultà a parte da #'''$2'''.",
 'showingresultsheader' => "{{PLURAL:$5|Arzultà '''$1''' ëd '''$3'''|Arzultà '''$1 - $2''' ëd '''$3'''}} për '''$4'''",
 'search-nonefound' => "A-i é gnun arzultà për l'arserca.",
@@ -1966,6 +1965,14 @@ Adess a l'é na ridiression a [[$2]].",
 'protectedpages-cascade' => 'Mach protession a cascà',
 'protectedpages-noredirect' => 'Stërmé le ridiression',
 'protectedpagesempty' => 'Për adess a-i é pa gnun-a pàgina protegiùa',
+'protectedpages-timestamp' => 'Stampin data e ora',
+'protectedpages-page' => 'Pàgina',
+'protectedpages-expiry' => 'A scad ai',
+'protectedpages-performer' => "Protession ëd l'utent",
+'protectedpages-params' => 'Paràmeter ëd protession',
+'protectedpages-reason' => 'Rason',
+'protectedpages-unknown-timestamp' => 'Sconossùa',
+'protectedpages-unknown-performer' => 'Utent ësconossù',
 'protectedtitles' => 'Tìtoj protegiù',
 'protectedtitlesempty' => "A-i é pa gnun tìtol protegiù ch'a-i intra coi criteri ch'a l'ha butà.",
 'listusers' => "Lista dj'utent",
@@ -2732,6 +2739,7 @@ $2",
 'thumbnail_image-type' => 'Sòrt ëd figura nen gestì',
 'thumbnail_gd-library' => 'Configurassion incompleta dla biblioteca GD: Fonsion $1 mancanta',
 'thumbnail_image-missing' => "L'archivi a smija ch'a manca: $1",
+'thumbnail_image-failure-limit' => "A-i son ëstaje ëd recent tròpi tentativ falì ($1 o pi) ëd rende costa plancia. Për piasì, ch'a preuva torna pi tard.",
 
 # Special:Import
 'import' => 'Amportassion ëd pàgine',
index 7c6bf87..1b69c79 100644 (file)
@@ -38,6 +38,7 @@
  * @author Malafaya
  * @author Manuel Menezes de Sequeira
  * @author Masked Rogue
+ * @author Matma Rex
  * @author McDutchie
  * @author MetalBrasil
  * @author Minh Nguyen
@@ -47,6 +48,7 @@
  * @author Opraco
  * @author Paulo Juntas
  * @author Pedroca cerebral
+ * @author Polyethylen
  * @author Rafael Vargas
  * @author Rei-artur
  * @author Remember the dot
@@ -485,7 +487,6 @@ $messages = array(
 'vector-action-protect' => 'Proteger',
 'vector-action-undelete' => 'Restaurar',
 'vector-action-unprotect' => 'Alterar proteção',
-'vector-simplesearch-preference' => 'Ativar barra de pesquisa simplificada (apenas no tema Vector)',
 'vector-view-create' => 'Criar',
 'vector-view-edit' => 'Editar',
 'vector-view-history' => 'Ver histórico',
@@ -1214,7 +1215,7 @@ Depois grave as alterações, para finalizar e desfazer a edição.',
 'cantcreateaccount-text' => "A criação de contas a partir deste endereço IP ('''$1''') foi bloqueada por [[User:$3|$3]].
 
 O motivo apresentado por $3 foi ''$2''",
-'cantcreateaccount-range-text' => "A criação de conta a partir dos Endereços IP no intervalo '''$1''', que inclui o seu Endereço IP ('''$4'''), foi bloqueado por [[User:$3|$3]].
+'cantcreateaccount-range-text' => "A criação de conta a partir dos endereços IP no intervalo '''$1''', que inclui o seu endereço IP ('''$4'''), foi bloqueada por [[User:$3|$3]].
 
 A razão dada por $3 é ''$2''",
 
@@ -1390,6 +1391,8 @@ Note que, se usar os links de navegação, os botões de opção voltarão aos v
 'showhideselectedversions' => 'Mostrar/ocultar versões selecionadas',
 'editundo' => 'desfazer',
 'diff-empty' => '(Sem diferenças)',
+'diff-multi-sameuser' => '(Há {{PLURAL:$1|uma edição intermédia|$1 edições intermédias}} do mesmo utilizador que não estão a ser apresentadas)',
+'diff-multi-otherusers' => '(Há {{PLURAL:$1|uma revisão intermédia|$1 revisões intermédias}} de {{PLURAL:$2|outro utilizador|$2 utilizadores}} que não {{PLURAL:$1|está a ser apresentada|estão a ser apresentadas}})',
 'diff-multi-manyusers' => '({{PLURAL:$1|Uma edição intermédia|$1 edições intermédias}} de mais de {{PLURAL:$2|um utilizador|$2 utilizadores}} não {{PLURAL:$1|apresentada|apresentadas}})',
 'difference-missing-revision' => '{{PLURAL:$2|Uma revisão|$2 revisões}} desta diferença ($1) não {{PLURAL:$2|foi encontrada|foram encontradas}}.
 
@@ -2541,7 +2544,7 @@ A eliminação de páginas como esta foi restringida na {{SITENAME}}, para evita
 'delete-warning-toobig' => 'Esta página tem um histórico de edições longo, com mais de $1 {{PLURAL:$1|edição|edições}}.
 Eliminá-la poderá causar problemas na base de dados da {{SITENAME}};
 prossiga com precaução.',
-'deleting-backlinks-warning' => "'''Aviso:''' Outras páginas têm ligação à página que está prestes a eliminar.",
+'deleting-backlinks-warning' => "'''Aviso:''' Outras páginas possuem ligação à ou são transcluídas da página que está prestes a eliminar.",
 
 # Rollback
 'rollback' => 'Reverter edições',
@@ -4143,7 +4146,7 @@ Caso contrário, pode facilmente usar o formulário abaixo. O seu comentário se
 'feedback-error1' => 'Erro: O resultado da API não foi reconhecido',
 'feedback-error2' => 'Erro: A edição falhou',
 'feedback-error3' => 'Erro: A API não responde',
-'feedback-thanks' => 'Obrigado! O seu comentário foi adicionado à página "[ $2  $1 ]".',
+'feedback-thanks' => 'Obrigado! O seu comentário foi adicionado à página "[$2 $1]".',
 'feedback-close' => 'Feito',
 'feedback-bugcheck' => 'Perfeito! Verifique apenas que não é já um dos [$1 defeitos conhecidos].',
 'feedback-bugnew' => 'Eu verifiquei. Comunicar um novo defeito.',
index 5c6929e..592a920 100644 (file)
@@ -37,6 +37,7 @@
  * @author Helder.wiki
  * @author Jaideraf
  * @author Jesielt
+ * @author Jgpacker
  * @author Jorge Morais
  * @author Kaganer
  * @author Leonardo.stabile
@@ -47,6 +48,7 @@
  * @author Malafaya
  * @author ManoDbo
  * @author Matheus Sousa L.T
+ * @author Matma Rex
  * @author McDutchie
  * @author MetalBrasil
  * @author MisterSanderson
@@ -492,7 +494,6 @@ $messages = array(
 'vector-action-protect' => 'Proteger',
 'vector-action-undelete' => 'Restaurar',
 'vector-action-unprotect' => 'Alterar a proteção',
-'vector-simplesearch-preference' => 'Ativar barra simplificada de buscas (apenas no skin Vector)',
 'vector-view-create' => 'Criar',
 'vector-view-edit' => 'Editar',
 'vector-view-history' => 'Ver histórico',
@@ -888,6 +889,8 @@ Se você optar por fornecê-lo, este nome será utilizado para dar ao usuário a
 'retypenew' => 'Reintroduza a nova senha',
 'resetpass_submit' => 'Definir senha e entrar',
 'changepassword-success' => 'Sua senha foi alterada com sucesso!',
+'changepassword-throttled' => 'Você realizou demasiadas tentativas de se registrar.
+Por favor, aguarde $1 antes de tentar novamente.',
 'resetpass_forbidden' => 'As senhas não podem ser alteradas',
 'resetpass-no-info' => 'Você precisa estar autenticado para acessar esta página diretamente.',
 'resetpass-submit-loggedin' => 'Alterar senha',
@@ -943,6 +946,8 @@ Senha temporária: $2',
 'changeemail-password' => 'Sua senha para o wiki {{SITENAME}}:',
 'changeemail-submit' => 'Alterar e-mail',
 'changeemail-cancel' => 'Cancelar',
+'changeemail-throttled' => 'Você realizou demasiadas tentativas de se registrar.
+Por favor, aguarde $1 antes de tentar novamente.',
 
 # Special:ResetTokens
 'resettokens' => 'Reiniciar os tokens',
@@ -1201,6 +1206,7 @@ Estes argumentos foram omitidos.',
 'undo-success' => 'A edição pôde ser desfeita. Por gentileza, verifique o comparativo a seguir para se certificar de que é isto que deseja fazer, salvando as alterações após ter terminado de revisá-las.',
 'undo-failure' => 'A edição não pôde ser desfeita devido a alterações intermediárias conflitantes.',
 'undo-norev' => 'A edição não pôde ser desfeita porque não existe ou foi apagada.',
+'undo-nochange' => 'Parece que a edição já foi desfeita.',
 'undo-summary' => 'Desfeita a edição $1 de [[Special:Contributions/$2|$2]] ([[User talk:$2|Discussão]])',
 'undo-summary-username-hidden' => 'Desfazer a revisão $1 de um usuário oculto',
 
@@ -1209,6 +1215,9 @@ Estes argumentos foram omitidos.',
 'cantcreateaccount-text' => "Este IP ('''$1''') foi bloqueado de criar novas contas por [[User:$3|$3]].
 
 A justificativa apresentada por $3 foi ''$2''",
+'cantcreateaccount-range-text' => "A criação de conta a partir dos endereços IP no intervalo '''$1''', que inclui o seu endereço IP ('''$4'''), foi bloqueada por [[User:$3|$3]].
+
+A razão dada por $3 é ''$2''",
 
 # History pages
 'viewpagelogs' => 'Ver registros para esta página',
@@ -1377,6 +1386,8 @@ Certifique-se de que tal alteração manterá a continuidade das ações.',
 'showhideselectedversions' => 'Exibir/ocultar edições selecionadas',
 'editundo' => 'desfazer',
 'diff-empty' => '(Sem diferença)',
+'diff-multi-sameuser' => '({{PLURAL:$1|Uma revisão intermediária|$1 revisões intermediárias}} pelo mesmo usuário não estão sendo mostradas)',
+'diff-multi-otherusers' => '({{PLURAL:$1|Uma revisão intermediária por {{PLURAL:$2|um outro usuário|$2 usuários}} não está sendo mostrada|$1 revisões intermediárias por {{PLURAL:$2|um outro usuário|$2 usuários}} não estão sendo mostradas}})',
 'diff-multi-manyusers' => '({{PLURAL:$1|Uma edição intermediária|$1 edições intermediárias}} de mais de {{PLURAL:$2|um usuário|$2 usuário}} não {{PLURAL:$1|apresentada|apresentadas}})',
 'difference-missing-revision' => '{{PLURAL:$2|Uma revisão|$2 revisões}} desta diferença ($1) não {{PLURAL:$2|foi encontrada|foram encontradas}}.
 
@@ -1413,6 +1424,7 @@ Os detalhes podem ser encontrados no [{{fullurl:{{#Special:Log}}/delete|page={{F
 'search-result-score' => 'Relevância: $1%',
 'search-redirect' => '(redirecionamento de $1)',
 'search-section' => '(seção $1)',
+'search-file-match' => '(coincide com o conteúdo do arquivo)',
 'search-suggest' => 'Você quis dizer: $1',
 'search-interwiki-caption' => 'Projetos irmãos',
 'search-interwiki-default' => 'Resultados de $1:',
@@ -2255,6 +2267,12 @@ Entradas <del>riscadas</del> foram resolvidas.',
 'protectedpages-cascade' => 'Apenas proteções progressivas',
 'protectedpages-noredirect' => 'Ocultar redirecionamentos',
 'protectedpagesempty' => 'Neste momento, nenhuma das páginas está protegida com estes parâmetros.',
+'protectedpages-timestamp' => 'Data e hora',
+'protectedpages-page' => 'Página',
+'protectedpages-expiry' => 'Expira',
+'protectedpages-reason' => 'Motivo',
+'protectedpages-unknown-timestamp' => 'Desconhecido',
+'protectedpages-unknown-performer' => 'Usuário desconhecido',
 'protectedtitles' => 'Títulos protegidos',
 'protectedtitlesempty' => 'Neste momento, nenhum dos títulos está protegido com estes parâmetros.',
 'listusers' => 'Lista de usuários',
@@ -2994,6 +3012,7 @@ Acesse [https://www.mediawiki.org/wiki/Localisation MediaWiki Localisation] e [/
 'allmessages-prefix' => 'Filtrar por prefixo:',
 'allmessages-language' => 'Língua:',
 'allmessages-filter-submit' => 'Ir',
+'allmessages-filter-translate' => 'Traduzir',
 
 # Thumbnails
 'thumbnail-more' => 'Ampliar',
@@ -3934,7 +3953,7 @@ Você também pode [[Special:EditWatchlist|editar a lista da maneira convenciona
 'version-antispam' => 'Prevenção contra spam',
 'version-skins' => 'Temas',
 'version-other' => 'Diversos',
-'version-mediahandlers' => 'Executores de média',
+'version-mediahandlers' => 'Executores de mídia',
 'version-hooks' => 'Hooks',
 'version-parser-extensiontags' => 'Etiquetas de extensões de tipo "parser"',
 'version-parser-function-hooks' => 'Funções "hooks" de "parser"',
@@ -4128,7 +4147,7 @@ Caso contrário, você poderá usar o formulário simplificado a seguir. Seu com
 'feedback-error1' => 'Erro: O resultado da API não foi reconhecido',
 'feedback-error2' => 'Erro: A edição falhou',
 'feedback-error3' => 'Erro: A API não responde',
-'feedback-thanks' => 'Obrigado! O seu comentário foi adicionado à página "[ $2  $1 ]".',
+'feedback-thanks' => 'Obrigado! O seu comentário foi adicionado à página "[$2 $1]".',
 'feedback-close' => 'Feito',
 'feedback-bugcheck' => 'Perfeito! Apenas verifique se não é um dos [$1 bugs já conhecidos].',
 'feedback-bugnew' => 'Eu verifiquei. Relatar um bug novo',
index b004b12..f0ddc54 100644 (file)
@@ -508,7 +508,6 @@ This page is only linked in CologneBlue (an old skin), not in Monobook or Vector
 {{Identical|Undelete}}',
 'vector-action-unprotect' => 'Tab at top of page, in vector skin.
 {{Identical|Change protection}}',
-'vector-simplesearch-preference' => 'Preference for enhanced search suggestion in the Vector skin.',
 'vector-view-create' => 'Tab label in the Vector skin. See for example {{canonicalurl:Foo|useskin=vector}}
 {{Identical|Create}}',
 'vector-view-edit' => 'Tab label in the Vector skin. See for example {{canonicalurl:Main_Page|useskin=vector}}
@@ -4670,7 +4669,7 @@ Parameters:
 'shared-repo-name-wikimediacommons' => '{{optional}}
 {{Identical|Wikimedia Commons}}',
 'filepage.css' => '{{Optional}}',
-'upload-disallowed-here' => 'This message appears on an image page in place of the normal reupload link if they cannot upload - e.g. if the image page is upload protected and they do not have the right priviledge.',
+'upload-disallowed-here' => 'This message appears on an image page in place of the normal reupload link if they cannot upload - e.g. if the image page is upload protected and they do not have the right privilege.',
 
 # File reversion
 'filerevert' => 'Used as page title. Parameters:
@@ -5009,11 +5008,34 @@ See the following search results:
 'deadendpagestext' => 'Introductory text for [[Special:DeadendPages]]',
 'protectedpages' => '{{doc-special|ProtectedPages}}',
 'protectedpages-indef' => 'Option in [[Special:ProtectedPages]]',
+'protectedpages-summary' => 'Summary of [[Special:ProtectedPages]].
+
+See also:
+* {{msg-mw|Protectedtitles-summary}}',
 'protectedpages-cascade' => 'Option in [[Special:ProtectedPages]]',
 'protectedpages-noredirect' => 'Option in [[Special:ProtectedPages]].
 {{Identical|Hide redirect}}',
 'protectedpagesempty' => 'Used in [[Special:ProtectedPages]], when there are no protected pages with the specified parameters.',
+'protectedpages-timestamp' => 'This is a column header for dates and times in the table on the page [[Special:ProtectedPages]].
+{{Identical|Timestamp}}',
+'protectedpages-page' => 'This is a column header in the table on the page [[Special:ProtectedPages]].
+{{Identical|Page}}',
+'protectedpages-expiry' => 'This is a column header in the table on the page [[Special:ProtectedPages]].
+
+This refers to expiry timestamp.
+{{Identical|Expire}}',
+'protectedpages-performer' => 'This is a column header in the table on the page [[Special:ProtectedPages]].',
+'protectedpages-params' => 'This is a column header in the table on the page [[Special:ProtectedPages]].',
+'protectedpages-reason' => 'This is a column header in the table on the page [[Special:ProtectedPages]].
+{{Identical|Reason}}',
+'protectedpages-unknown-timestamp' => 'This is shown, when the date and time is unknown for a protection on the page [[Special:ProtectedPages]].
+{{Identical|Unknown}}',
+'protectedpages-unknown-performer' => 'This is shown, when the protecting user is unknown for a protection on the page [[Special:ProtectedPages]].',
 'protectedtitles' => '{{doc-special|ProtectedTitles}}',
+'protectedtitles-summary' => 'Summary of [[Special:ProtectedTitles]].
+
+See also:
+* {{msg-mw|Protectedpages-summary}}',
 'protectedtitlesempty' => 'Used on [[Special:ProtectedTitles]]. This text appears if the list of protected titles is empty. See the [[mw:Project:Protected_titles|help page on MediaWiki]] for more information.',
 'listusers' => '{{doc-special|ListUsers}}',
 'listusers-editsonly' => 'Option in [[Special:ListUsers]].',
@@ -7269,8 +7291,10 @@ See also:
 *$1 is a function name of the GD library',
 'thumbnail_image-missing' => 'This is the parameter 1 of the message {{msg-mw|thumbnail error}}.
 *$1 is the path incl. filename of the missing image',
-'thumbnail_image-failure-limit' => 'This is the parameter 1 of the message {{msg-mw|thumbnail error}}.
-*$1 is the maximum allowed number of failed attempts',
+'thumbnail_image-failure-limit' => 'Used as <code>$1</code> in {{msg-mw|Thumbnail error}}.
+
+Parameters:
+* $1 - the maximum allowed number of failed attempts',
 
 # Special:Import
 'import' => 'The title of the special page [[Special:Import]];',
@@ -10030,7 +10054,9 @@ There are no such extensions here, so look at [[wikipedia:Special:Version]] for
 'version-parser-extensiontags' => 'Part of [[Special:Version]].
 This message is followed by the list of parser extension tags like <code><nowiki><charinsert></nowiki></code>, <code><nowiki><coordinates></nowiki></code>, etc.',
 'version-parser-function-hooks' => 'Shown in [[Special:Version]]',
-'version-hook-name' => 'Shown in [[Special:Version]]',
+'version-hook-name' => 'Shown in [[Special:Version]].
+
+For meaning of hook see [[mw:Special:MyLanguage/Manual:Hooks|mw:Manual:Hooks]] and [[w:Hooking]].',
 'version-hook-subscribedby' => 'Shown in [[Special:Version]]',
 'version-version' => '{{Optional}}
 Used in [[Special:Version]]. Preceded by the MediaWiki extension name.
index fb19e55..6c04416 100644 (file)
@@ -427,7 +427,6 @@ $messages = array(
 'vector-action-protect' => 'Amachay',
 'vector-action-undelete' => 'Qullusqata paqarichiy',
 'vector-action-unprotect' => 'Amachayta wakinchay',
-'vector-simplesearch-preference' => 'Maskanapaq sikllallachasqa sinruta atichiy (Vector qarallapi)',
 'vector-view-create' => 'Kamariy',
 'vector-view-edit' => "Llamk'apuy",
 'vector-view-history' => 'Wiñay kawsayta qhaway',
@@ -2626,7 +2625,8 @@ Willariy imaraykum hark'anki (ahinataq: sapaq wandaluchasqa p'anqakunamanta will
 'change-blocklink' => "hark'ayta hukniraqchay",
 'contribslink' => "llamk'apusqakuna",
 'emaillink' => 'e-chaskita kachay',
-'autoblocker' => 'Kikinmanta hark\'asqam kanki, "[[User:$1|$1]]" sutiyuq ruraq IP huchhaykita ñaqha llamk\'arquptinmi. Hark\'aqqa "[[User:$1|$1]]"-ta hark\'aspa kaytam nirqan, kayrayku: "$2".',
+'autoblocker' => 'Kikinmanta hark\'asqam kanki, "[[User:$1|$1]]" sutiyuq ruraq IP huchhaykita ñaqha llamk\'arquptinmi.
+Hark\'aqqa $1-ta hark\'aspa kaytam nirqan, kayrayku: "\'\'$2"\'\'.',
 'blocklogpage' => "Ruraq hark'asqakuna",
 'blocklog-showlog' => "Kay ruraqqa ñawpaqta hark'asqam. Hark'ay hallch'ataqa kaypim rikunki willasunaykipaq:",
 'blocklog-showsuppresslog' => "Kay ruraqqa ñawpaqta hark'asqam pakasqapas. Ñit'ipay hallch'ataqa kaypim rikunki willasunaykipaq:",
index 74377cd..0dd7b4e 100644 (file)
@@ -461,7 +461,6 @@ $messages = array(
 'vector-action-protect' => 'Protejare',
 'vector-action-undelete' => 'Recuperare',
 'vector-action-unprotect' => 'Modificare protecție',
-'vector-simplesearch-preference' => 'Activează bara de căutare simplificată (exclusiv pentru interfața Vector)',
 'vector-view-create' => 'Creare',
 'vector-view-edit' => 'Modificare',
 'vector-view-history' => 'Istoric',
@@ -2222,6 +2221,14 @@ Intrările <del>tăiate</del> au fost rezolvate.',
 'protectedpages-cascade' => 'Doar protejări în cascadă',
 'protectedpages-noredirect' => 'Ascunde redirecționările',
 'protectedpagesempty' => 'Nu există pagini protejate',
+'protectedpages-timestamp' => 'Data și ora',
+'protectedpages-page' => 'Pagină',
+'protectedpages-expiry' => 'Expiră la',
+'protectedpages-performer' => 'Utilizator care a protejat',
+'protectedpages-params' => 'Parametri de protejare',
+'protectedpages-reason' => 'Motiv',
+'protectedpages-unknown-timestamp' => 'Necunoscut',
+'protectedpages-unknown-performer' => 'Utilizator necunoscut',
 'protectedtitles' => 'Titluri protejate',
 'protectedtitlesempty' => 'Nu există titluri protejate cu acești parametri.',
 'listusers' => 'Listă utilizatori',
@@ -2985,6 +2992,7 @@ $2',
 'thumbnail_image-type' => 'Acest tip de imagine nu este suportat',
 'thumbnail_gd-library' => 'Configurație incompletă a bibliotecii GD: lipsește funcția $1',
 'thumbnail_image-missing' => 'Fișierul următor nu poate fi găsit: $1',
+'thumbnail_image-failure-limit' => 'Recent au existat prea multe încercări nereușite ($1 sau mai multe) pentru a randa această miniatură. Încercați din nou mai târziu.',
 
 # Special:Import
 'import' => 'Importare pagini',
index 7897a32..6cd2cb6 100644 (file)
@@ -606,7 +606,6 @@ $messages = array(
 'vector-action-protect' => 'Защитить',
 'vector-action-undelete' => 'Восстановить',
 'vector-action-unprotect' => 'Изменить защиту',
-'vector-simplesearch-preference' => 'Включить упрощённую строку поиска (только для оформления «Векторное»)',
 'vector-view-create' => 'Создание',
 'vector-view-edit' => 'Править',
 'vector-view-history' => 'История',
@@ -910,7 +909,7 @@ $2',
 'createacct-captcha' => 'Проверка безопасности',
 'createacct-imgcaptcha-ph' => 'Введите текст, который вы видите выше',
 'createacct-submit' => 'Создать учётную запись',
-'createacct-another-submit' => 'Создать ещё одну учётную запись',
+'createacct-another-submit' => 'Создать ещё одну запись',
 'createacct-benefit-heading' => '{{SITENAME}} — совместный труд таких же людей, как вы.',
 'createacct-benefit-body1' => '{{PLURAL:$1|правка|правок|правки}}',
 'createacct-benefit-body2' => '{{PLURAL:$1|статья|статей|статьи}}',
@@ -2374,6 +2373,14 @@ $1',
 'protectedpages-cascade' => 'Только каскадная защита',
 'protectedpages-noredirect' => 'Скрыть перенаправления',
 'protectedpagesempty' => 'В настоящий момент нет защищённых страниц с указанными параметрами',
+'protectedpages-timestamp' => 'Дата/время',
+'protectedpages-page' => 'Страница',
+'protectedpages-expiry' => 'Истекает',
+'protectedpages-performer' => 'Защита участника',
+'protectedpages-params' => 'Параметры защиты',
+'protectedpages-reason' => 'Причина',
+'protectedpages-unknown-timestamp' => 'Неизвестно',
+'protectedpages-unknown-performer' => 'Неизвестный участник',
 'protectedtitles' => 'Защищённые названия',
 'protectedtitlesempty' => 'В настоящий момент нет запрещённых названий с указанными параметрами.',
 'listusers' => 'Список участников',
@@ -3136,6 +3143,7 @@ $2',
 'thumbnail_image-type' => 'Данный тип изображения не поддерживается',
 'thumbnail_gd-library' => 'Неполная конфигурация библиотеки GD, отсутствует функция $1',
 'thumbnail_image-missing' => 'По-видимому, отсутствует файл $1',
+'thumbnail_image-failure-limit' => 'Было сделано слишком много неудачных попыток ($1 или больше) формирования этого эскиза. Пожалуйста, повторите попытку позже.',
 
 # Special:Import
 'import' => 'Импортирование страниц',
@@ -4150,7 +4158,7 @@ $5
 'duplicate-defaultsort' => 'Внимание. Ключ сортировки по умолчанию «$2» переопределяет прежний ключ сортировки по умолчанию «$1».',
 
 # Special:Version
-'version' => 'Версия MediaWiki',
+'version' => 'Версия',
 'version-extensions' => 'Установленные расширения',
 'version-specialpages' => 'Служебные страницы',
 'version-parserhooks' => 'Перехватчики синтаксического анализатора',
index 7220cd9..4a58588 100644 (file)
@@ -369,7 +369,6 @@ $messages = array(
 'vector-action-protect' => 'Zaštiti',
 'vector-action-undelete' => 'Vrati obrisano',
 'vector-action-unprotect' => 'Promijeni zaštitu',
-'vector-simplesearch-preference' => 'Omogući traku za pojednostavljenu pretragu (samo Vector skin)',
 'vector-view-create' => 'Napravi',
 'vector-view-edit' => 'Uredi',
 'vector-view-history' => 'Pregled historije',
@@ -419,7 +418,7 @@ $messages = array(
 'talk' => 'Razgovor / Разговор',
 'views' => 'Pregledi',
 'toolbox' => 'Alatke / Алатке',
-'userpage' => 'Pogledajte korisničku stranicu',
+'userpage' => 'Pogledaj korisničku stranicu - Погледај корисничку страницу',
 'projectpage' => 'Pogledajte stranicu projekta',
 'imagepage' => 'Vidi stranicu datoteke/fajla',
 'mediawikipage' => 'Pogledaj stranicu s porukom',
@@ -461,7 +460,7 @@ $1',
 'policy-url' => 'Project:Pravila',
 'portal' => 'Portal zajednice',
 'portal-url' => 'Project:Portal_zajednice',
-'privacy' => 'Politika privatnosti',
+'privacy' => 'Politika privatnosti - Политика приватности',
 'privacypage' => 'Project:Pravila o anonimnosti',
 
 'badaccess' => 'Greška pri odobrenju',
@@ -633,7 +632,7 @@ Ne zaboravite izmijeniti vlastite [[Special:Preferences|{{SITENAME}} postavke]].
 'login' => 'Prijavi me - Пријави ме',
 'nav-login-createaccount' => 'Prijavi se / Registruj se',
 'loginprompt' => "Morate imati kolačiće ('''cookies''') omogućene da biste se prijavili na {{SITENAME}}.",
-'userlogin' => 'Prijavi se / stvori korisnički račun',
+'userlogin' => 'Prijavi se / Пријави се',
 'userloginnocreate' => 'Prijavi se',
 'logout' => 'Odjavi se - Одјави се',
 'userlogout' => 'Odjavi se / Одјави се',
@@ -1068,7 +1067,7 @@ Ovakvi argumenti se trebaju izbjegavati.",
 Molimo da provjerite usporedbu ispod da budete sigurni da to želite učiniti, a zatim spremite promjene da bi ste završili vraćanje izmjene.',
 'undo-failure' => 'Izmjene se ne mogu vratiti zbog konflikta sa izmjenama u međuvremenu.',
 'undo-norev' => 'Izmjena se ne može vratiti jer ne postoji ranija ili je obrisana.',
-'undo-summary' => 'Vraćena izmjena $1 [[Special:Contributions/$2|korisnika $2]] ([[User talk:$2|razgovor]])',
+'undo-summary' => 'Poništena izmjena $1 [[Special:Contributions/$2|korisnika $2]] ([[User talk:$2|razgovor]])',
 'undo-summary-username-hidden' => 'Poništi izmjenu $1 od skrivenog korisnika',
 
 # Account creation failure
@@ -1615,8 +1614,8 @@ u zadnjih / у последњних $2 dana / дана<br />
 <br>
 $3
 <br>',
-'diff' => 'razl',
-'hist' => 'hist',
+'diff' => 'razl-разл',
+'hist' => 'his-пов',
 'hide' => 'Sakrij',
 'show' => 'prikaži / прикажи',
 'minoreditletter' => 'm/м',
@@ -1646,7 +1645,7 @@ Stranice koje su na vašem [[Special:Watchlist|spisku praćenja]] su '''podeblja
 'uploadbtn' => 'Postavi datoteku',
 'reuploaddesc' => 'Vratite se na upitnik za slanje',
 'upload-tryagain' => 'Pošaljite izmijenjeni opis datoteke',
-'uploadnologin' => 'Niste prijavljeni',
+'uploadnologin' => 'Niste prijavljeni / Нисте пријављени',
 'uploadnologintext' => 'Morate biti $1 da bi ste slali datoteke.',
 'upload_directory_missing' => 'Folder za postavljanje ($1) nedostaje i webserver ga ne može napraviti.',
 'upload_directory_read_only' => 'Folder za postavljanje ($1) na webserveru je postavljen samo za čitanje.',
@@ -2911,7 +2910,7 @@ Molimo pokušajte ponovno.',
 'import-rootpage-nosubpage' => 'Imenski prostor „$1“ osnovne stranice ne dozvoljava podstranice.',
 
 # Import log
-'importlogpage' => 'Registar uvoza',
+'importlogpage' => 'Evidencija uvoza stranica',
 'importlogpagetext' => 'Administrativni uvozi stranica s historijom izmjena sa drugih wikija.',
 'import-logentry-upload' => 'uvezen/a [[$1]] postavljanjem datoteke',
 'import-logentry-upload-detail' => '$1 {{PLURAL:$1|revizija|revizije|revizija}}',
index 894dfa2..ba38fa5 100644 (file)
@@ -349,7 +349,6 @@ $messages = array(
 'vector-action-protect' => 'Zaščiti',
 'vector-action-undelete' => 'Vrni',
 'vector-action-unprotect' => 'Spremeni zaščito',
-'vector-simplesearch-preference' => 'Omogoči poenostavljeno vrstico za iskanje (samo koža Vector)',
 'vector-view-create' => 'Ustvari',
 'vector-view-edit' => 'Uredi',
 'vector-view-history' => 'Zgodovina',
@@ -2134,10 +2133,20 @@ Sedaj je preusmeritev na [[$2]].',
 'deadendpagestext' => 'Spodaj navedene strani se ne povezujejo na druge članke v {{GRAMMAR:dajalnik|{{SITENAME}}}}.',
 'protectedpages' => 'Zaščitene strani',
 'protectedpages-indef' => 'Samo neomejene zaščite',
+'protectedpages-summary' => 'Stran navaja obstoječe strani, ki so trenutno zaščitene. Za seznam strani, ki so zaščitene pred ustvarjanjem, glej [[{{#special:ProtectedTitles}}]].',
 'protectedpages-cascade' => 'Le kaskadne zaščite',
 'protectedpages-noredirect' => 'Skrij preusmeritve',
 'protectedpagesempty' => 'Nobena stran ni trenutno zaščitena s temi parametri.',
+'protectedpages-timestamp' => 'Časovni žig',
+'protectedpages-page' => 'Stran',
+'protectedpages-expiry' => 'Poteče',
+'protectedpages-performer' => 'Zaščitni uporabnik',
+'protectedpages-params' => 'Parametri zaščite',
+'protectedpages-reason' => 'Razlog',
+'protectedpages-unknown-timestamp' => 'Neznano',
+'protectedpages-unknown-performer' => 'Neznani uporabnik',
 'protectedtitles' => 'Zaščiteni naslovi',
+'protectedtitles-summary' => 'Stran navaja obstoječe strani, ki so trenutno zaščitene pred ustvarjanjem. Za seznam obstoječih strani, ki so zaščitene, glej [[{{#special:ProtectedPages}}]].',
 'protectedtitlesempty' => 'Noben naslov ni trenutno zaščiten s temi parametri.',
 'listusers' => 'Seznam uporabnikov',
 'listusers-editsonly' => 'Pokaži samo uporabnike z urejanji',
@@ -2906,6 +2915,7 @@ $2',
 'thumbnail_image-type' => 'Vrsta slike ni podprta',
 'thumbnail_gd-library' => 'Nepopolna konfiguracija knjižice GD: manjka funkcija $1',
 'thumbnail_image-missing' => 'Kaže, da datoteka manjka: $1',
+'thumbnail_image-failure-limit' => 'Nedavno je bilo preveč spodletelih poskusov ($1 ali več) izdelave sličice. Prosimo, poskusite znova pozneje.',
 
 # Special:Import
 'import' => 'Uvoz strani',
index f715235..1b7fb33 100644 (file)
@@ -558,7 +558,6 @@ $messages = array(
 'vector-action-protect' => 'Заштити',
 'vector-action-undelete' => 'Врати',
 'vector-action-unprotect' => 'Промени заштиту',
-'vector-simplesearch-preference' => 'Упрошћено поље за претрагу (само за тему „Векторско“)',
 'vector-view-create' => 'Направи',
 'vector-view-edit' => 'Уреди',
 'vector-view-history' => 'Историја',
@@ -580,7 +579,7 @@ $messages = array(
 'history' => 'Историја странице',
 'history_short' => 'Историја',
 'updatedmarker' => 'ажурирано од моје последње посете',
-'printableversion' => 'Ð\92еÑ\80зиÑ\98а Ð·Ð° Ñ\88Ñ\82ампÑ\83',
+'printableversion' => 'Ð\97а Ñ\88Ñ\82ампаÑ\9aе',
 'permalink' => 'Трајна веза',
 'print' => 'Штампај',
 'view' => 'Погледај',
@@ -1256,7 +1255,7 @@ $2
 # "Undo" feature
 'undo-success' => 'Измена се може вратити.
 Проверите разлике испод, па сачувајте измене.',
-'undo-failure' => 'Ð\9dе Ð¼Ð¾Ð³Ñ\83 Ð´Ð° Ð²Ñ\80аÑ\82им Ð¸Ð·Ð¼ÐµÐ½Ñ\83 Ð·Ð±Ð¾Ð³ Ð¿Ð¾Ñ\81Ñ\82оÑ\98аÑ\9aа Ñ\81Ñ\83кобÑ\99ениÑ\85 Ð¼ÐµÑ\92Ñ\83измена.',
+'undo-failure' => 'Ð\9eва Ð¸Ð·Ð¼ÐµÐ½Ð° Ñ\81е Ð½Ðµ Ð¼Ð¾Ð¶Ðµ Ð¿Ð¾Ð½Ð¸Ñ\88Ñ\82иÑ\82и Ð·Ð±Ð¾Ð³ ÐºÐ¾Ð½Ñ\84ликÑ\82а измена.',
 'undo-norev' => 'Не могу да вратим измену јер не постоји или је обрисана.',
 'undo-summary' => 'Поништена измена $1 {{GENDER:$2|корисника|кориснице}} [[Special:Contributions/$2|$2]] ([[User talk:$2|разговор]])',
 'undo-summary-username-hidden' => 'Поништи измену $1 скривеног корисника',
@@ -1647,7 +1646,7 @@ $1",
 'group-all' => '(сви)',
 
 'group-user-member' => '{{GENDER:$1|корисник|корисница|корисник}}',
-'group-autoconfirmed-member' => '{{GENDER:$1|аутоматски потврђен корисник|аутоматски потврђена корисница|аутоматски потврђен корисник}}',
+'group-autoconfirmed-member' => '{{GENDER:$1|аутоматски потврђен корисник|аутоматски потврђена корисница}}',
 'group-bot-member' => '{{GENDER:$1|бот}}',
 'group-sysop-member' => '{{GENDER:$1|администратор|администраторка|администратор}}',
 'group-bureaucrat-member' => '{{GENDER:$1|бирократа|бирократкиња|бирократа}}',
@@ -1742,7 +1741,7 @@ $1",
 'action-createaccount' => 'отварање овог корисничког налога',
 'action-minoredit' => 'означавање ове измене као мање',
 'action-move' => 'премести ову страницу',
-'action-move-subpages' => 'пÑ\80емеÑ\81Ñ\82и Ð¾Ð²Ñ\83 Ñ\81Ñ\82Ñ\80аниÑ\86Ñ\83, ÐºÐ°Ð¾ Ð¸ Ñ\9aене Ð¿Ð¾Ð´Ñ\81Ñ\82Ñ\80аниÑ\86е',
+'action-move-subpages' => 'пÑ\80емеÑ\88Ñ\82аÑ\9aе Ð¾Ð²Ðµ Ñ\81Ñ\82Ñ\80аниÑ\86е Ð¸ Ñ\9aениÑ\85 Ð¿Ð¾Ð´Ñ\81Ñ\82Ñ\80аниÑ\86а',
 'action-move-rootuserpages' => 'премештање основних корисничких страница',
 'action-movefile' => 'премести ову датотеку',
 'action-upload' => 'слање ове датотеке',
@@ -2657,7 +2656,7 @@ $UNWATCHURL
 'protect-edit-reasonlist' => 'Уреди разлоге заштићивања',
 'protect-expiry-options' => '1 сат:1 hour,1 дан:1 day,1 недеља:1 week,2 недеље:2 weeks,1 месец:1 month,3 месеца:3 months,6 месеци:6 months,1 година:1 year,трајно:infinite',
 'restriction-type' => 'Дозвола:',
-'restriction-level' => 'СÑ\82епен Ð¾Ð³Ñ\80аниÑ\87еÑ\9aа:',
+'restriction-level' => 'Ð\9dиво Ð·Ð°Ñ\88Ñ\82иÑ\82е:',
 'minimum-size' => 'Најмања величина',
 'maximum-size' => 'Највећа величина:',
 'pagesize' => '(бајтови)',
@@ -2671,7 +2670,7 @@ $UNWATCHURL
 # Restriction levels
 'restriction-level-sysop' => 'потпуно заштићено',
 'restriction-level-autoconfirmed' => 'полузаштићено',
-'restriction-level-all' => 'било који степен',
+'restriction-level-all' => 'сви нивои',
 
 # Undelete
 'undelete' => 'Приказ обрисаних страница',
@@ -4344,7 +4343,7 @@ $5
 'logentry-rights-rights' => '$1 је {{GENDER:$2|променио|променила}} чланство групе за $3 из $4 у $5',
 'logentry-rights-rights-legacy' => '$1 је {{GENDER:$2|променио|променила}} чланство групе за $3',
 'logentry-rights-autopromote' => '$1 је аутоматски {{GENDER:$2|унапређен|унапређена}} из $4 у $5',
-'rightsnone' => '(ниÑ\88Ñ\82а)',
+'rightsnone' => '(нема)',
 
 # Feedback
 'feedback-bugornote' => 'Ако сте спремни да детаљно опишете технички проблем, онда [$1 пријавите грешку].
index c140704..24766d4 100644 (file)
@@ -469,7 +469,6 @@ $messages = array(
 'vector-action-protect' => 'Zaštiti',
 'vector-action-undelete' => 'Vrati',
 'vector-action-unprotect' => 'Promeni zaštitu',
-'vector-simplesearch-preference' => 'Uprošćeno polje za pretragu (samo za temu „Vektorsko“)',
 'vector-view-create' => 'Napravi',
 'vector-view-edit' => 'Uredi',
 'vector-view-history' => 'Istorija',
@@ -490,7 +489,7 @@ $messages = array(
 'history' => 'Istorija stranice',
 'history_short' => 'Istorija',
 'updatedmarker' => 'ažurirano od moje poslednje posete',
-'printableversion' => 'Verzija za štampu',
+'printableversion' => 'Za štampanje',
 'permalink' => 'Trajna veza',
 'print' => 'Štampaj',
 'view' => 'Pogledaj',
@@ -1141,7 +1140,7 @@ Ovakve argumente bi trebalo izbegavati.",
 # "Undo" feature
 'undo-success' => 'Izmena se može vratiti.
 Proverite razlike ispod, pa sačuvajte izmene.',
-'undo-failure' => 'Ne mogu da vratim izmenu zbog postojanja sukobljenih međuizmena.',
+'undo-failure' => 'Ova izmena se ne može poništiti zbog konflikta izmena.',
 'undo-norev' => 'Ne mogu da vratim izmenu jer ne postoji ili je obrisana.',
 'undo-summary' => 'Poništena izmena $1 {{GENDER:$2|korisnika|korisnice}} [[Special:Contributions/$2|$2]] ([[User talk:$2|razgovor]])',
 
@@ -1528,7 +1527,7 @@ Ako izaberete da ga unesete, ono će biti korišćeno za pripisivanje vašeg rad
 'group-all' => '(svi)',
 
 'group-user-member' => '{{GENDER:$1|korisnik|korisnica|korisnik}}',
-'group-autoconfirmed-member' => '{{GENDER:$1|automatski potvrđen korisnik|automatski potvrđena korisnica|automatski potvrđen korisnik}}',
+'group-autoconfirmed-member' => '{{GENDER:$1|automatski potvrđen korisnik|automatski potvrđena korisnica}}',
 'group-bot-member' => '{{GENDER:$1|bot}}',
 'group-sysop-member' => '{{GENDER:$1|administrator|administratorka}}',
 'group-bureaucrat-member' => '{{GENDER:$1|birokrata|birokratkinja}}',
@@ -1619,7 +1618,7 @@ Ako izaberete da ga unesete, ono će biti korišćeno za pripisivanje vašeg rad
 'action-createaccount' => 'otvaranje ovog korisničkog naloga',
 'action-minoredit' => 'označavanje ove izmene kao manje',
 'action-move' => 'premesti ovu stranicu',
-'action-move-subpages' => 'premesti ovu stranicu, kao i njene podstranice',
+'action-move-subpages' => 'premeštanje ove stranice i njenih podstranica',
 'action-move-rootuserpages' => 'premeštanje osnovnih korisničkih stranica',
 'action-movefile' => 'premesti ovu datoteku',
 'action-upload' => 'slanje ove datoteke',
@@ -2514,7 +2513,7 @@ Možete da promenite stepen zaštite, ali to neće uticati na prenosivu zaštitu
 'protect-edit-reasonlist' => 'Uredi razloge zaštićivanja',
 'protect-expiry-options' => '1 sat:1 hour,1 dan:1 day,1 nedelja:1 week,2 nedelje:2 weeks,1 mesec:1 month,3 meseca:3 months,6 meseci:6 months,1 godina:1 year,trajno:infinite',
 'restriction-type' => 'Dozvola:',
-'restriction-level' => 'Stepen ograničenja:',
+'restriction-level' => 'Nivo zaštite:',
 'minimum-size' => 'Najmanja veličina',
 'maximum-size' => 'Najveća veličina:',
 'pagesize' => '(bajtovi)',
@@ -2528,7 +2527,7 @@ Možete da promenite stepen zaštite, ali to neće uticati na prenosivu zaštitu
 # Restriction levels
 'restriction-level-sysop' => 'potpuno zaštićeno',
 'restriction-level-autoconfirmed' => 'poluzaštićeno',
-'restriction-level-all' => 'bilo koji stepen',
+'restriction-level-all' => 'svi nivoi',
 
 # Undelete
 'undelete' => 'Prikaz obrisanih stranica',
@@ -4181,7 +4180,7 @@ Trebalo bi da ste primili [{{SERVER}}{{SCRIPTPATH}}/COPYING primerak GNU-ove op
 'logentry-rights-rights' => '$1 je {{GENDER:$1|promenio|promenila}} članstvo grupe za $3 iz $4 u $5',
 'logentry-rights-rights-legacy' => '$1 je {{GENDER:$2|promenio|promenila}} čalnstvo grupe za $3',
 'logentry-rights-autopromote' => '$1 je automatski {{GENDER:$1|unapređen|unapređena}} iz $4 u $5',
-'rightsnone' => '(ništa)',
+'rightsnone' => '(nema)',
 
 # Feedback
 'feedback-bugornote' => 'Ako ste spremni da detaljno opišete tehnički problem, onda [$1 prijavite grešku].
index 6b654b5..be034d8 100644 (file)
@@ -489,7 +489,6 @@ $messages = array(
 'vector-action-protect' => 'Skrivskydda',
 'vector-action-undelete' => 'Återställ',
 'vector-action-unprotect' => 'Ändra skydd',
-'vector-simplesearch-preference' => 'Aktivera förenklat sökfält (endast Vector-utseendet)',
 'vector-view-create' => 'Skapa',
 'vector-view-edit' => 'Redigera',
 'vector-view-history' => 'Visa historik',
@@ -655,9 +654,9 @@ Detta kan tyda på en bugg i mjukvaran.',
 'databaseerror-query' => 'Fråga: $1',
 'databaseerror-function' => 'Funktion: $1',
 'databaseerror-error' => 'Fel: $1',
-'laggedslavemode' => 'Varning: Sidan kan sakna de senaste uppdateringarna.',
+'laggedslavemode' => '<strong>Varning:</strong> Sidan kan sakna de senaste uppdateringarna.',
 'readonly' => 'Databasen är låst',
-'enterlockreason' => 'Ange varför sidan låsts, och ge en uppskattning av hur länge skrivskyddet bör behållas.',
+'enterlockreason' => 'Ange varför sidan låsts, och ge en uppskattning av hur länge låset kommer att släppas',
 'readonlytext' => 'Databasen är tillfälligt låst för nya inlägg och andra modifieringar, förmodligen på grund av rutinmässigt underhåll, efter vilket den kommer den att återgå till normalläge.
 
 Den administratör som låste den har angivit följande förklaring: $1',
@@ -1031,16 +1030,16 @@ Det kan ha flyttats eller raderats medan du tittade på sidan.',
 'accmailtitle' => 'Lösenord skickat.',
 'accmailtext' => "Ett slumpgenererat lösenord för [[User talk:$1|$1]] har skickats till $2. Det kan ändras på sidan ''[[Special:ChangePassword|ändra lösenord]]'' när du loggar in.",
 'newarticle' => '(Ny)',
-'newarticletext' => 'Du har klickat på en länk till en sida som inte finns ännu. Du kan själv skapa sidan genom att skriva i fältet nedan (du kan läsa mer på [[{{MediaWiki:Helppage}}|hjälpsidan]]). Om du inte vill skriva något kan du bara trycka på "tillbaka" i din webbläsare.',
+'newarticletext' => 'Du har klickat på en länk till en sida som inte finns ännu. För att skapa sidan, börja att skriva i fältet nedan (du kan läsa mer på [[{{MediaWiki:Helppage}}|hjälpsidan]]). Om du kom hit av misstag kan du bara trycka på <strong>tillbaka</strong>-knappen i din webbläsare.',
 'anontalkpagetext' => "----''Detta är diskussionssidan för en anonym användare som inte ännu skapat ett konto, eller som inte använder det.
 Därför måste vi använda den numeriska IP-adressen för att identifiera honom/henne.
 En sådan IP-adress kan delas av flera användare.
 Om du är en anonym användare och känner att irrelevanta kommentarer har riktats mot dig, vänligen [[Special:UserLogin/signup|skapa ett konto]] eller [[Special:UserLogin|logga in]] för att undvika framtida förväxlingar med andra anonyma användare.''",
 'noarticletext' => 'Det finns just nu ingen text på denna sida.
-Du kan [[Special:Search/{{PAGENAME}}|söka efter denna sidtitel]] på andra sidor, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} söka i loggarna], eller [{{fullurl:{{FULLPAGENAME}}|action=edit}} redigera denna sida]</span>.',
+Du kan [[Special:Search/{{PAGENAME}}|söka efter denna sidtitel]] på andra sidor, <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} söka i relaterade loggar], eller [{{fullurl:{{FULLPAGENAME}}|action=edit}} redigera denna sida]</span>.',
 'noarticletext-nopermission' => 'Det finns för tillfället ingen text på denna sida.
 Du kan [[Special:Search/{{PAGENAME}}|söka efter denna sidas titel]] på andra sidor,
-eller <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} söka i relaterade loggar]</span>.',
+eller <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} söka i relaterade loggar]</span> men du har inte behörighet att skapa sidan.',
 'missing-revision' => 'Revisionen #$1 av sidan med namnet "{{PAGENAME}}" finns inte.
 
 Detta orsakas vanligen av efter en gammal historiklänk till en sida som har raderats.
@@ -1396,7 +1395,7 @@ Detaljer kan hittas i [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}
 'nextn-title' => 'Nästa $1 {{PLURAL:$1|resultat|resultat}}',
 'shown-title' => 'Visa $1 {{PLURAL:$1|resultat|resultat}} per sida',
 'viewprevnext' => 'Visa ($1 {{int:pipe-separator}} $2) ($3)',
-'searchmenu-exists' => "'''Det finns en sida med namnet \"[[:\$1]]\" på denna wiki.''' {{PLURAL:\$2|0=|Se även de andra sökresultaten som hittades.}}",
+'searchmenu-exists' => '<strong>Det finns en sida med namnet "[[:$1]]" på denna wiki.</strong> {{PLURAL:$2|0=|Se även de andra sökresultaten som hittades.}}',
 'searchmenu-new' => '<strong>Skapa sidan "[[:$1]]" på denna wiki!</strong> {{PLURAL:$2|0=|Se även sidan som hittades med din sökning.|Se även sidorna som hittades med din sökning.}}',
 'searchprofile-articles' => 'Innehållssidor',
 'searchprofile-project' => 'Hjälp- och projektsidor',
@@ -1533,7 +1532,7 @@ Programvaran använder detta värde för att adressera dig till andra med rätt
 'prefs-help-realname' => 'Riktigt namn behöver inte anges.
 Om du väljer att ange ditt riktiga namn, kommer det att användas för att tillskriva dig ditt arbete.',
 'prefs-help-email' => 'Att ange e-postadress är valfritt, men gör det möjligt att få ditt lösenord mejlat till dig om du glömmer det.',
-'prefs-help-email-others' => 'Du kan också välja att låta andra användare kontakta dig genom din användar- eller diskussionssida utan att avslöja din identitet.',
+'prefs-help-email-others' => 'Du kan också välja att låta andra kontakta dig med e-post genom en länk på din användar- eller diskussionssida. Din e-postadress avslöjas inte när andra användare kontaktar dig.',
 'prefs-help-email-required' => 'E-postadress måste anges.',
 'prefs-info' => 'Grundläggande information',
 'prefs-i18n' => 'Internationalisering',
@@ -2248,6 +2247,14 @@ Varje rad innehåller länkar till den första och andra omdirigeringsidan, samt
 'protectedpages-cascade' => 'Endast kaskaderande skydd',
 'protectedpages-noredirect' => 'Dölj omdirigeringar',
 'protectedpagesempty' => 'Inga sidor är skyddade under de villkoren.',
+'protectedpages-timestamp' => 'Tidsstämpel',
+'protectedpages-page' => 'Sida',
+'protectedpages-expiry' => 'Upphör',
+'protectedpages-performer' => 'Skyddar användare',
+'protectedpages-params' => 'Skyddsparametrar',
+'protectedpages-reason' => 'Anledning',
+'protectedpages-unknown-timestamp' => 'Okänd',
+'protectedpages-unknown-performer' => 'Okänd användare',
 'protectedtitles' => 'Skyddade titlar',
 'protectedtitlesempty' => 'Just nu finns inga skyddade sidtitlar med de parametrarna.',
 'listusers' => 'Användarlista',
@@ -2276,7 +2283,7 @@ Observera att andra webbplatser kan länka direkt till en fil med en URL. Filer
 # Book sources
 'booksources' => 'Bokkällor',
 'booksources-search-legend' => 'Sök efter bokkällor',
-'booksources-go' => '',
+'booksources-go' => 'Visa',
 'booksources-text' => 'Nedan följer en lista över länkar till webbplatser som säljer nya och begagnade böcker, och som kanske har ytterligare information om de böcker du söker.',
 'booksources-invalid-isbn' => 'Det angivna ISBN-numret verkar inte vara giltigt. Kontrollera källan för eventuella fel.',
 
@@ -2664,7 +2671,7 @@ $1',
 
 # Namespace form on various pages
 'namespace' => 'Namnrymd:',
-'invert' => 'Uteslut vald namnrymd',
+'invert' => 'Invertera val',
 'tooltip-invert' => 'Markera denna ruta för att dölja ändringar på sidor inom det valda namnrymden (och tillhörande namnrymden om det är markerat)',
 'namespace_association' => 'Associerad namnrymd',
 'tooltip-namespace_association' => 'Markera denna ruta för att även inkludera diskussions- eller ämnesnamnrymden som är associerad med den valda namnrymden',
@@ -2773,7 +2780,7 @@ För att se alla aktuella blockeringar, gå till [[Special:BlockList|listan öve
 'blocklist-userblocks' => 'Göm kontoblockeringar',
 'blocklist-tempblocks' => 'Dölj tillfälliga blockeringar',
 'blocklist-addressblocks' => 'Göm enskilda IP-blockeringar',
-'blocklist-rangeblocks' => 'Göm intervallblokeringar',
+'blocklist-rangeblocks' => 'Göm intervallblockeringar',
 'blocklist-timestamp' => 'Tidsstämpel',
 'blocklist-target' => 'Mål',
 'blocklist-expiry' => 'Upphör',
@@ -2920,7 +2927,7 @@ Välj något annat namn istället.',
 'movesubpagetext' => 'Denna sida har $1 {{PLURAL:$1|undersida|undersidor}} som visas nedan.',
 'movenosubpage' => 'Denna sida har inga undersidor.',
 'movereason' => 'Anledning:',
-'revertmove' => 'flytta tillbaka',
+'revertmove' => 'återställ',
 'delete_and_move' => 'Radera och flytta',
 'delete_and_move_text' => '==Radering krävs==
 Den titel du vill flytta sidan till, "[[:$1]]", finns redan. Vill du radera den för att möjliggöra flytt av denna sida dit?',
@@ -3004,6 +3011,7 @@ $2',
 'thumbnail_image-type' => 'Bildtypen stöds inte',
 'thumbnail_gd-library' => 'Inkomplett GD library konfigurering: saknar funktionen $1',
 'thumbnail_image-missing' => 'Fil verkar saknas: $1',
+'thumbnail_image-failure-limit' => 'Det har nyligen förekommit alltför många misslyckade ($1 eller fler) försök skapa den här miniatyrbilden. Försök igen senare.',
 
 # Special:Import
 'import' => 'Importera sidor',
@@ -3106,12 +3114,12 @@ Vänligen använd förhandsgranskningsknappen innan du sparar.',
 'tooltip-n-currentevents' => 'Hitta bakgrundsinformation om aktuella händelser',
 'tooltip-n-recentchanges' => 'Lista över senaste ändringar i wikin',
 'tooltip-n-randompage' => 'Gå till en slumpmässigt vald sida',
-'tooltip-n-help' => 'Hjälp och information',
+'tooltip-n-help' => 'Platsen för att hitta',
 'tooltip-t-whatlinkshere' => 'Lista över alla wikisidor som länkar hit',
 'tooltip-t-recentchangeslinked' => 'Visa senaste ändringarna av sidor som den här sidan länkar till',
-'tooltip-feed-rss' => 'RSS-matning för den här sidan',
-'tooltip-feed-atom' => 'Atom-matning för den här sidan',
-'tooltip-t-contributions' => 'Visa lista över bidrag från den här användaren',
+'tooltip-feed-rss' => 'RSS-flöde för den här sidan',
+'tooltip-feed-atom' => 'Atom-flöde för den här sidan',
+'tooltip-t-contributions' => 'En lista över bidrag från den här användaren',
 'tooltip-t-emailuser' => 'Skicka e-post till den här användaren',
 'tooltip-t-upload' => 'Ladda upp filer',
 'tooltip-t-specialpages' => 'Lista över alla specialsidor',
@@ -3139,7 +3147,7 @@ Vänligen använd förhandsgranskningsknappen innan du sparar.',
 'tooltip-upload' => 'Starta uppladdning',
 'tooltip-rollback' => '"Tillbakarullning" tar med en knapptryckning bort ändringar som gjorts av den som senast redigerade sidan',
 'tooltip-undo' => '"Gör ogjord" återställer denna redigering och öppnar redigeringsrutan med förhandsgranskning.
-Ger möjlighet att skriva en motivering i redigeringssammanfattningen',
+Den ger möjlighet att skriva en motivering i redigeringssammanfattningen.',
 'tooltip-preferences-save' => 'Spara inställningar',
 'tooltip-summary' => 'Skriv en kort sammanfattning',
 'interlanguage-link-title' => '$1 - $2',
@@ -4178,6 +4186,7 @@ Annars kan du använda det enkla formuläret nedan. Din kommentar kommer att lä
 'api-error-overwrite' => 'Det är inte tillåtet att skriva över en befintlig fil.',
 'api-error-stashfailed' => 'Internt fel: servern kunde inte lagra temporär fil.',
 'api-error-publishfailed' => 'Internt fel: Servern kunde inte publicera temporär fil.',
+'api-error-stasherror' => 'Ett fel uppstod under uppladdningen av filen till mellanlagringsfilen.',
 'api-error-timeout' => 'Servern svarade inte inom förväntad tid.',
 'api-error-unclassified' => 'Ett okänt fel uppstod',
 'api-error-unknown-code' => 'Okänt fel: "$1"',
index 4be19de..81d554b 100644 (file)
@@ -8,6 +8,7 @@
  * @file
  *
  * @author Arjunaraoc
+ * @author Ashokjayanti
  * @author Chaduvari
  * @author Jprmvnvijay5
  * @author Kaganer
@@ -152,7 +153,7 @@ $messages = array(
 'tog-numberheadings' => 'శీర్షికలకు అప్రమేయంగా వరుస సంఖ్యలు చేర్చు',
 'tog-showtoolbar' => 'దిద్దుబాటు పనిముట్ల పట్టీని చూపించు',
 'tog-editondblclick' => 'డబుల్‌ క్లిక్కు చేసినప్పుడు పేజీని మార్చు',
-'tog-editsectiononrightclick' => 'విభాగాల శీర్షికల మీద కుడినొక్కుతో విభాగపు దిద్దుబాటును చేతనంచేయి',
+'tog-editsectiononrightclick' => 'విభాగాల శీర్షికల మీద కుడినొక్కుతో విభాగపు దిద్దుబాటును చేతనం చేయి',
 'tog-rememberpassword' => 'ఈ విహారిణిలో నా ప్రవేశాన్ని (గరిష్ఠంగా $1 {{PLURAL:$1|రోజు|రోజుల}} పాటు) గుర్తుంచుకో',
 'tog-watchcreations' => 'నేను సృష్టించే పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు',
 'tog-watchdefault' => 'నేను మార్చే పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు',
@@ -228,7 +229,7 @@ $messages = array(
 'may-gen' => 'మే',
 'june-gen' => 'జూన్',
 'july-gen' => 'జూలై',
-'august-gen' => 'à°\86à°\97à°·్టు',
+'august-gen' => 'à°\86à°\97à°¸్టు',
 'september-gen' => 'సెప్టెంబరు',
 'october-gen' => 'అక్టోబరు',
 'november-gen' => 'నవంబరు',
@@ -253,23 +254,23 @@ $messages = array(
 'june-date' => 'జూన్ $1',
 'july-date' => 'జూలై $1',
 'august-date' => 'ఆగస్టు $1',
-'september-date' => 'à°¸à±\86à°ªà±\8dà°\9fà±\86à°\82బరà±\8d $1',
-'october-date' => 'à°\85à°\95à±\8dà°\9fà±\8bబరà±\8d $1',
-'november-date' => 'నవà°\82బరà±\8d $1',
-'december-date' => 'à°¡à°¿à°¸à±\86à°\82బరà±\8d $1',
+'september-date' => 'à°¸à±\86à°ªà±\8dà°\9fà±\86à°\82బరà±\81 $1',
+'october-date' => 'à°\85à°\95à±\8dà°\9fà±\8bబరà±\81 $1',
+'november-date' => 'నవà°\82బరà±\81 $1',
+'december-date' => 'à°¡à°¿à°¸à±\86à°\82బరà±\81 $1',
 
 # Categories related messages
 'pagecategories' => '{{PLURAL:$1|వర్గం|వర్గాలు}}',
 'category_header' => '"$1" వర్గంలోని పుటలు',
 'subcategories' => 'ఉపవర్గాలు',
-'category-media-header' => '"$1" వర్గంలో ఉన్న మీడియా ఫైళ్లు',
-'category-empty' => "''ప్రస్తుతం ఈ వర్గంలో ఎలాంటి పేజీలుగానీ మీడియా ఫైళ్లుగానీ లేవు.''",
+'category-media-header' => '"$1" వర్గంలో ఉన్న మీడియా',
+'category-empty' => '<em>ప్రస్తుతం ఈ వర్గంలో ఎలాంటి పేజీలుగానీ మీడియాగానీ లేవు.</em>',
 'hidden-categories' => '{{PLURAL:$1|దాచిన వర్గం|దాచిన వర్గాలు}}',
 'hidden-category-category' => 'దాచిన వర్గాలు',
-'category-subcat-count' => '{{PLURAL:$2|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\95à±\8dà°°à°¿à°\82à°¦ à°\9aà±\82పిసà±\8dà°¤à±\81à°¨à±\8dà°¨ à°\92à°\95à±\87 à°\89పవరà±\8dà°\97à°\82 à°\89à°\82ది.|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\89à°¨à±\8dà°¨ à°®à±\8aà°¤à±\8dà°¤à°\82 $2 à°µà°°à±\8dà°\97ాలలà±\8b à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤à°\82 {{PLURAL:$1|à°\92à°\95 à°\89పవరà±\8dà°\97ానà±\8dని|$1 à°\89పవరà±\8dà°\97ాలనà±\81}} à°\9aà±\82పిసà±\8dà°¤à±\81à°¨à±\8dనామà±\81.}}',
-'category-subcat-count-limited' => 'ఈ వర్గం క్రింద చూపిస్తున్న {{PLURAL:$1|ఒక ఉపవర్గం ఉంది|$1 ఉపవర్గాలు ఉన్నాయి}}.',
-'category-article-count' => '{{PLURAL:$2|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\95à±\8dà°°à°¿à°\82à°¦ à°\9aà±\82పిసà±\8dà°¤à±\81à°¨à±\8dà°¨ à°\92à°\95à±\87 à°ªà±\87à°\9cà±\80 à°\89à°\82ది.|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\89à°¨à±\8dà°¨ à°®à±\8aà°¤à±\8dà°¤à°\82 $2 à°ªà±\87à°\9cà±\80లలà±\8b à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤à°\82 {{PLURAL:$1|à°\92à°\95 à°ªà±\87à°\9cà±\80ని|$1 à°ªà±\87à°\9cà±\80లనà±\81}} à°\9aà±\82పిసà±\8dà°¤à±\81à°¨à±\8dనామà±\81.}}',
-'category-article-count-limited' => 'à°\88 à°µà°°à±\8dà°\97à°\82 à°\95à±\8dà°°à°¿à°\82à°¦ à°\9aà±\82పిసà±\8dà°¤à±\81à°¨à±\8dà°¨ {{PLURAL:$1|à°\92à°\95 à°ªà±\87à°\9cà±\80 à°\89à°\82ది|$1 à°ªà±\87à°\9cà±\80à°²à±\81 à°\89న్నాయి}}.',
+'category-subcat-count' => '{{PLURAL:$2|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\95à°¿à°\82à°¦ à°\9aà±\82పిన à°\92à°\95à±\87 à°\89పవరà±\8dà°\97à°\82 à°\89à°\82ది.|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\95à°¿à°\82ది {{PLURAL:$1|à°\89పవరà±\8dà°\97à°\82 à°\89à°\82ది|$1 à°\89పవరà±\8dà°\97ాలà±\81 à°\89à°¨à±\8dనాయి}}, à°®à±\8aà°¤à±\8dà°¤à°\82 $2 à°²à±\8b.}}',
+'category-subcat-count-limited' => 'ఈ వర్గంలో కింది {{PLURAL:$1|ఉపవర్గం ఉంది|$1 ఉపవర్గాలు ఉన్నాయి}}.',
+'category-article-count' => '{{PLURAL:$2|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\95à°¿à°\82ది à°ªà±\87à°\9cà±\80 à°\92à°\95à°\9fà±\87 à°\89à°\82ది.|à°\88 à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\95à°¿à°\82ది {{PLURAL:$1|à°ªà±\87à°\9cà±\80 à°\89à°\82ది|$1 à°ªà±\87à°\9cà±\80à°²à±\81à°¨à±\8dనాయి}}, à°®à±\8aà°¤à±\8dà°¤à°\82 $2 à°ªà±\87à°\9cà±\80లలà±\8b.}}',
+'category-article-count-limited' => 'à°ªà±\8dà°°à°¸à±\8dà°¤à±\81à°¤ à°µà°°à±\8dà°\97à°\82à°²à±\8b à°\95à°¿à°\82ది {{PLURAL:$1|à°ªà±\87à°\9cà±\80 à°\89à°\82ది|$1 à°ªà±\87à°\9cà±\80à°²à±\81న్నాయి}}.',
 'category-file-count' => '{{PLURAL:$2|ఈ వర్గంలో క్రింద చూపిస్తున్న ఒకే ఫైలు ఉంది.|ఈ వర్గంలో ఉన్న మొత్తం $2 పేజీలలో ప్రస్తుతం {{PLURAL:$1|ఒక ఫైలును|$1 ఫైళ్లను}} చూపిస్తున్నాము.}}',
 'category-file-count-limited' => 'ఈ వర్గం క్రింద చూపిస్తున్న {{PLURAL:$1|ఒక ఫైలు ఉంది|$1 ఫైళ్లు ఉన్నాయి}}.',
 'listingcontinuesabbrev' => '(కొనసాగింపు)',
@@ -305,7 +306,6 @@ $messages = array(
 'vector-action-protect' => 'సంరక్షించు',
 'vector-action-undelete' => 'తిరిగి చేర్చు',
 'vector-action-unprotect' => 'సంరక్షణను మార్చు',
-'vector-simplesearch-preference' => 'సరళమైన వెతుకుడు పట్టీని చేతనంచేయి (వెక్టర్ అలంకారానికి మాత్రమే)',
 'vector-view-create' => 'సృష్టించు',
 'vector-view-edit' => 'సవరించు',
 'vector-view-history' => 'చరిత్రను చూడండి',
@@ -1433,15 +1433,15 @@ $1",
 'right-deletedtext' => 'తొలగించిన పాఠ్యాన్ని మరియు తొలగించిన కూర్పుల మధ్య మార్పలని చూడగలగడం',
 'right-browsearchive' => 'తొలగించిన పేజీలను వెతుకు',
 'right-undelete' => 'పేజీ తొలగింపును రద్దు చెయ్యి',
-'right-suppressrevision' => 'నిరà±\8dవాహà°\95à±\81à°²à°\95à±\81 à°\95నబడà°\95à±\81à°\82à°¡à°¾ à°\89à°¨à±\8dà°¨ à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81 à°¸à°®à±\80à°\95à±\8dà°·à°¿à°\82à°\9aà°¿ à°ªà±\8cనసà±\8dథాపిà°\82à°\9aà±\81',
-'right-suppressionlog' => 'à°\97à±\8bà°ªà±\8dà°¯à°\82à°\97à°¾ à°\89à°¨à±\8dà°¨ à°²à°¾à°\97à±\8dâ\80\8cలనà±\81 à°\9aà±\82à°¡à±\81',
+'right-suppressrevision' => 'నిరà±\8dవాహà°\95à±\81à°²à°\95à±\81 à°\95నబడà°\95à±\81à°\82à°¡à°¾ à°\89à°¨à±\8dà°¨ à°\95à±\82à°°à±\8dà°ªà±\81లనà±\81 à°¸à°®à±\80à°\95à±\8dà°·à°¿à°\82à°\9aà°¿ à°ªà±\81నసà±\8dథాపిà°\82à°\9aà°¡à°\82',
+'right-suppressionlog' => 'à°\97à±\8bà°ªà±\8dà°¯à°\82à°\97à°¾ à°\89à°¨à±\8dà°¨ à°²à°¾à°\97à±\8dâ\80\8cలనà±\81 à°\9aà±\82à°¡à°¡à°\82',
 'right-block' => 'దిద్దుబాటు చెయ్యకుండా ఇతర వాడుకరులను నిరోధించగలగడం',
 'right-blockemail' => 'ఈమెయిలు పంపకుండా సభ్యుని నిరోధించు',
 'right-hideuser' => 'ప్రజలకు కనబడకుండా చేసి, సభ్యనామాన్ని నిరోధించు',
 'right-ipblock-exempt' => 'ఐపీ నిరోధాలు, ఆటో నిరోధాలు, శ్రేణి నిరోధాలను తప్పించు',
 'right-proxyunbannable' => 'ప్రాక్సీల ఆటోమాటిక్ నిరోధాన్ని తప్పించు',
 'right-unblockself' => 'స్వీయ అనిరోధం',
-'right-protect' => 'à°¸à°\82à°°à°\95à±\8dà°·à°£ à°¸à±\8dథాయిలనà±\81 à°®à°¾à°°à±\8dà°\9aà±\81, à°¸à°\82రక్షిత పేజీలలో దిద్దుబాటు చెయ్యి',
+'right-protect' => 'à°¸à°\82à°°à°\95à±\8dà°·à°£ à°¸à±\8dథాయిలనà±\81 à°®à°¾à°°à±\8dà°\9aà±\81, à°\95ాసà±\8dà°\95à±\87à°¡à±\8d-రక్షిత పేజీలలో దిద్దుబాటు చెయ్యి',
 'right-editprotected' => '"{{int:protect-level-sysop}}" గా సంక్షించబడిన పేజీలను సరిదిద్దు',
 'right-editsemiprotected' => '"{{int:protect-level-autoconfirmed}}" గా సంరక్షించబడ్డ పేజీలను మార్చు',
 'right-editinterface' => 'యూజరు ఇంటరుఫేసులో దిద్దుబాటు చెయ్యి',
@@ -1528,6 +1528,7 @@ $1",
 'recentchanges' => 'ఇటీవలి మార్పులు',
 'recentchanges-legend' => 'ఇటీవలి మార్పుల ఎంపికలు',
 'recentchanges-summary' => 'వికీలో ఇటీవలే జరిగిన మార్పులను ఈ పేజీలో గమనించవచ్చు.',
+'recentchanges-noresult' => 'ఈ నియమాలకు సరిపోలే మార్పులు ఇచ్చిన కాలంలో లేవు.',
 'recentchanges-feed-description' => 'ఈ ఫీడు ద్వారా వికీలో జరుగుతున్న మార్పుల గురించి ఎప్పటికప్పుడు సమాచారాన్ని పొందండి.',
 'recentchanges-label-newpage' => 'ఈ మార్పు కొత్త పేజీని సృష్టించింది',
 'recentchanges-label-minor' => 'ఇది ఒక చిన్న మార్పు',
@@ -1699,6 +1700,7 @@ $1',
 'upload-too-many-redirects' => 'ఆ URLలో చాలా దారిమార్పులు ఉన్నాయి',
 'upload-unknown-size' => 'సైజు తెలియదు',
 'upload-http-error' => 'ఒక HTTP పొరపాటు జరిగింది: $1',
+'upload-copy-upload-invalid-domain' => 'ఈ డొమెయిన్ నుంచి కాపీ ఎక్కింపులు కుదరదు.',
 
 # File backend
 'backend-fail-stream' => '"$1" ఫైలును స్ట్రీమింగు చెయ్యలేకపోయాం.',
@@ -1724,6 +1726,18 @@ $1',
 'backend-fail-internal' => 'స్టోరేజీ బ్యాక్‍ఎండ్ "$1" లో ఏదో తెలియని లోపం దొర్లింది.',
 'backend-fail-contenttype' => '"$1" లో దాచాల్సిన ఫైలు యొక్క కంటెంటు రకమేంటో నిర్ధారించలేకపోయాం.',
 'backend-fail-batchsize' => 'స్టోరేజీ బ్యాక్‍ఎండ్ కు $1 ఫైలు {{PLURAL:$1|ఆపరేషన్|ఆపరేషన్ల}} తో కూడిన బ్యాచ్ ఒకటి ఇవ్వబడింది; పరిమితి: $2 {{PLURAL:$2|ఆపరేషన్|ఆపరేషన్లు}}.',
+'backend-fail-usable' => 'సరిపడా అనుమతులు లేకపోవడం వలన గానీ, అవసరమైన డైరెక్టరీలు/కంటెయినర్లు లేకపోవడం వలనగానీ "$1" ఫైలును చదవడం, రాయడం చెయ్యలేకపోయాం.',
+
+# Lock manager
+'lockmanager-notlocked' => '"$1" తాళం తియ్యలేకపోయాం; అదసలు లాక్ అయ్యేలేదు..',
+'lockmanager-fail-closelock' => '"$1" యొక్క లాక్ ఫైలును మూయలేకపోయాం.',
+'lockmanager-fail-deletelock' => '"$1" యొక్క లాక్ ఫైలును తొలగించలేకపోయాం.',
+'lockmanager-fail-acquirelock' => '"$1" కోసం లాక్ ను పొందలేకపోయాం.',
+'lockmanager-fail-openlock' => '"$1" కోసం లాక్ ఫైలును తెరవలేకపోయాం.',
+'lockmanager-fail-releaselock' => '"$1" యొక్క లాక్ ను విడుదల చెయ్యలేకపోయాం.',
+'lockmanager-fail-db-release' => 'డేటాబేసు $1 పై లాకులను విడుదల చెయ్యలేకపోయాం.',
+'lockmanager-fail-svr-acquire' => 'సర్వరు $1 పై లాకులను పొందలేకపోయాం.',
+'lockmanager-fail-svr-release' => 'సర్వరు $1 పై లాకులను విడుదల చెయ్యలేకపోయాం.',
 
 # ZipDirectoryReader
 'zip-file-open-error' => 'ఈ ఫైలును ZIP పరీక్ష కోసం తెరవబోతే, ఏదో తెలియని లోపం ఎదురైంది.',
@@ -1734,7 +1748,10 @@ $1',
 దీనిపై సరైన భద్రతా పరీక్షలు చెయ్యలేం.',
 
 # Special:UploadStash
+'uploadstash' => 'భోషాణం ఎక్కింపు',
 'uploadstash-summary' => 'ఎక్కించినప్పటికీ వికీలో ప్రచురితం కాని  (లేదా ఎక్కింపు జరుగుతున్న) ఫైళ్ళు ఈ పేజీలో కనిపిస్తాయి. ఈ ఫైళ్ళు ఎక్కించిన వాడుకరికి తప్ప మరొకరికి కనబడవు.',
+'uploadstash-clear' => 'భోషాణం లోని ఫైళ్లను తీసివెయ్యి',
+'uploadstash-nofiles' => 'మీకు ఫైళ్ళ భోషాణమేమీ లేదు.',
 'uploadstash-badtoken' => 'ఆ చర్య విఫలమైంది. బహుశా మీ ఎడిటింగు అనుమతులకు కాలం చెల్లిందేమో. మళ్ళీ ప్రయత్నించండి.',
 'uploadstash-errclear' => 'ఫైళ్ళ తీసివేత విఫలమైంది.',
 'uploadstash-refresh' => 'దస్త్రాల జాబిజాను తాజాకరించు',
@@ -1792,6 +1809,7 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'listfiles_size' => 'పరిమాణం',
 'listfiles_description' => 'వివరణ',
 'listfiles_count' => 'కూర్పులు',
+'listfiles-show-all' => 'బొమ్మల పాత కూర్పులను కలుపు',
 'listfiles-latestversion' => 'ప్రస్తుత కూర్పు',
 'listfiles-latestversion-yes' => 'అవును',
 'listfiles-latestversion-no' => 'కాదు',
@@ -1827,6 +1845,10 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 మరింత సమాచారం కోసం, దయచేసి [$2 ఫైలు వివరణ పేజీ]ని చూడండి.',
 'sharedupload-desc-here' => 'ఈ ఫైలు $1 నుండి మరియు దీనిని ఇతర ప్రాజెక్టులలో కూడా ఉపయోగిస్తూ ఉండవచ్చు.
 దీని [$2 ఫైలు వివరణ పేజీ] లో ఉన్న వివరణని క్రింద చూపించాం.',
+'sharedupload-desc-edit' => 'ఈ ఫైలు $1 లోనిది. దాన్ని ఇతర ప్రాజెక్టులు కూడా వాడుతూ ఉండి ఉండవచ్చు.
+దాని [$2 ఫైలు వివరణ పేజీ] లోని వివరణను మారుస్తారేమో చూడండి.',
+'sharedupload-desc-create' => 'ఈ ఫైలు $1 లోనిది. దాన్ని ఇతర ప్రాజెక్టులు కూడా వాడుతూ ఉండి ఉండవచ్చు.
+దాని [$2 ఫైలు వివరణ పేజీ] లోని వివరణను మారుస్తారేమో చూడండి.',
 'filepage-nofile' => 'ఈ పేరుతో ఏ ఫైలు లేదు.',
 'filepage-nofile-link' => 'ఈ పేరుతో ఏ ఫైలూ లేదు, కానీ మీరు $1 ను అప్‌లోడ్ చెయ్యవచ్చు.',
 'uploadnewversion-linktext' => 'ఈ దస్త్రపు కొత్త కూర్పును ఎక్కించండి',
@@ -1888,8 +1910,10 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'randompage-nopages' => 'ఈ క్రింది {{PLURAL:$2|పెరుబరిలో|పెరుబరులలో}} పేజీలు ఏమి లేవు:$1',
 
 # Random page in category
+'randomincategory' => 'వర్గంలోని యాదృచ్చిక పేజీ',
 'randomincategory-invalidcategory' => '"$1" అనేది సరైన పర్గం పేరు కాదు.',
 'randomincategory-nopages' => '[[:Category:$1|$1]] వర్గంలో పేజీలేమీ లేవు.',
+'randomincategory-selectcategory' => 'ఈ వర్గం నుంచి ఒక యాదృచ్ఛిక పేజీని చూడండి: $1 $2.',
 'randomincategory-selectcategory-submit' => 'వెళ్ళు',
 
 # Random redirect
@@ -1917,7 +1941,13 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'statistics-users-active-desc' => 'గత {{PLURAL:$1|రోజు|$1 రోజుల}}లో ఒక్క చర్యైనా చేసిన వాడుకరులు',
 'statistics-mostpopular' => 'ఎక్కువగా చూసిన పేజీలు',
 
+'pageswithprop' => 'ఒక పేజీ లక్షణం కలిగిన పేజీలు',
+'pageswithprop-legend' => 'ఒక పేజీ లక్షణం కలిగిన పేజీలు',
+'pageswithprop-text' => 'ఫలానా పేజీ లక్షణం కలిగిన పేజీల జాబితాను ఈ పేజీలో చూడవచ్చు.',
+'pageswithprop-prop' => 'లక్షణం పేరు:',
 'pageswithprop-submit' => 'వెళ్ళు',
+'pageswithprop-prophidden-long' => 'long text లక్షణం విలువ దాచబడింది ($1)',
+'pageswithprop-prophidden-binary' => 'binary లక్షణం విలువ దాచబడింది ($1)',
 
 'doubleredirects' => 'జంట దారిమార్పులు',
 'doubleredirectstext' => 'ఇతర దారిమార్పు పుటలకి తీసుకెళ్ళే దారిమార్పులని ఈ పుట చూపిస్తుంది.
@@ -1964,6 +1994,8 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'wantedpages' => 'కోరిన పేజీలు',
 'wantedpages-badtitle' => 'ఫలితాల సమితిలో తప్పుడు శీర్షిక: $1',
 'wantedfiles' => 'కావలసిన ఫైళ్ళు',
+'wantedfiletext-cat' => 'కింది ఫైళ్ళను వాడారు, కానీ అవి ఉనికిలో లేవు. బయటి రిపాజిటరీలలోని ఫైళ్ళను, అవి ఉనికిలో ఉన్నప్పటికీ, చూపవచ్చు. అటువంటి తప్పు పాజిటివులు <del>కొట్టివేయబడతాయి</del>. పైగా, ఉనికిలో లేని ఫైళ్ళను ఇమిడ్చే పేజీలు [[:$1]] లో చేర్చబడతాయి.',
+'wantedfiletext-nocat' => 'కింది ఫైళ్ళను వాడారు, కానీ అవి ఉనికిలో లేవు. బయటి రిపాజిటరీలలోని ఫైళ్ళను, అవి ఉనికిలో ఉన్నప్పటికీ, చూపవచ్చు. అటువంటి తప్పు పాజిటివులు <del>కొట్టివేయబడతాయి</del>.',
 'wantedtemplates' => 'కావాల్సిన మూసలు',
 'mostlinked' => 'అధిక లింకులు చూపే పేజీలు',
 'mostlinkedcategories' => 'అధిక లింకులు చూపే వర్గాలు',
@@ -1984,7 +2016,16 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'protectedpages-cascade' => 'కాస్కేడింగు రక్షణలు మాత్రమే',
 'protectedpages-noredirect' => 'దారిమార్పులను దాచు',
 'protectedpagesempty' => 'ఈ పరామితులతో ప్రస్తుతం ఏ పేజీలు కూడా సంరక్షించబడి లేవు.',
+'protectedpages-timestamp' => 'కాలముద్ర',
+'protectedpages-page' => 'పేజీ',
+'protectedpages-expiry' => 'కాలం చెల్లేది',
+'protectedpages-performer' => 'రక్షించబడే వాడుకరి',
+'protectedpages-params' => 'సంరక్షణ పరామితులు',
+'protectedpages-reason' => 'కారణం',
+'protectedpages-unknown-timestamp' => 'తెలియని',
+'protectedpages-unknown-performer' => 'తెలియని వాడుకరి',
 'protectedtitles' => 'సంరక్షిత శీర్షికలు',
+'protectedtitles-summary' => 'యీ పేజీలో ప్రస్తుతానికి నిర్మాణం నిషిద్దమైన శీర్ణికలన్నీ పొందుపరచబడ్డాయి.ప్రస్తుతం ఉన్న రక్షిత పేజీలకోసం యిక్కడ చూడండి [[{{#special:ProtectedPages}}]].',
 'protectedtitlesempty' => 'ఈ పరామితులతో ప్రస్తుతం శీర్షికలేమీ సరక్షించబడి లేవు.',
 'listusers' => 'వాడుకరుల జాబితా',
 'listusers-editsonly' => 'మార్పులు చేసిన వాడుకరులను మాత్రమే చూపించు',
@@ -2194,30 +2235,30 @@ https://www.mediawiki.org/wiki/Manual:Image_Authorization చూడండి.',
 'enotif_anon_editor' => 'అజ్ఞాత వాడుకరి $1',
 'enotif_body' => 'ప్రియమైన $WATCHINGUSERNAME,
 
+$PAGEINTRO $NEWPAGE
 
-{{SITENAME}}లో $PAGETITLE అనే పేజీని $PAGEEDITDATE సమయానికి $PAGEEDITOR $CHANGEDORCREATED, ప్రస్తుత కూర్పు కొరకు $PAGETITLE_URL చూడండి.
+చేర్పరి సారాంశం: $PAGESUMMARY $PAGEMINOREDIT
 
-$NEWPAGE
-
-రచయిత సారాంశం: $PAGESUMMARY $PAGEMINOREDIT
-
-రచయితను సంప్రదించండి:
+చేర్పరిని సంప్రదించండి:
 మెయిలు: $PAGEEDITOR_EMAIL
 వికీ: $PAGEEDITOR_WIKI
 
-à°®à±\80à°°à±\81 à°\88 à°ªà±\87à°\9cà±\80à°\95à°¿ à°µà±\86à°³à±\8dà°¤à±\87 à°¤à°ªà±\8dà°ª à°\87à°\95 à°®à±\81à°\82à°¦à±\81 à°\88 à°ªà±\87à°\9cà±\80à°\95à°¿ à°\9cà°°à°¿à°\97à±\87 à°®à°¾à°°à±\8dà°ªà±\81ల గురించిన వార్తలను మీకు పంపించము. మీ వీక్షణజాబితా లోని అన్ని పేజీలకు ఉన్న గమనింపు జెండాలను మార్చుకోవచ్చు.
+à°®à±\80à°°à±\81 à°²à°¾à°\97à°¿à°¨à±\88 à°\88 à°ªà±\87à°\9cà±\80à°\95à°¿ à°µà±\86à°³à±\8dà°¤à±\87 à°¤à°ªà±\8dà°ª à°\87à°\95 à°®à±\81à°\82à°¦à±\81 à°\9cà°°à°¿à°\97à±\87 à°\95ారà±\8dà°¯à°\95లాపాల గురించిన వార్తలను మీకు పంపించము. మీ వీక్షణజాబితా లోని అన్ని పేజీలకు ఉన్న గమనింపు జెండాలను మార్చుకోవచ్చు.
 
-             మీ స్నేహపూర్వక {{SITENAME}} గమనింపుల వ్యవస్థ
+మీ స్నేహపూర్వక {{SITENAME}} గమనింపుల వ్యవస్థ
 
 --
-à°®à±\80 à°µà±\80à°\95à±\8dà°·à°£à°\9cాబితా à°\85మరిà°\95లనà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\81à°¨à±\87à°\82à°¦à±\81à°\95à±\81,
-{{canonicalurl:{{#special:EditWatchlist}}}} ని చూడండి.
+à°®à±\80 à°\88à°®à±\86యిలà±\81 à°\97మనిà°\82à°ªà±\81à°² à°\85మరిà°\95లనà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\81à°¨à±\87à°\82à°¦à±\81à°\95à±\81, à°\9aà±\82à°¡à°\82à°¡à°¿
+{{canonicalurl:{{#special:Preferences}}}}
 
-à°\88 à°ªà±\87à°\9cà±\80ని à°®à±\80 à°µà±\80à°\95à±\8dà°·à°£à°\9cాబితా à°¨à±\81à°\82à°¡à°¿ à°¤à±\8aà°²à°\97à°¿à°\82à°\9aà±\81à°\95à±\81à°¨à±\87à°\82à°¦à±\81à°\95à±\81,
-$UNWATCHURL కి వెళ్ళండి.
+à°®à±\80 à°µà±\80à°\95à±\8dà°·à°£ à°\9cాబితా à°\85మరిà°\95లనà±\81 à°®à°¾à°°à±\8dà°\9aà±\81à°\95à±\81à°¨à±\87à°\82à°¦à±\81à°\95à±\81, à°\9aà±\82à°¡à°\82à°¡à°¿
+{{canonicalurl:{{#special:EditWatchlist}}}}
 
-మీ అభిప్రాయాలు చెప్పేందుకు మరియు మరింత సహాయానికై:
-{{canonicalurl:{{MediaWiki:helppage}}}}',
+మీ వీక్షణ జాబితా నుండి పేజీని తొలగించేందుకు, చూడండి
+$UNWATCHURL
+
+ఫీడుబ్యాకుకు, ఇతర సహాయం కోసం:
+{{canonicalurl:{{MediaWiki:Helppage}}}}',
 'created' => 'సృష్టించారు',
 'changed' => 'మార్చారు',
 
@@ -2251,7 +2292,7 @@ $UNWATCHURL కి వెళ్ళండి.
 'delete-edit-reasonlist' => 'తొలగింపు కారణాలని మార్చండి',
 'delete-toobig' => 'ఈ పేజీకి $1 {{PLURAL:$1|కూర్పుకు|కూర్పులకు}} మించిన, చాలా పెద్ద దిద్దుబాటు చరితం ఉంది. {{SITENAME}}కు అడ్డంకులు కలగడాన్ని నివారించేందుకు గాను, అలాంటి పెద్ద పేజీల తొలగింపును నియంత్రించాం.',
 'delete-warning-toobig' => 'ఈ పేజీకి $1 {{PLURAL:$1|కూర్పుకు|కూర్పులకు}} మించిన, చాలా పెద్ద దిద్దుబాటు చరితం ఉంది. దాన్ని తొలగిస్తే {{SITENAME}}కి చెందిన డేటాబేసు కార్యాలకు ఆటంకం కలగొచ్చు; అప్రమత్తతో ముందుకుసాగండి.',
-'deleting-backlinks-warning' => "'''హెచ్చరిక:''' మీరు తొలగించబోతున్న పేజీకి ఇతర పేజీల నుండి లింకులు ఉన్నాయి.",
+'deleting-backlinks-warning' => "'''హెచ్చరిక:''' మీరు తొలగించబోతున్న పేజీకి ఇతర పేజీల నుండి లింకులు ఉన్నాయి లేదా ఇక్కడ నుండి ట్రాన్స్‍క్లూడు అవుతున్నాయి.",
 
 # Rollback
 'rollback' => 'దిద్దుబాట్లను రద్దుచేయి',
@@ -2384,6 +2425,7 @@ $1',
 'undelete-bad-store-key' => '$1 టైమ్‌స్టాంపు కలిగిన ఫైలు తొలగింపును రద్దు చెయ్యలేకున్నాం: తొలగింపుకు ముందే ఫైలు కనబడటం లేదు.',
 'undelete-cleanup-error' => 'వాడని భాండారం ఫైలు "$1" తొలగింపును రద్దు చెయ్యడంలో లోపం దొర్లింది.',
 'undelete-missing-filearchive' => 'ID $1 కలిగిన భాండారం ఫైలు డేటాబేసులో లేకపోవడం చేత దాన్ని పునస్థాపించలేకున్నాం. దాని తొలగింపును ఇప్పటికే రద్దుపరచి ఉండవచ్చు.',
+'undelete-error' => 'పుటను తిరిగి సృష్టించుటలో దోషం',
 'undelete-error-short' => 'ఫైలు $1 తొలగింపును రద్దు పరచడంలో లోపం దొర్లింది',
 'undelete-error-long' => 'ఫైలు $1 తొలగింపును రద్దు పరచడంలో లోపాలు దొర్లాయి',
 'undelete-show-file-confirm' => '$2 నాడు $3 సమయాన ఉన్న "<nowiki>$1</nowiki>" ఫైలు యొక్క తొలగించిన కూర్పుని మీరు నిజంగానే చూడాలనుకుంటున్నారా?',
@@ -2481,6 +2523,7 @@ $1',
 'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] నిరోధించబడింది.<br />
 నిరోధాల సమీక్ష కొరకు [[Special:BlockList|నిరోధాల జాబితా]] చూడండి.',
 'ipb-blockingself' => 'మిమ్మల్ని మీరే నిరోధించుకోబోతున్నారు! అదే మీ నిశ్చయమా?',
+'ipb-confirmaction' => 'మీరు నిజంగానే ఆ పని చెయ్యాలనుకుంటే, కింద ఉన్న "{{int:ipb-confirm}}" ఫీల్డును చెక్ చెయ్యండి.',
 'ipb-edit-dropdown' => 'నిరోధపు కారణాలను మార్చండి',
 'ipb-unblock-addr' => '$1 పై ఉన్న నిరోధాన్ని తొలగించండి',
 'ipb-unblock' => 'వాడుకరి పేరుపై లేదా ఐపీ చిరునామాపై ఉన్న నిరోధాన్ని తొలగించండి',
@@ -2522,7 +2565,8 @@ $1',
 'change-blocklink' => 'నిరోధాన్ని మార్చండి',
 'contribslink' => 'రచనలు',
 'emaillink' => 'ఈ-మెయిలును పంపించు',
-'autoblocker' => 'మీ ఐ.పీ. అడ్రసును "[[User:$1|$1]]" ఇటీవల వాడుట చేత, అది ఆటోమాటిక్‌గా నిరోధించబడినది. $1ను నిరోధించడానికి కారణం: "\'\'\'$2\'\'\'"',
+'autoblocker' => 'మీ ఐ.పీ. అడ్రసును ఇటీవల "[[User:$1|$1]]" వాడటం చేత, అది ఆటోమాటిక్‌గా నిరోధించబడినది. 
+$1 ను నిరోధించడానికి కారణం: "$2"',
 'blocklogpage' => 'నిరోధాల చిట్టా',
 'blocklog-showlog' => 'ఈ వాడుకరిని గతంలో నిరోధించారు.
 మీ సమాచారం కోసం నిరోధపు చిట్టాని క్రింద ఇచ్చాం:',
@@ -2656,6 +2700,7 @@ $1',
 'immobile-target-namespace-iw' => 'పేజీని తరలించడానికి అంతర్వికీ లింకు సరైన లక్ష్యం కాదు.',
 'immobile-source-page' => 'ఈ పేజీని తరలించలేరు.',
 'immobile-target-page' => 'ఆ లక్ష్యిత శీర్షికకి తరలించలేము.',
+'bad-target-model' => 'కోరుకున్న గమ్య స్థానం వేరే కంటెంటు మోడల్‍ను వాడుతోంది. $1 నుండి $2 కు మార్చలేం.',
 'imagenocrossnamespace' => 'ఫైలును, ఫైలుకు చెందని నేమ్‌స్పేసుకు తరలించలేం',
 'nonfile-cannot-move-to-file' => 'దస్త్రాలు కానివాటిని దస్త్రపు పేరుబరికి తరలించలేరు',
 'imagetypemismatch' => 'ఈ కొత్త ఫైలు ఎక్స్&zwnj;టెన్షన్ ఫైలు రకానికి సరిపోలేదు',
@@ -2682,6 +2727,7 @@ $1',
 'exportcuronly' => 'ప్రస్తుత కూర్పు మాత్రమే, పూర్తి చరితం వద్దు',
 'exportnohistory' => "----
 '''గమనిక:''' ఈ ఫారాన్ని ఉపయోగించి పేజీలయొక్క పూర్తి చరిత్రను ఎగుమతి చేయడాన్ని సర్వరుపై వత్తిడి పెరిగిన కారణంగా ప్రస్తుతం నిలిపివేశారు.",
+'exportlistauthors' => 'ప్రతీపేజీలోను చేర్పరుల పూర్తి జాబితాను కూడా ఉంచు',
 'export-submit' => 'ఎగుమతించు',
 'export-addcattext' => 'ఈ వర్గంలోని పేజీలను చేర్చు:',
 'export-addcat' => 'చేర్చు',
@@ -2724,6 +2770,7 @@ $2',
 'thumbnail_image-type' => 'ఈ బొమ్మ రకానికి మద్దతు లేదు',
 'thumbnail_gd-library' => 'అసంపూర్ణ GD సంచయపు ఏర్పాటు: $1 ఫంక్షను లేదు.',
 'thumbnail_image-missing' => 'ఫైలు తప్పిపోయినట్లున్నది: $1',
+'thumbnail_image-failure-limit' => 'ఈ థంబ్‍నెయిల్‍ను రెండరు చెయ్యడానికి చాలా ఎక్కువ విఫలయత్నాలు ($1 లేదా అంతకంటే ఎక్కువ) జరిగాయి. కాస్తాగి మళ్ళీ ప్రయత్నించండి.',
 
 # Special:Import
 'import' => 'పేజీలను దిగుమతి చేసుకోండి',
@@ -2772,6 +2819,7 @@ $2',
 'import-error-invalid' => 'పేజీ "$1" పేరు సరైనది కాదు కాబట్టి దాన్ని దిగుమతి చెయ్యలేదు.',
 'import-options-wrong' => 'తప్పు {{PLURAL:$2|ఐచ్ఛికం|ఐచ్ఛికాలు}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid' => 'ఇచ్చిన మూలపు పేజీ సరైన శీర్షిక కాదు.',
+'import-rootpage-nosubpage' => 'మూలపేజీ యొక్క పేరుబరి "$1" ఉపపేజీలను అనుమతించదు.',
 
 # Import log
 'importlogpage' => 'దిగుమతుల చిట్టా',
@@ -2784,6 +2832,10 @@ $2',
 # JavaScriptTest
 'javascripttest' => 'జావాస్క్రిప్ట్ పరీక్ష',
 'javascripttest-title' => '$1 పరీక్షలు నడుస్తున్నాయి',
+'javascripttest-pagetext-noframework' => 'ఈ పేజీ JavaScript పరీక్షల కోసం ఉద్దేశించబడింది.',
+'javascripttest-pagetext-unknownframework' => 'తెలియని పరీక్షా ఫ్రేమ్‍వర్కు "$1".',
+'javascripttest-pagetext-frameworks' => 'కింది పరీక్షా ఫ్రేమ్‍వర్కులలో ఒకదాన్ని ఎంచుకోండి: $1',
+'javascripttest-qunit-intro' => 'mediawiki.org లోని [$1 పరీక్షా డాక్యుమెంటేషన్] చూడండి.',
 
 # Tooltip help for the actions
 'tooltip-pt-userpage' => 'మీ వాడుకరి పేజీ',
@@ -2877,6 +2929,9 @@ $2',
 'spambot_username' => 'మీడియావికీ స్పాము శుద్ధి',
 'spam_reverting' => '$1 కు లింకులు లేని గత కూర్పుకు తిరిగి తీసుకెళ్తున్నాం',
 'spam_blanking' => '$1 కు లింకులు ఉన్న కూర్పులన్నిటినీ ఖాళీ చేస్తున్నాం',
+'spam_deleting' => '$1 కు లింకులున్న కూర్పులను తొలగిస్తున్నాం',
+'simpleantispam-label' => 'యాంటీ స్పామ్ పరీక్ష.
+దీన్ని <strong>పూరించకండి</strong>!',
 
 # Info page
 'pageinfo-title' => '"$1" గురించి సమాచారం',
@@ -2889,6 +2944,8 @@ $2',
 'pageinfo-length' => 'పేజీ నిడివి (బైట్లలో)',
 'pageinfo-article-id' => 'పేజీ ఐడీ',
 'pageinfo-language' => 'పేజీ విషయపు భాష',
+'pageinfo-content-model' => 'పేజీ కంటెంటు మోడల్',
+'pageinfo-robot-policy' => 'రోబోట్లచే ఇండెక్సవుతోంది',
 'pageinfo-robot-index' => 'అనుమతించబడింది',
 'pageinfo-robot-noindex' => 'అనుమతించబడలేదు',
 'pageinfo-views' => 'వీక్షణల సంఖ్య',
@@ -2902,7 +2959,9 @@ $2',
 'pageinfo-lastuser' => 'ఇట్టీవలి మార్పుచేర్పుల కర్త',
 'pageinfo-lasttime' => 'చివరిసారిగా మార్పు చేసిన తేదీ',
 'pageinfo-edits' => 'మొత్తం మార్పుల సంఖ్య',
+'pageinfo-authors' => 'ప్రత్యేక కర్తల మొత్తం సంఖ్య',
 'pageinfo-recent-edits' => 'ఇటీవలి మార్పుల సంఖ్య (గత $1 లోపు)',
+'pageinfo-recent-authors' => 'ప్రత్యేక కర్తల ఇటీవలి సంఖ్య',
 'pageinfo-magic-words' => 'చమత్కార {{PLURAL:$1|పదం|పదాలు}} ($1)',
 'pageinfo-hidden-categories' => 'దాచిన {{PLURAL:$1|వర్గం|వర్గాలు}} ($1)',
 'pageinfo-templates' => 'ట్రాన్స్‍క్లూడు చేసిన {{PLURAL:$1|మూస|మూసలు}} ($1)',
@@ -3370,6 +3429,8 @@ $1',
 'exif-gpsdirection-t' => 'వాస్తవ దిశ',
 'exif-gpsdirection-m' => 'అయస్కాంత దిశ',
 
+'exif-ycbcrpositioning-1' => 'మధ్యగతం చేయబడిన',
+
 'exif-dc-contributor' => 'సహాయకులు',
 'exif-dc-date' => 'తేదీ‍‍(లు)',
 'exif-dc-publisher' => 'ప్రచురణకర్త',
@@ -3759,6 +3820,7 @@ $5
 
 # Search suggestions
 'searchsuggest-search' => 'వెతుకు',
+'searchsuggest-containing' => 'కలిగియున్న...',
 
 # API errors
 'api-error-badaccess-groups' => 'ఈ వికీ లోనికి దస్త్రాలను ఎక్కించే అనుమతి మీకు లేదు.',
@@ -3783,6 +3845,7 @@ $5
 'api-error-illegal-filename' => 'ఆ పైల్ పేరు అనుమతించబడదు.',
 'api-error-internal-error' => 'అంతర్గత లోపం: ఈ వికీలో మీ ఎక్కింపును ప్రాసెసు చెయ్యడంలో ఎదో తప్పు జరిగింది.',
 'api-error-invalid-file-key' => 'అంతర్గత దోషము: తాత్కాలిక నిల్వలో ఫైల్ కనపడలేదు.',
+'api-error-missingparam' => 'అంతర్గత దోషం: అభ్యర్ధనలో పరామితులు అన్నీ లేవు.',
 'api-error-mustbeloggedin' => 'దస్త్రాలను ఎక్కించడానికి మీరు ప్రవేశించివుండాలి.',
 'api-error-noimageinfo' => 'ఎక్కింపు జయప్రదమైంది. కానీ సర్వరు, ఆ ఫైలు గురించిన సమాచారమేమీ ఇవ్వలేదు.',
 'api-error-nomodule' => 'అంతర్గత దోషము: ఎక్కింపు పర్వికము అమర్చబడలేదు.',
@@ -3837,4 +3900,6 @@ $5
 'expand_templates_generate_rawhtml' => 'ముడి HTML ను చూపించు',
 'expand_templates_preview' => 'మునుజూపు',
 
+# Unknown messages
+'uploadinvalidxml' => 'ఎక్కించిన ఫైలులోని XML ను పార్సు చెయ్యలేకపోయాం.',
 );
index e72795d..a6f20b3 100644 (file)
@@ -46,6 +46,7 @@
  * @author Nemo bis
  * @author Rapsar
  * @author Reedy
+ * @author Rhinestorm
  * @author Runningfridgesrule
  * @author Sadrettin
  * @author Srhat
@@ -368,8 +369,8 @@ $messages = array(
 'tog-editsectiononrightclick' => 'Bölüm başlığına sağ tıklayarak bölümleri düzenleyebilme olanağı ver',
 'tog-rememberpassword' => 'Girişimi bu tarayıcıda hatırla (en fazla $1 {{PLURAL:$1|gün|gün}} için)',
 'tog-watchcreations' => 'Açtığım sayfaları ve yüklediğim dosyaları izleme listeme ekle',
-'tog-watchdefault' => 'Düzenleme yaptığım sayfaları izleme listeme ekle',
-'tog-watchmoves' => 'Taşıdığım sayfaları izleme listeme ekle',
+'tog-watchdefault' => 'Düzenleme yaptığım sayfaları ve dosyaları izleme listeme ekle',
+'tog-watchmoves' => 'Taşıdığım sayfaları ve dosyaları izleme listeme ekle',
 'tog-watchdeletion' => 'Sildiğim sayfaları ve dosyaları izleme listeme ekle',
 'tog-minordefault' => 'Varsayılan olarak bütün düzenlemeleri küçük olarak işaretle',
 'tog-previewontop' => 'Ön izlemeyi düzenleme kutusunun üstünde göster',
@@ -519,7 +520,6 @@ $messages = array(
 'vector-action-protect' => 'Koru',
 'vector-action-undelete' => 'Silinmeyi geri al',
 'vector-action-unprotect' => 'Korumayı değiştir',
-'vector-simplesearch-preference' => 'Gelişmiş arama önerilerini etkinleştir (Sadece Vector görünümü için)',
 'vector-view-create' => 'Oluştur',
 'vector-view-edit' => 'Düzenle',
 'vector-view-history' => 'Geçmişi gör',
@@ -529,7 +529,7 @@ $messages = array(
 'namespaces' => 'Ad alanları',
 'variants' => 'Türevler',
 
-'navigation-heading' => 'Dolaşım menüsü',
+'navigation-heading' => 'Gezinti menüsü',
 'errorpagetitle' => 'Hata',
 'returnto' => '$1 sayfasına geri dön.',
 'tagline' => '{{SITENAME}} sitesinden',
@@ -1217,6 +1217,7 @@ Bu değişkenler atlandı.",
 'undo-success' => 'Bu değişiklik geri alınabilir. Lütfen aşağıdaki karşılaştırmayı kontrol edin, gerçekten bu değişikliği yapmak istediğinizden emin olun ve sayfayı kaydederek bir önceki değişikliği geriye alın.',
 'undo-failure' => 'Değişikliklerin çakışması nedeniyle geri alma işlemi başarısız oldu.',
 'undo-norev' => 'Değişiklik geri alınamaz çünkü ya silinmiş ya da varolmamaktadır.',
+'undo-nochange' => 'Düzeltme zaten geri alınmış.',
 'undo-summary' => '$1 değişikliği [[Special:Contributions/$2|$2]] ([[User talk:$2|mesaj]]) tarafından geri alındı.',
 'undo-summary-username-hidden' => 'Gizli bir kullanıcı tarafından $1 sürümü geri alınıyor',
 
@@ -1444,6 +1445,7 @@ Ayrıntılar [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} silme g
 'searchrelated' => 'ilgili',
 'searchall' => 'hepsi',
 'showingresults' => "$2. sonuçtan başlayarak {{PLURAL:$1|'''1''' sonuç |'''$1''' sonuç }} aşağıdadır:",
+'showingresultsinrange' => '<strong>$2</strong> ile <strong>$3</strong> arasında toplam <strong>$1</strong> sonuç gösteriliyor.',
 'showingresultsnum' => "'''$2''' sonuçtan başlayarak {{PLURAL:$3|'''1''' sonuç|'''$3''' sonuç}} aşağıdadır:",
 'showingresultsheader' => "'''$4''' için {{PLURAL:$5|'''$3''' sonuçtan '''$1'''i|'''$1 - $2''' arası '''$3''' sonuç}}",
 'search-nonefound' => 'Sorguyla eşleşen bir sonuç yok.',
@@ -3061,7 +3063,7 @@ Dosyanın sadece bir kısmı yüklendi.',
 Geçici dosya kayıp.',
 'import-parse-failure' => 'XML içeri aktarma derlemesi başarısız',
 'import-noarticle' => 'İçe aktarılacak sayfa yok!',
-'import-nonewrevisions' => 'Tüm revizyonlar önceden içe aktarılmış.',
+'import-nonewrevisions' => 'Hiçbir revizyon içe aktarılmadı (zaten hepsi vardı ya da hatadan dolayı atlandı).',
 'xml-error-string' => '$2 satırında, $3 sütununda $1 (bayt $4): $5',
 'import-upload' => 'XML bilgileri yükle',
 'import-token-mismatch' => 'Oturum verisi kaybı. Lütfen yeniden deneyin.',
index 5900d22..6537cb5 100644 (file)
@@ -14,6 +14,7 @@
  * @author Reedy
  * @author Sahran
  * @author Tel'et
+ * @author بىلگە
  */
 
 $rtl = true;
@@ -212,7 +213,6 @@ $messages = array(
 'vector-action-protect' => 'قوغدا',
 'vector-action-undelete' => 'ئەسلىگە قايتۇر',
 'vector-action-unprotect' => 'قوغداش ئۆزگەرت',
-'vector-simplesearch-preference' => 'ئاددىي ئىزدەش ئىستون ئاچ (پەقەت ۋېكتور قېلىپ)',
 'vector-view-create' => 'قۇر',
 'vector-view-edit' => 'تەھرىر',
 'vector-view-history' => 'تارىخ كۆرسەت',
@@ -643,6 +643,8 @@ $1 ساقلاپ، ئاندىن قايتا سىناڭ.',
 'retypenew' => 'يېڭى پارولنى قايتا كىرگۈزۈڭ:',
 'resetpass_submit' => 'پارول بەلگىلەپ تىزىمغا كىرىڭ',
 'changepassword-success' => 'پارولىڭىز ئوڭۇشلۇق ئۆزگەرتىلدى!',
+'changepassword-throttled' => 'سىز بۇ ھېساباتتا تىزىمغا كىرىشنى كۆپ قېتىم سىنىدىڭىز.
+$1 ساقلاپ، ئاندىن قايتا سىناڭ.',
 'resetpass_forbidden' => 'پارولنى ئۆزگەرتەلمىدى',
 'resetpass-no-info' => 'سىز تىزىمغا كىرگەندىن كېيىن بىۋاسىتە بۇ بەتكە كىرىشىڭىز لازىم.',
 'resetpass-submit-loggedin' => 'پارولنى ئۆزگەرتىش',
@@ -698,9 +700,14 @@ $2
 'changeemail-password' => '{{SITENAME}} دىكى پارولىڭىز:',
 'changeemail-submit' => 'ئېلخەت ئۆزگەرت',
 'changeemail-cancel' => 'ۋاز كەچ',
+'changeemail-throttled' => 'سىز بۇ ھېساباتتا تىزىمغا كىرىشنى كۆپ قېتىم سىنىدىڭىز.
+$1 ساقلاپ، ئاندىن قايتا سىناڭ.',
 
 # Special:ResetTokens
 'resettokens' => 'ئاچقۇچلۇق بەلگىلەرنى قايتا بېكىتمەك',
+'resettokens-text' => 'سىز بۇ يەردە سىزنىڭ ھىساۋاتىڭىزگە مۇناسۋەتلىك شەخسى ئۇچۇر مەخپىيەتلىكىنى قايتا كۆرەلەيسىز.
+
+ئۇ ئۇچۇرلار ھەمبەھرلىنىپ كەتسە ياكى باشقىلار ئىشلىتۋالغان بولسا، ئۇ ئۇچۇرلارنى ئەسلىگە قايتۇرۇڭ.',
 'resettokens-no-tokens' => 'قايتا بېكىتىدىغان ھېچقانداق ئاچقۇچلۇق بەلگە يوق.',
 'resettokens-legend' => 'ئاچقۇچلۇق بەلگىلەرنى قايتا بېكىتمەك',
 'resettokens-tokens' => 'ئاچقۇچلۇق بەلگىلەر:',
@@ -923,6 +930,8 @@ $2
 'content-not-allowed-here' => '[[$2]] بەتتە "$1" مەزمۇنغا يول قويۇلمايدۇ',
 'editwarning-warning' => 'بەتتىن ئايرىلغاندا بەلكىم بارلىق تەھرىرلىگىنىڭىز بېكار بولۇپ كېتىشى مۇمكىن.
 ئ‍ەگەر تىزىمغا كىرسىڭىز، مايىللىق بېتىڭىزنىڭ «{{int:prefs-editing}}» بۆلىكىدە، بۇ ئەسكەرتمىنى ئىناۋەتسىز قىلالايسىز.',
+'editpage-notsupportedcontentformat-title' => 'مەزمۇن ئەندىزىسىنى قوللىمىدى.',
+'editpage-notsupportedcontentformat-text' => 'مەزمۇن قېلىپى $2 نى مەزمۇن ئەندىزىسى $1 نى قوللىمىدى.',
 
 # Content models
 'content-model-wikitext' => 'ۋىكىتېكىست',
@@ -957,6 +966,7 @@ $2
 تۆۋەندىكى سېلىشتۇرۇشنى تەكشۈرۈپ بۇنىڭ ئۆزىڭىزنىڭ ئويى ئىكەنلىكىنى دەلىللەڭ، ئاندىن تۆۋەندىكى ئۆزگەرتىشنى ساقلاپ تەھرىرلەشتىن يېنىۋىلىڭ.',
 'undo-failure' => 'ئوتتۇرىلىقتا بىردەك بولماسلىق سەۋەبىدىن بۇ تەھرىردىن يېنىۋالغىلى بولمايدۇ.',
 'undo-norev' => 'تۈزىتىلگەن نەشرى مەۋجۇد ئەمەس ياكى ئۆچۈرۈلگەنلىكتىن، بۇ تەھرىردىن يېنىۋالغىلى بولمايدۇ.',
+'undo-nochange' => 'بۇ قېتىملىق تەھرىرلەش ۋاز كېچىلدى.',
 'undo-summary' => '[[Special:Contributions/$2|$2]] ([[User talk:$2|مۇنازىرە]]) ئېلىپ بارغان تۈزىتىش $1',
 'undo-summary-username-hidden' => 'بىر يوشۇرۇن ئىشلەتكۈچى تەرىپىدىن يېنىۋېلىندى $1.',
 
@@ -1044,7 +1054,7 @@ $3 تەمىنلىگەن چەكلەش سەۋەبى ''$2''",
 'revdelete-confirm' => 'بۇ مەشغۇلاتنى ئىجرا قىلسىڭىز ئاقىۋىتىنى چۈشىنىدىغانلىقىڭىزنى ھەمدە بۇ پروگراممىنىڭ [[{{MediaWiki:Policy-url}}|سىياسەت]]كە ئۇيغۇن كېلىدىغانلىقىنى جەزملەڭ.',
 'revdelete-suppress-text' => "'''پەقەت''' تۆۋەندىكى ئەھۋاللار يۈز بەرگەندىلا زىيارەت چەكلىنىدۇ:
 * نامۇۋاپىق شەخسىي ئۇچۇر
-*: ''home ئولتۇرۇشلۇق ئادرېس، تېلېفون نومۇر، كىملىك نومۇرى قاتارلىق.''",
+*: ''ئولتۇرۇشلۇق ئادرېس، تېلېفون نومۇر، كىملىك نومۇرى قاتارلىق.''",
 'revdelete-legend' => 'كۆرۈنۈشچانلىق چەكلىمە تەڭشىكى',
 'revdelete-hide-text' => 'تۈزىتىلگەن تېكىست',
 'revdelete-hide-image' => 'ھۆججەت مەزمۇنىنى يوشۇر',
@@ -1133,6 +1143,7 @@ $1",
 'compareselectedversions' => 'تاللانغان نەشرىنى سېلىشتۇر',
 'showhideselectedversions' => 'تاللانغان تۈزىتىلگەن نەشرىنى كۆرسەت/يوشۇر',
 'editundo' => 'يېنىۋال',
+'diff-empty' => '(پەرقى يوق)',
 'diff-multi-manyusers' => '( $2  دىن كۆپ{{PLURAL:$2|ئىشلەتكۈچى|ئىشلەتكۈچى}} نىڭ {{PLURAL:$1|تۈزىتىلگەن نەشرى|$1 تۈزىتىلگەن نەشرى}}  كۆرسىتىلمىدى)',
 'difference-missing-revision' => '{{PLURAL:$2|نەشر|$2 نەشىر لەر}} نىڭ ($1) پەرق سېلىشتۇرما {{PLURAL:$2}} تېپىلمىدى.
 
@@ -1169,6 +1180,7 @@ $1",
 'search-result-score' => 'باغلىنىشچانلىق: $1%',
 'search-redirect' => '($1 قايتا نىشانلا)',
 'search-section' => '(ئابزاس $1)',
+'search-file-match' => '(ھۆججەت مەزمۇنى ماس كەلگەن)',
 'search-suggest' => 'ئىزدىمەكچى بولغىنىڭىز: $1',
 'search-interwiki-caption' => 'ھەمشىرە قۇرۇلۇشلار',
 'search-interwiki-default' => '$1 نەتىجە:',
@@ -1309,6 +1321,7 @@ HTML بەلگىسىنى تەكشۈرۈڭ.',
 'prefs-displaywatchlist' => 'كۆرسىتىش تاللانما',
 'prefs-tokenwatchlist' => 'ئاچقۇچ',
 'prefs-diffs' => 'پەرقلەر',
+'prefs-help-prefershttps' => 'بۇ سەپلەك، سىز قايتا تىزىمغا كىرگەندە ئىشلەيدۇ.',
 
 # User preference: email validation using jQuery
 'email-address-validity-valid' => 'ئېلخەت ئادرېسى ئىناۋەتلىك',
@@ -3949,8 +3962,15 @@ MediaWiki ئىشلىتىش مەقسىتىنى ئاساس قىلىپ ئېلان 
 'limitreport-walltime-value' => '$1 {{PLURAL:$1|سېكۇنت}}',
 
 # Special:ExpandTemplates
+'expand_templates_input' => 'مەزمۇن كىرگۈزۈڭ:',
 'expand_templates_output' => 'نەتىجە',
+'expand_templates_xml_output' => 'XML چىقار',
+'expand_templates_html_output' => 'ئەسلى HTML چىقار',
 'expand_templates_ok' => 'جەزملە',
+'expand_templates_remove_comments' => 'ئىزاھاتنى ئۆچۈر',
+'expand_templates_remove_nowiki' => 'نەتىجىسىدە <nowiki> خەتكۈچ كۆرۈنمىسۇن',
+'expand_templates_generate_xml' => 'XML گىرامماتىكىسىنى كۆرسەت',
+'expand_templates_generate_rawhtml' => 'ئەسلى HTML نى كۆرسەت',
 'expand_templates_preview' => 'ئالدىن كۆزەت',
 
 );
index d647342..5eb04b6 100644 (file)
@@ -531,7 +531,6 @@ $messages = array(
 'vector-action-protect' => 'Захистити',
 'vector-action-undelete' => 'Відновити',
 'vector-action-unprotect' => 'Зміна захисту',
-'vector-simplesearch-preference' => 'Увімкнути спрощене поле пошуку (лише для оформлення "Векторне")',
 'vector-view-create' => 'Створити',
 'vector-view-edit' => 'Редагувати',
 'vector-view-history' => 'Переглянути історію',
@@ -2315,6 +2314,14 @@ $1',
 'protectedpages-cascade' => 'Тільки каскадний захист',
 'protectedpages-noredirect' => 'Сховати перенаправлення',
 'protectedpagesempty' => 'Зараз нема захищених сторінок із зазначеними параметрами',
+'protectedpages-timestamp' => 'Часова мітка',
+'protectedpages-page' => 'Сторінка',
+'protectedpages-expiry' => 'Закінчується',
+'protectedpages-performer' => 'Захист користувача',
+'protectedpages-params' => 'Параметри захисту',
+'protectedpages-reason' => 'Причина',
+'protectedpages-unknown-timestamp' => 'Невідомо',
+'protectedpages-unknown-performer' => 'Невідомий користувач',
 'protectedtitles' => 'Заборонені назви',
 'protectedtitlesempty' => 'Зараз нема захищених назв із зазначеними параметрами.',
 'listusers' => 'Список користувачів',
@@ -3076,6 +3083,7 @@ $2',
 'thumbnail_image-type' => 'Тип зображення не підтримується',
 'thumbnail_gd-library' => 'Неповна конфігурація бібліотеки GD, відсутня функція $1',
 'thumbnail_image-missing' => 'Очевидно, відсутній файл $1',
+'thumbnail_image-failure-limit' => 'Там було дуже багато недавніх невдалих спроб ($1 або більше) для візуалізації цього ескізу. Будь ласка, спробуйте ще раз пізніше.',
 
 # Special:Import
 'import' => 'Імпорт статей',
index 04e1173..1d4ef60 100644 (file)
@@ -501,7 +501,6 @@ $messages = array(
 'vector-action-protect' => 'Khóa',
 'vector-action-undelete' => 'Phục hồi',
 'vector-action-unprotect' => 'Đổi mức khóa',
-'vector-simplesearch-preference' => 'Hộp tìm kiếm đơn giản (cần bề ngoài Vectơ)',
 'vector-view-create' => 'Tạo',
 'vector-view-edit' => 'Sửa đổi',
 'vector-view-history' => 'Xem lịch sử',
@@ -1422,7 +1421,7 @@ Xem chi tiết trong [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}}
 'showingresults' => "Dưới đây là {{PLURAL:$1|'''1'''|'''$1'''}} kết quả bắt đầu từ #'''$2'''.",
 'showingresultsinrange' => 'Dưới đây là cho tới <strong>$1</strong> kết quả từ #<strong>$2</strong> đến #<strong>$3</strong>.',
 'showingresultsnum' => "Dưới đây là {{PLURAL:$3|'''1'''|'''$3'''}} kết quả bắt đầu từ #'''$2'''.",
-'showingresultsheader' => "{{PLURAL:$5|Kết quả thứ '''$1''' trong tổng số '''$3''' kết quả|Kết quả từ '''$1 - $2''' trong tổng số '''$3''' kết quả}} cho '''$4'''",
+'showingresultsheader' => "{{PLURAL:$5|Kết quả thứ '''$1''' trong tổng số '''$3''' kết quả|Các kết quả '''$1–$2''' trong tổng số '''$3''' kết quả}} cho '''$4'''",
 'search-nonefound' => 'Không có kết quả nào khớp với câu truy vấn.',
 'powersearch-legend' => 'Tìm kiếm nâng cao',
 'powersearch-ns' => 'Tìm trong không gian tên:',
index 545f9d9..a0df6fd 100644 (file)
@@ -226,7 +226,6 @@ $messages = array(
 'vector-action-protect' => 'Panalipda',
 'vector-action-undelete' => 'Igbalik an ginpara',
 'vector-action-unprotect' => 'Liwani an panalipod',
-'vector-simplesearch-preference' => 'Ginpadulot an yinano nga pamiling nga kahon (Panit vector la)',
 'vector-view-create' => 'Himo-a',
 'vector-view-edit' => 'Igliwat',
 'vector-view-history' => 'Kitaa an kaagi',
@@ -269,8 +268,8 @@ $messages = array(
 'newpage' => 'Bag-o nga pakli',
 'talkpage' => 'Pakighimangraw hiunong hini nga pakli',
 'talkpagelinktext' => 'Hiruhimangraw',
-'specialpage' => 'Ispisyal nga Pakli',
-'personaltools' => 'Mga pankalugaring nga garamiton',
+'specialpage' => 'Pinaurog nga pakli',
+'personaltools' => 'Mga pankalugaringon nga garamiton',
 'postcomment' => 'Bag-o nga bahin',
 'articlepage' => 'Kitaa in may sulod nga pakli',
 'talk' => 'Hiruhimangraw',
@@ -278,7 +277,7 @@ $messages = array(
 'toolbox' => 'Mga higamit',
 'userpage' => 'Kitaa in pakli hin gumaramit',
 'projectpage' => 'Kitaa in pakli hin proyekto',
-'imagepage' => 'Kitaa in pakli hin fayl',
+'imagepage' => 'Kitaa in pakli hin paypay',
 'mediawikipage' => 'Kitaa in pakli hin mensahe',
 'templatepage' => 'Kitaa in pakli hin plantilya',
 'viewhelppage' => 'Kitaa in pakli hin bulig',
@@ -655,7 +654,12 @@ Imo malinamposon nga ginsalyuan an imo tigaman-panakob o umaro ka na hin bag-o n
 'passwordreset-capture-help' => 'Kun imo igtsek ini nga kahon, an email (lakip an temporaryo nga tigaman-panakob) in igpapakita ha imo labot la han ginpadangat ha gumaramit.',
 'passwordreset-email' => 'E-mail adres:',
 'passwordreset-emailtitle' => 'Mga detalye han akawnt ha {{SITENAME}}',
-'passwordreset-emailtext-ip' => '{{PLURAL:$3|Iní nga temporaryo nga tigaman-pansulod|Iní nga mga temporaryo nga tigaman-pansulod}} ma-waray bali hin {{PLURAL:$5|usa ka adlaw|$5 nga mga adlaw}}.',
+'passwordreset-emailtext-ip' => 'Mayda gumaramit (bangin hi ikaw, tikang han IP adres nga $1) nga naghangyo hin reset han imo tigaman-pansulod han {{SITENAME}} ($4). An nasunod nga gumaramit {{PLURAL:$3|nga akawnt|nga mga akawnt}} nahanungod hini nga email nga adres: 
+
+$2
+
+{{PLURAL:$3|Iní nga temporaryo nga tigaman-pansulod|Iní nga mga temporaryo nga tigaman-pansulod}} ma-waray bali hin {{PLURAL:$5|usa ka adlaw|$5 nga mga adlaw}}.
+Angay ka sumakob ngan pumílì hin bag-o nga tigaman-pansulod ha yanâ.  Kun mayda lain nga naghatag hini nga hangyo, o kun nahinumdoman mo an imo orihinal nga tigaman-pansulod, ngan nadírì ka na pagbalyo hiní, puyde mo pasagdan ini nga sumat ngan magpadayon hin paggamit han imo daan nga tigaman-pansulod.',
 'passwordreset-emailelement' => 'Agnay han gumaramit: $1
 Temporaryo nga tigaman han pagsakob: $2',
 'passwordreset-emailsent' => 'Ginpadangat an password reset email.',
@@ -673,6 +677,7 @@ Temporaryo nga tigaman han pagsakob: $2',
 'changeemail-password' => 'An imo {{SITENAME}} password:',
 'changeemail-submit' => 'Igbalyo an e-mail',
 'changeemail-cancel' => 'Pasagdi',
+'changeemail-throttled' => 'Nakadamo kada pag-log-in. Alayon paghulat hin $1 ugsa ka umutro.',
 
 # Special:ResetTokens
 'resettokens' => 'Igrest an mga token',
@@ -788,6 +793,7 @@ An pinakaurhi nga log entry han mga pinugong in ginhatag ha ubos para hit repere
 'previewnote' => "'''Hinumdumi nga pahiuna-nga-paggawas pa la ini.'''
 ¡Waray pa katipig an imo mga ginbag-o!",
 'continue-editing' => 'Pakadto han lugar hin panliwat',
+'edit_form_incomplete' => '<strong>An iba nga parte han imo pagliwat nga porma in waray umabot ha serbidor; alayon kitaa utro kun an imo mga pagliwat in aada pa ngan utroha pa.</strong>',
 'editing' => 'Ginliliwat an $1',
 'creating' => 'Ginhihimo an $1',
 'editingsection' => 'Ginliliwat an $1 (bahin)',
@@ -795,10 +801,16 @@ An pinakaurhi nga log entry han mga pinugong in ginhatag ha ubos para hit repere
 'editconflict' => 'Diri pagkakauroyon han pagliwat: $1',
 'yourtext' => 'Imo sinurat',
 'storedversion' => 'Nakahipos nga pagbag-o',
+'editingold' => '<strong>Pahimatngon: Imo ginliliwat an daan nga rebisyon hini nga pakli.</strong>
+Kun imo ini igtipig, an bisan ano nga mga pagliwat nga ginhimo tikang hini nga rebisyon in mawawara.',
 'yourdiff' => 'Mga kaibhan',
 'copyrightwarning' => "Iginpapasabot nga an ngatanan nga imo gin-amot ha {{SITENAME}} iginhatag mo ha ilarom han $2 (kitaa an $1 para han mga detalye).  Kun diri mo igkakalipay nga an imo ginsurat waray kalooy nga liliwaton ngan igpapakalat hit bisan hin-o nga it may gusto, alayon ayaw hiton igsumitir dinhi. <br />
 Nasaad ka liwat nga imo ini kalugaringon nga ginsurat, o ginkopya nimo ini tikang ha panimongto nga dominyo o kapareho nga waray-sabit nga kuruhaon.
 '''Ayaw igsumitir an mga buhat nga may ''copyright'' hin waray sarit!'''",
+'copyrightwarning2' => 'Alayon kasabot nga an ngatanan nga mga kontribusyon ha {{SITENAME}} in puydi liwaton, saliwanon, o tanggalon hin bisan hin-o nga karuyag magbuhat.
+Kun diri mo karuyag nga an imo sinurat in maliliwat la hin waray kalooy, ayaw gud igsumite dinhi.<br />
+Nasaad ka gihap nga ikaw mismo an nagsurat hini, o ginkopya mo ini ha dominyo publiko o kaparehas nga talwas nga ginkuhaan (kitaa an $1 para hin mga detalye).
+<strong>Ayaw igsumite an mga buhat nga naka-copywrite nga waray pagtugot!</strong>',
 'templatesused' => '{{PLURAL:$1|Batakan|Mga batakan}} nga gingamit dinhi nga pakli:',
 'template-protected' => '(pinaliporan)',
 'template-semiprotected' => '(katunga nga pinasaliporan)',
@@ -806,7 +818,7 @@ Nasaad ka liwat nga imo ini kalugaringon nga ginsurat, o ginkopya nimo ini tikan
 'nocreate-loggedin' => 'Diri ka gintutugotan paghimo hin mga bag-o nga pakli.',
 'sectioneditnotsupported-title' => 'Diri suportado han pagliwat han seksyon',
 'sectioneditnotsupported-text' => 'Diri suportado an pagliwat han seksyon ha dinhi nga pakli.',
-'permissionserrors' => 'Mga sayop hin mga pagtugot',
+'permissionserrors' => 'Sayop hin pagtugot',
 'permissionserrorstext' => 'Diri ka gintutugotan pagbuhat hito, mahitungod han mga nasunod nga {{PLURAL:$1|katadungan|mga katadungan}}:',
 'permissionserrorstext-withaction' => 'Waray ka permiso han $2, tungod han masunod nga {{PLURAL:$1|rason|mga rason}}:',
 'recreate-moveddeleted-warn' => "'''Pahimatngon: Naghihimo ka hin pakli nga ginpara na.'''
@@ -894,13 +906,13 @@ An mga detalye in mabibilngan ha [{{fullurl:{{#Special:Log}}/delete|page={{FULLP
 'revisiondelete' => 'Pagpara/pagtanggal han pagpara nga mga rebisyon',
 'revdelete-show-file-confirm' => 'Sigurado ka nga gusto mo makita an ginpara nga pagliwat han file "<nowiki>$1</nowiki>" tikang $2 ha $3?',
 'revdelete-show-file-submit' => 'Oo',
-'revdelete-hide-text' => 'Tagoon an rebisyon han teksto',
+'revdelete-hide-text' => 'Rebisyon nga sinurat',
 'revdelete-hide-image' => 'Tagoon an sulod han paypay',
 'revdelete-hide-name' => 'Tagoon an buhat ngan kakadtoan',
-'revdelete-hide-comment' => 'Tagoon an dalikyat nga sumat han pagliwat',
+'revdelete-hide-comment' => 'Dalikyat nga sumat hin pagliwat',
 'revdelete-radio-same' => '(ayaw balyu-e)',
-'revdelete-radio-set' => 'Oo',
-'revdelete-radio-unset' => 'Ayaw',
+'revdelete-radio-set' => 'Tinago',
+'revdelete-radio-unset' => 'Nakikit-an',
 'revdelete-log' => 'Rason:',
 'revdel-restore' => 'igliwat an nakikit-an',
 'pagehist' => 'Kaagi han pakli',
@@ -1084,7 +1096,7 @@ An imo e-mail address in diri makikit-an kun an iba nga mga gumaramit in makonta
 'prefs-i18n' => 'Internasyonalisasyon',
 'prefs-signature' => 'Pirma',
 'prefs-dateformat' => 'Batakan han petsa',
-'prefs-advancedediting' => 'Abansado nga mga pagpipilian',
+'prefs-advancedediting' => 'Mga kasahiran nga pagpipilian',
 'prefs-preview' => 'Pahiuna nga pakita',
 'prefs-advancedrc' => 'Abansado nga mga pagpipilian',
 'prefs-advancedrendering' => 'Abansado nga mga pagpipilian',
@@ -1156,7 +1168,7 @@ Diri ka gintutugotan pagliwat han mga katungod han gumaramit ha iba nga mga wiki
 'right-reupload' => 'Sapawa an mga aada nga mga paypay',
 'right-reupload-own' => 'Igsapaw an aada yana nga mga paypay nga ginkarga-pasaka nimo mismo',
 'right-upload_by_url' => 'Igkarga paigbaw an mga paypay tikang ha uska URL',
-'right-autoconfirmed' => 'Igliwat an mga semi-pinanpasaliporan nga pakli',
+'right-autoconfirmed' => 'Diri malalalbtan hin IP-nga-nahibasi nga mga rate hin paglimit',
 'right-bot' => 'Igtrato komo uska naglulugaring nga proseso',
 'right-delete' => 'Igpara an mga pakli',
 'right-bigdelete' => 'Igpara an mga pakli nga may-ada dagko nga mga kaagi',
@@ -1211,8 +1223,8 @@ Diri ka gintutugotan pagliwat han mga katungod han gumaramit ha iba nga mga wiki
 'action-suppressionlog' => 'kitaa an kanan hini pribado nga talaan',
 'action-block' => 'Pugnga ini nga gumaramit ha pagliwat',
 'action-protect' => 'igsaliwan an katupngan han pananalipod para hini nga pakli',
-'action-import' => 'ig-angbit ini nga pakli tikang ha iba nga wiki',
-'action-importupload' => 'ig-angbit ini nga pakli tikang ha uska ginkarga-pasaka nga paypay',
+'action-import' => 'ig-angbit hin mga pakli tikang ha iba nga wiki',
+'action-importupload' => 'ig-angbit hin mga pakli pakli tikang ha uska ginkarga-pasaka nga paypay',
 'action-patrol' => 'markahi an kanan iba pagliwat komo nakapatrolya',
 'action-mergehistory' => 'Igtampo an kaagi hini nga pakli',
 'action-userrights' => 'Igliwat an ngatanan nga mga katungod han gumaramit',
@@ -1232,7 +1244,7 @@ Diri ka gintutugotan pagliwat han mga katungod han gumaramit ha iba nga mga wiki
 'rclistfrom' => 'Pakit-a an mga ginbag-ohan tikang han $1',
 'rcshowhideminor' => '$1 gudti nga mga pagliwat',
 'rcshowhidebots' => '$1 mga bot',
-'rcshowhideliu' => '$1 ka rehistrado nga gumaramit',
+'rcshowhideliu' => '$1 an mga rehistrado nga gumaramit',
 'rcshowhideanons' => '$1 waray nagpakilala nga mga gumaramit',
 'rcshowhidepatr' => '$1 mga pinatrolya nga mga paliwat',
 'rcshowhidemine' => '$1 akon mga ginliwat',
@@ -1707,9 +1719,11 @@ Kitaa an $2 para hin talaan han mga gibag-ohi nga mga ginpamara.',
 'deleteotherreason' => 'Lain/dugang nga katadungan:',
 'deletereasonotherlist' => 'Lain nga katadungan',
 'deletereason-dropdown' => "*Agsob nga rason hin pagpara
-** Tugon han manunurat
+** Spam
+** Bandalismo
 ** Pagtalapas ha katungod hin pagtatag-iya (''copyright'')
-** Bandalismo",
+** Tugon han manunurat
+** Utod nga redirek",
 'delete-edit-reasonlist' => 'Igliwat an mga rason han pagpara',
 
 # Rollback
@@ -2059,12 +2073,12 @@ Makikit-an nimo an ginkuhaaan',
 'pageinfo-display-title' => 'Iglatag an titulo',
 'pageinfo-length' => 'Kahilaba han pakli (ha mga byte)',
 'pageinfo-article-id' => 'ID han pakli',
-'pageinfo-robot-policy' => 'Pamilnga an kahimtang han makina',
-'pageinfo-robot-index' => 'Matutudlok',
-'pageinfo-robot-noindex' => 'Diri matutudlok',
+'pageinfo-robot-policy' => 'Pag-index hin mga robot',
+'pageinfo-robot-index' => 'Gintutugot',
+'pageinfo-robot-noindex' => 'Dírì gintutugot',
 'pageinfo-views' => 'Ihap han mga naglantaw',
 'pageinfo-watchers' => 'Ihap han nangingita hin pakli',
-'pageinfo-redirects-name' => 'Nairedirekta ha dinhi nga pakli',
+'pageinfo-redirects-name' => 'Ihap hin mga redirek ngani nga pakli',
 'pageinfo-subpages-name' => 'Mga bahinpakli hin nga pakli',
 'pageinfo-subpages-value' => '$1 ($2 {{PLURAL:$2|redirekta|mga redirekta}}; $3 {{PLURAL:$3|diri redirekta|mga diri redirekta}})',
 'pageinfo-firstuser' => 'Naghimo han pakli',
@@ -2217,7 +2231,7 @@ An iba in daan nakatago.
 'exif-cameraownername' => 'Tag-iya han kamera',
 'exif-usageterms' => 'Mga termino hit paggamit',
 
-'exif-copyrighted-false' => 'Dominyo panpubliko',
+'exif-copyrighted-false' => 'Status hin katungod-hin-panag-iya waray mahabutang',
 
 'exif-unknowndate' => 'Waray kasabti an petsa',
 
@@ -2401,7 +2415,7 @@ An iba in daan nakatago.
 'version-hooks' => 'Mga kawil',
 'version-hook-name' => 'Ngaran han kawil',
 'version-version' => '(Bersion $1)',
-'version-license' => 'Lisensya',
+'version-license' => 'MediaWiki nga Lisensya',
 'version-poweredby-credits' => "Ini nga wiki in pinapaandar han '''[https://www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
 'version-poweredby-others' => 'mga iba',
 'version-software-product' => 'Produkto',
@@ -2473,10 +2487,10 @@ An iba in daan nakatago.
 'revdelete-content-hid' => 'sulod nakatago',
 'revdelete-summary-hid' => 'nakatago an dalikyat nga sumat han pagliwat',
 'revdelete-uname-hid' => 'nakatago an agnay-hit-gumaramit',
-'logentry-newusers-newusers' => '$1 in naghimo hin gumaramit nga akawnt',
-'logentry-newusers-create' => '$1 in naghimo hin gumaramit nga akawnt',
-'logentry-newusers-create2' => '$1 in naghimo hin gumaramit nga akawnt $3',
-'logentry-newusers-autocreate' => 'An akawnt nga $1 in lugaring nga nahimo',
+'logentry-newusers-newusers' => 'An gumaramit nga akawnt nga $1 {{GENDER:$2|ginhimo}}',
+'logentry-newusers-create' => 'An gumaramit nga akawnt nga $1 {{GENDER:$2|ginhimo}}',
+'logentry-newusers-create2' => 'An gumaramit nga akawnt nga $3 {{GENDER:$2|ginhimo}} ni $1',
+'logentry-newusers-autocreate' => 'An gumaramit nga akawnt nga $1 in lugaring nga {{GENDER:$2|ginhimo}}',
 'rightsnone' => '(waray)',
 
 # Feedback
index b34e333..ff1e984 100644 (file)
@@ -8,6 +8,7 @@
  * @file
  *
  * @author Anson2812
+ * @author Antonytse
  * @author Horacewai2
  * @author Justincheng12345
  * @author Kaganer
@@ -241,8 +242,8 @@ $messages = array(
 'tog-extendwatchlist' => '展開監視清單去顯示全部更改,唔係淨係最新嘅',
 'tog-usenewrc' => '用強化版最近更改(需要JavaScript)',
 'tog-numberheadings' => '標題自動編號',
-'tog-showtoolbar' => '顯示修改工具列(需要JavaScript)',
-'tog-editondblclick' => '撳兩下改嘢(需要JavaScript)',
+'tog-showtoolbar' => '顯示修改工具列',
+'tog-editondblclick' => '撳兩下改嘢',
 'tog-editsectiononrightclick' => '可以撳右掣更改個別段落(需要JavaScript)',
 'tog-rememberpassword' => '響呢個瀏覽器度記住我嘅登入資料 (最高維持$1{{PLURAL:$1|日|日}})',
 'tog-watchcreations' => '將我開嘅頁加入監視清單',
@@ -257,7 +258,7 @@ $messages = array(
 'tog-enotifminoredits' => '小修改都要電郵通知我',
 'tog-enotifrevealaddr' => '喺電郵通知信上面話畀人聽我嘅電郵地址',
 'tog-shownumberswatching' => '顯示有幾多人監視',
-'tog-oldsig' => '原有簽名嘅預覽:',
+'tog-oldsig' => '現有簽名:',
 'tog-fancysig' => '將簽名以維基字對待(冇自動連結)',
 'tog-uselivepreview' => '用即時預覽(需要JavaScript)(實驗緊)',
 'tog-forceeditsummary' => '我冇入修改註解時通知我',
@@ -337,6 +338,18 @@ $messages = array(
 'oct' => '10月',
 'nov' => '11月',
 'dec' => '12月',
+'january-date' => '1月$1號',
+'february-date' => '2月$1號',
+'march-date' => '3月$1號',
+'april-date' => '4月$1號',
+'may-date' => '5月$1號',
+'june-date' => '6月$1號',
+'july-date' => '7月$1號',
+'august-date' => '8月$1號',
+'september-date' => '9月$1號',
+'october-date' => '10月$1號',
+'november-date' => '11月$1號',
+'december-date' => '12月$1號',
 
 # Categories related messages
 'pagecategories' => '屬於$1類',
@@ -383,7 +396,6 @@ $messages = array(
 'vector-action-protect' => '保護',
 'vector-action-undelete' => '去睇刪除咗嘅頁面',
 'vector-action-unprotect' => '解除保護',
-'vector-simplesearch-preference' => '打開加強搵嘢建議(只限Vector畫面)',
 'vector-view-create' => '建立',
 'vector-view-edit' => '編輯',
 'vector-view-history' => '睇吓歷史',
@@ -486,6 +498,7 @@ $1',
 'ok' => 'OK',
 'retrievedfrom' => '由 "$1" 收',
 'youhavenewmessages' => '你有$1($2)。',
+'newmessageslinkplural' => '新訊息',
 'youhavenewmessagesmulti' => '你響 $1 有新信',
 'editsection' => '編輯',
 'editold' => '編輯',
@@ -612,8 +625,13 @@ $1',
 'gotaccount' => '已經有戶口? $1。',
 'gotaccountlink' => '登入',
 'userlogin-resetlink' => '唔記得簽到資料?',
+'userlogin-resetpassword-link' => '唔記得密碼?',
+'userlogin-createanother' => '開過個戶口',
+'createacct-emailrequired' => '電郵地址',
 'createaccountmail' => '用電郵',
 'createaccountreason' => '原因:',
+'createacct-reason-ph' => '開過個戶口嘅原因',
+'createacct-submit' => '開戶口',
 'badretype' => '你入嘅密碼唔一致。',
 'userexists' => '你入嘅用戶名已經有人用咗,唔該揀過個名啦。',
 'loginerror' => '登入錯誤',
@@ -636,7 +654,7 @@ $1',
 'passwordtooshort' => '你嘅密碼最少要有$1個半形字元。',
 'password-name-match' => '你嘅密碼一定要同你嘅用戶名唔一樣。',
 'password-login-forbidden' => '呢個用戶名同密碼嘅利用係被禁止嘅。',
-'mailmypassword' => '寄個新密碼',
+'mailmypassword' => '重設密碼',
 'passwordremindertitle' => '{{SITENAME}}嘅新臨時密碼',
 'passwordremindertext' => '有人(可能係你,IP 位置 $1)
 請求 {{SITENAME}} 嘅新密碼 ($4)。
@@ -696,7 +714,18 @@ $1',
 
 # Special:PasswordReset
 'passwordreset' => '密碼重設',
-'passwordreset-username' => '用戶名',
+'passwordreset-legend' => '重設密碼',
+'passwordreset-username' => '用戶名:',
+'passwordreset-domain' => '域名:',
+'passwordreset-email' => '電郵地址:',
+'passwordreset-emailelement' => '用戶名:$1
+臨時密碼:$2',
+
+# Special:ChangeEmail
+'changeemail' => '改電郵地址',
+'changeemail-submit' => '轉電郵',
+'changeemail-cancel' => '取消',
+'changeemail-throttled' => '你試咗登入太多次,請喺$1後再試過。',
 
 # Edit page toolbar
 'bold_sample' => '粗體字',
@@ -806,6 +835,7 @@ $1',
 'note' => "'''留意:'''",
 'previewnote' => "'''請記住呢個只係預覽。'''
 更改嘅内容重未儲存!",
+'continue-editing' => '去編輯區',
 'previewconflict' => '呢個預覽係反映如果你選擇儲存嘅話,嘅上面嘅文字編輯區裏面嘅字會儲存落嚟。',
 'session_fail_preview' => "'''對唔住!由於小節嘅資料唔見咗,我哋唔能夠處理你嘅編輯。'''
 請再試過喇。如果仍然唔得嘅話,試下[[Special:UserLogout|登出]],然後重新登入。",
@@ -930,7 +960,7 @@ $1',
 'history-fieldset-title' => '瀏覽歷史',
 'history-show-deleted' => '只顯示刪除咗嘅',
 'histfirst' => '最早',
-'histlast' => '最',
+'histlast' => '最',
 'historysize' => '($1 {{PLURAL:$1|byte|bytes}})',
 'historyempty' => '(空)',
 
@@ -1187,7 +1217,7 @@ $1",
 'prefs-emailconfirm-label' => '電郵確認:',
 'youremail' => '電郵:',
 'username' => '用戶名:',
-'uid' => '用戶 ID:',
+'uid' => '{{GENDER:$1|用戶}}ID:',
 'prefs-memberingroups' => '{{PLURAL:$1|一|多}}組嘅成員:',
 'prefs-registration' => '註冊時間:',
 'yourrealname' => '真名:',
@@ -1262,8 +1292,8 @@ $1",
 
 'group-user-member' => '用戶',
 'group-autoconfirmed-member' => '自動確認用戶',
-'group-bot-member' => '機械人',
-'group-sysop-member' => '操作員',
+'group-bot-member' => '{{GENDER:$1|機械人}}',
+'group-sysop-member' => '{{GENDER:$1|管理員}}',
 'group-bureaucrat-member' => '事務員',
 'group-suppress-member' => '監督',
 
@@ -1543,6 +1573,10 @@ $1',
 'upload-unknown-size' => '未知嘅大細',
 'upload-http-error' => '一個HTTP錯誤發生咗: $1',
 
+# File backend
+'backend-fail-notexists' => '檔案$1唔存在。',
+'backend-fail-delete' => '刪唔到檔案「$1」。',
+
 # ZipDirectoryReader
 'zip-file-open-error' => '在開啟檔案進行ZIP檢查時出錯。',
 'zip-wrong-format' => '呢個唔係一個ZIP檔案。',
@@ -1785,6 +1819,7 @@ $1',
 'protectedpages-indef' => '只有無期保謢頁',
 'protectedpages-cascade' => '只有連串保護頁',
 'protectedpagesempty' => '響呢啲參數度,現時無頁面響度保護緊。',
+'protectedpages-reason' => '原因',
 'protectedtitles' => '保護咗嘅標題',
 'protectedtitlesempty' => '響呢啲參數之下並無標題保護住。',
 'listusers' => '用戶一覽',
@@ -1818,7 +1853,7 @@ $1',
 
 # Special:Log
 'specialloguserlabel' => '用戶:',
-'speciallogtitlelabel' => '標題:',
+'speciallogtitlelabel' => '目標(題目或者用戶):',
 'log' => '日誌',
 'all-logs-page' => '全部嘅公共日誌',
 'alllogstext' => '響{{SITENAME}}度全部日誌嘅綜合顯示。你可以選擇一個日誌類型、用戶名、或者受影響嘅頁面,嚟縮窄顯示嘅範圍。',
@@ -1929,7 +1964,7 @@ $1',
 'usermessage-editor' => '系統訊息',
 
 # Watchlist
-'watchlist' => '監視單',
+'watchlist' => '監視單',
 'mywatchlist' => '監視清單',
 'watchlistfor2' => '$1嘅監視清單 $2',
 'nowatchlist' => '你嘅監視清單度並冇任何項目。',
@@ -2066,8 +2101,8 @@ wiki: $PAGEEDITOR_WIKI
 'protect-cascadeon' => '呢一版現時正響度保護緊,因為佢係響以下嘅{{PLURAL:$1|一|幾}}頁度包含咗,而當中又開咗連串保護。你可以更改呢一版嘅保護等級,但係呢個修改係唔會影響到嗰個連串保護。',
 'protect-default' => '容許全部用戶',
 'protect-fallback' => '需要"$1"嘅許可',
-'protect-level-autoconfirmed' => '限制新嘅同未註冊嘅用戶',
-'protect-level-sysop' => '只限操作員',
+'protect-level-autoconfirmed' => '只限已經自動確認嘅用戶',
+'protect-level-sysop' => '只限管理員',
 'protect-summary-cascade' => '連串保護',
 'protect-expiring' => '響 $1 (UTC) 到期',
 'protect-expiry-indefinite' => '唔定',
index 44ef5b1..29c44dd 100644 (file)
@@ -37,6 +37,7 @@
  * @author Jding2010
  * @author Jetlag
  * @author Jidanni
+ * @author Jienus
  * @author Jimmy xu wrk
  * @author Kaganer
  * @author KaiesTse
@@ -548,7 +549,6 @@ $messages = array(
 'vector-action-protect' => '保护',
 'vector-action-undelete' => '还原',
 'vector-action-unprotect' => '更改保护',
-'vector-simplesearch-preference' => '启用简化的搜索栏(仅Vector皮肤)',
 'vector-view-create' => '创建',
 'vector-view-edit' => '编辑',
 'vector-view-history' => '查看历史',
@@ -1354,7 +1354,7 @@ $1",
 'showhideselectedversions' => '显示/隐藏选择的版本',
 'editundo' => '撤销',
 'diff-empty' => '(没有差异)',
-'diff-multi-sameuser' => '(相同用户的{{PLURAL:$1|一个|$1个}}中间修订版本未显示',
+'diff-multi-sameuser' => '(相同用户的{{PLURAL:$1|一个|$1个}}中间修订版本未显示',
 'diff-multi-otherusers' => '({{PLURAL:$1|某位用户|$2位用户}}的{{PLURAL:$1|一个|$1个}}中间修订版本未显示)',
 'diff-multi-manyusers' => '(未显示超过$2个用户的$1个中间版本)',
 'difference-missing-revision' => '此差异对比的{{PLURAL:$2|一个修订|$2个修订}}($1){{PLURAL:$2|没有}}找到。
@@ -2180,10 +2180,20 @@ $1',
 'deadendpagestext' => '以下页面没有链接至{{SITENAME}}的其它页面。',
 'protectedpages' => '受保护页面',
 'protectedpages-indef' => '仅无限期保护',
+'protectedpages-summary' => '本页面列出当前受保护的页面。要浏览受限制创建的标题列表,请参见[[{{#special:ProtectedTitles}}]]。',
 'protectedpages-cascade' => '仅连锁保护',
 'protectedpages-noredirect' => '隐藏重定向',
 'protectedpagesempty' => '在这些参数下没有页面正在保护。',
+'protectedpages-timestamp' => '时间戳',
+'protectedpages-page' => '页面',
+'protectedpages-expiry' => '到期',
+'protectedpages-performer' => '保护用户',
+'protectedpages-params' => '保护参数',
+'protectedpages-reason' => '原因',
+'protectedpages-unknown-timestamp' => '未知',
+'protectedpages-unknown-performer' => '未知用户',
 'protectedtitles' => '受保护标题',
+'protectedtitles-summary' => '本页面列出当前限制创建的标题。要浏览受限制页面的列表,请参见[[{{#special:ProtectedPages}}]]。',
 'protectedtitlesempty' => '在这些参数之下并无标题正在保护。',
 'listusers' => '用户列表',
 'listusers-editsonly' => '只显示有编辑的用户',
@@ -2916,6 +2926,7 @@ $2',
 'thumbnail_image-type' => '图像类型不支持',
 'thumbnail_gd-library' => '未完成的GD设置:功能遗失 $1',
 'thumbnail_image-missing' => '文件可能丢失:$1',
+'thumbnail_image-failure-limit' => '近期尝试生成此缩略图失败太多次($1次或更多)。请稍后再试。',
 
 # Special:Import
 'import' => '导入页面',
index 514b06c..8ee9c6b 100644 (file)
@@ -433,7 +433,6 @@ $messages = array(
 'vector-action-protect' => '保護',
 'vector-action-undelete' => '恢復被刪頁面',
 'vector-action-unprotect' => '更改保護',
-'vector-simplesearch-preference' => '啟用簡化搜尋欄(僅限 Vector 外觀)',
 'vector-view-create' => '建立',
 'vector-view-edit' => '編輯',
 'vector-view-history' => '檢視歷史',
@@ -736,7 +735,7 @@ $2',
 'createacct-captcha' => '安全驗證',
 'createacct-imgcaptcha-ph' => '輸入您在上方看到的文字',
 'createacct-submit' => '建立帳號',
-'createacct-another-submit' => '建ç«\8bå\8f¦ä¸\80å\80\8b使ç\94¨è\80\85帳è\99\9f',
+'createacct-another-submit' => '建立另一帳號',
 'createacct-benefit-heading' => '{{SITENAME}}是由像您一樣的人建立。',
 'createacct-benefit-body1' => '{{PLURAL:$1|次編輯}}',
 'createacct-benefit-body2' => '{{PLURAL:$1|篇頁面}}',
@@ -2129,10 +2128,20 @@ $1',
 'deadendpagestext' => '以下頁面沒有連結到{{SITENAME}}中的其它頁面。',
 'protectedpages' => '受保護頁面',
 'protectedpages-indef' => '只有無期之保護頁面',
+'protectedpages-summary' => '此頁面列出當前受保護之頁面。欲訪問受白紙保護之標題列表,請參見[[{{#special:ProtectedTitles}}]]。',
 'protectedpages-cascade' => '只有連鎖之保護頁面',
 'protectedpages-noredirect' => '隱藏重定向',
 'protectedpagesempty' => '在這些參數下沒有頁面正在保護。',
+'protectedpages-timestamp' => '時間戳',
+'protectedpages-page' => '頁面',
+'protectedpages-expiry' => '過期',
+'protectedpages-performer' => '保護用戶',
+'protectedpages-params' => '保護參數',
+'protectedpages-reason' => '原因',
+'protectedpages-unknown-timestamp' => '未知',
+'protectedpages-unknown-performer' => '未知用戶',
 'protectedtitles' => '受保護標題',
+'protectedtitles-summary' => '此頁面列出當前受白紙保護之標題。欲訪問受保護頁面之列表,請參見[[{{#special:ProtectedPages}}]]。',
 'protectedtitlesempty' => '在這些參數之下並無標題正在保護。',
 'listusers' => '用戶列表',
 'listusers-editsonly' => '只顯示有編輯的用戶',
@@ -2885,6 +2894,7 @@ $2',
 'thumbnail_image-type' => '圖片類型不支援',
 'thumbnail_gd-library' => '未完成的GD設定: 功能遺失 $1',
 'thumbnail_image-missing' => '檔案似乎遺失: $1',
+'thumbnail_image-failure-limit' => '新近嘗試生成此縮略圖失敗太多($1次或以上)。請稍後再試。',
 
 # Special:Import
 'import' => '匯入頁面',
index 4e2e869..edd97fd 100644 (file)
@@ -5,7 +5,7 @@
  * UTS #35 Revision 33
  * http://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Language_Plural_Rules
  *
- * @author Niklas Laxstrom, Tim Starling
+ * @author Niklas Laxström, Tim Starling
  *
  * @copyright Copyright © 2010-2012, Niklas Laxström
  * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0
index f1cd2f8..aa138bd 100644 (file)
@@ -25,6 +25,7 @@
                                        "mw.inspect",
                                        "mw.inspect.reports",
                                        "mw.notification",
+                                       "mw.Notification_",
                                        "mw.user",
                                        "mw.util",
                                        "mw.plugin.*"
index 216c19b..7326ed2 100644 (file)
@@ -30,6 +30,7 @@
                "../../resources/mediawiki.language",
                "../../resources/jquery/jquery.localize.js",
                "../../resources/jquery/jquery.spinner.js",
-               "../../resources/oojs"
+               "../../resources/oojs",
+               "../../resources/oojs-ui"
        ]
 }
index d692e2b..46b0362 100644 (file)
@@ -149,7 +149,6 @@ $wgIgnoredMessages = array(
        'booksources-summary',
        'categories-summary',
        'blocklist-summary',
-       'protectedtitles-summary',
        'listusers-summary',
        'longpages-summary',
        'preferences-summary',
@@ -180,7 +179,7 @@ $wgIgnoredMessages = array(
        'userrights-summary',
        'brokenredirects-summary',
        'deadendpages-summary',
-       'protectedpages-summary',
+       'protectedpages-unknown-reason',
        'disambiguations-summary',
        'pageswithprop-summary',
        'doubleredirects-summary',
index 6e6c3ed..73f5ca2 100644 (file)
@@ -196,7 +196,6 @@ $wgMessageStructure = array(
                'vector-action-protect',
                'vector-action-undelete',
                'vector-action-unprotect',
-               'vector-simplesearch-preference',
                'vector-view-create',
                'vector-view-edit',
                'vector-view-history',
@@ -1816,6 +1815,15 @@ $wgMessageStructure = array(
                'protectedpages-cascade',
                'protectedpages-noredirect',
                'protectedpagesempty',
+               'protectedpages-timestamp',
+               'protectedpages-page',
+               'protectedpages-expiry',
+               'protectedpages-performer',
+               'protectedpages-params',
+               'protectedpages-reason',
+               'protectedpages-unknown-timestamp',
+               'protectedpages-unknown-performer',
+               'protectedpages-unknown-reason',
                'protectedtitles',
                'protectedtitles-summary',
                'protectedtitlesempty',
index 71fdd61..dc560e3 100644 (file)
 -- tables.
 
 -- LINE:53
-CREATE TABLE /*$wgDBprefix*/user (
+CREATE TABLE /*_*/mwuser (
    user_id           INT           NOT NULL  PRIMARY KEY IDENTITY(0,1),
    user_name         NVARCHAR(255)  NOT NULL UNIQUE DEFAULT '',
    user_real_name    NVARCHAR(255)  NOT NULL DEFAULT '',
    user_password     NVARCHAR(255)  NOT NULL DEFAULT '',
    user_newpassword  NVARCHAR(255)  NOT NULL DEFAULT '',
-   user_newpass_time DATETIME NULL,
+   user_newpass_time varchar(14) NULL DEFAULT NULL,
    user_email        NVARCHAR(255)  NOT NULL DEFAULT '',
    user_options      NVARCHAR(MAX) NOT NULL DEFAULT '',
-   user_touched      DATETIME      NOT NULL DEFAULT GETDATE(),
+   user_touched      varchar(14)      NOT NULL DEFAULT '',
    user_token        NCHAR(32)      NOT NULL DEFAULT '',
-   user_email_authenticated DATETIME DEFAULT NULL,
+   user_email_authenticated varchar(14) DEFAULT NULL,
    user_email_token  NCHAR(32) DEFAULT '',
-   user_email_token_expires DATETIME DEFAULT NULL,
-   user_registration DATETIME DEFAULT NULL,
-   user_editcount    INT NULL
+   user_email_token_expires varchar(14) DEFAULT NULL,
+   user_registration varchar(14) DEFAULT NULL,
+   user_editcount    INT NULL DEFAULT NULL
 );
-CREATE        INDEX /*$wgDBprefix*/user_email_token ON /*$wgDBprefix*/[user](user_email_token);
-CREATE UNIQUE INDEX /*$wgDBprefix*/[user_name]        ON /*$wgDBprefix*/[user]([user_name]);
-;
+CREATE UNIQUE INDEX /*i*/user_name ON /*_*/mwuser (user_name);
+CREATE INDEX /*i*/user_email_token ON /*_*/mwuser (user_email_token);
+CREATE INDEX /*i*/user_email ON /*_*/mwuser (user_email);
+
+-- Insert a dummy user to represent anons
+INSERT INTO /*_*/mwuser (user_name) VALUES ('##Anonymous##');
 
 --
 -- User permissions have been broken out to a separate table;
@@ -57,86 +60,106 @@ CREATE UNIQUE INDEX /*$wgDBprefix*/[user_name]        ON /*$wgDBprefix*/[user]([
 -- permissions assigned to a user in each project.
 --
 -- This table replaces the old user_rights field which used a
--- comma-separated blob.
-CREATE TABLE /*$wgDBprefix*/user_groups (
-   ug_user  INT     NOT NULL REFERENCES /*$wgDBprefix*/[user](user_id) ON DELETE CASCADE,
-   ug_group NVARCHAR(16) NOT NULL DEFAULT '',
+-- comma-separated nvarchar(max).
+CREATE TABLE /*_*/user_groups (
+   ug_user  INT     NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
+   ug_group NVARCHAR(255) NOT NULL DEFAULT '',
+);
+CREATE UNIQUE clustered INDEX /*i*/ug_user_group ON /*_*/user_groups (ug_user, ug_group);
+CREATE INDEX /*i*/ug_group ON /*_*/user_groups(ug_group);
+
+-- Stores the groups the user has once belonged to.
+-- The user may still belong to these groups (check user_groups).
+-- Users are not autopromoted to groups from which they were removed.
+CREATE TABLE /*_*/user_former_groups (
+  ufg_user INT NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
+  ufg_group nvarchar(255) NOT NULL default ''
 );
-CREATE UNIQUE clustered INDEX /*$wgDBprefix*/user_groups_unique ON /*$wgDBprefix*/user_groups(ug_user, ug_group);
-CREATE INDEX /*$wgDBprefix*/user_group ON /*$wgDBprefix*/user_groups(ug_group);
+CREATE UNIQUE INDEX /*i*/ufg_user_group ON /*_*/user_former_groups (ufg_user,ufg_group);
 
 -- Stores notifications of user talk page changes, for the display
 -- of the "you have new messages" box
--- Changed user_id column to mwuser_id to avoid clashing with user_id function
-CREATE TABLE /*$wgDBprefix*/user_newtalk (
-   user_id INT         NOT NULL DEFAULT 0 REFERENCES /*$wgDBprefix*/[user](user_id) ON DELETE CASCADE,
+-- Changed user_id column to user_id to avoid clashing with user_id function
+CREATE TABLE /*_*/user_newtalk (
+   user_id INT         NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
    user_ip NVARCHAR(40) NOT NULL DEFAULT '',
-   user_last_timestamp DATETIME NOT NULL DEFAULT '',
+   user_last_timestamp varchar(14) DEFAULT NULL,
 );
-CREATE INDEX /*$wgDBprefix*/user_group_id ON /*$wgDBprefix*/user_newtalk([user_id]);
-CREATE INDEX /*$wgDBprefix*/user_ip       ON /*$wgDBprefix*/user_newtalk(user_ip);
+CREATE INDEX /*i*/un_user_id ON /*_*/user_newtalk (user_id);
+CREATE INDEX /*i*/un_user_ip ON /*_*/user_newtalk (user_ip);
 
 --
 -- User preferences and other fun stuff
--- replaces old user.user_options BLOB
+-- replaces old user.user_options nvarchar(max)
 --
-CREATE TABLE /*$wgDBprefix*/user_properties (
-       up_user INT NOT NULL,
-       up_property NVARCHAR(32) NOT NULL,
+CREATE TABLE /*_*/user_properties (
+       up_user INT NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
+       up_property NVARCHAR(255) NOT NULL,
        up_value NVARCHAR(MAX),
 );
-CREATE UNIQUE clustered INDEX /*$wgDBprefix*/user_props_user_prop ON /*$wgDBprefix*/user_properties(up_user, up_property);
-CREATE INDEX /*$wgDBprefix*/user_props_prop ON /*$wgDBprefix*/user_properties(up_property);
+CREATE UNIQUE CLUSTERED INDEX /*i*/user_properties_user_property ON /*_*/user_properties (up_user,up_property);
+CREATE INDEX /*i*/user_properties_property ON /*_*/user_properties (up_property);
 
 
 --
 -- Core of the wiki: each page has an entry here which identifies
 -- it by title and contains some essential metadata.
 --
-CREATE TABLE /*$wgDBprefix*/page (
-   page_id        INT          NOT NULL  PRIMARY KEY clustered IDENTITY,
+CREATE TABLE /*_*/page (
+   page_id        INT          NOT NULL  PRIMARY KEY IDENTITY(0,1),
    page_namespace INT          NOT NULL,
    page_title     NVARCHAR(255)  NOT NULL,
-   page_restrictions NVARCHAR(255) NULL,
+   page_restrictions NVARCHAR(255) NOT NULL,
    page_counter BIGINT            NOT NULL DEFAULT 0,
    page_is_redirect BIT           NOT NULL DEFAULT 0,
    page_is_new BIT                NOT NULL DEFAULT 0,
-   page_random NUMERIC(15,14)     NOT NULL DEFAULT RAND(),
-   page_touched DATETIME NOT NULL DEFAULT GETDATE(),
-   page_latest INT NOT NULL,
+   page_random real     NOT NULL DEFAULT RAND(),
+   page_touched varchar(14) NOT NULL default '',
+   page_links_updated varchar(14) DEFAULT NULL,
+   page_latest INT, -- FK inserted later
    page_len INT NOT NULL,
+   page_content_model nvarchar(32) default null
 );
-CREATE UNIQUE INDEX /*$wgDBprefix*/page_unique_name ON /*$wgDBprefix*/page(page_namespace, page_title);
-CREATE        INDEX /*$wgDBprefix*/page_random_idx  ON /*$wgDBprefix*/page(page_random);
-CREATE        INDEX /*$wgDBprefix*/page_len_idx     ON /*$wgDBprefix*/page(page_len);
-;
+CREATE UNIQUE INDEX /*i*/name_title ON /*_*/page (page_namespace,page_title);
+CREATE INDEX /*i*/page_random ON /*_*/page (page_random);
+CREATE INDEX /*i*/page_len ON /*_*/page (page_len);
+CREATE INDEX /*i*/page_redirect_namespace_len ON /*_*/page (page_is_redirect, page_namespace, page_len);
+
+-- insert a dummy page
+INSERT INTO /*_*/page (page_namespace, page_title, page_restrictions, page_latest, page_len) VALUES (-1,'','',0,0);
 
 --
 -- Every edit of a page creates also a revision row.
 -- This stores metadata about the revision, and a reference
 -- to the TEXT storage backend.
 --
-CREATE TABLE /*$wgDBprefix*/revision (
-   rev_id INT NOT NULL UNIQUE IDENTITY,
-   rev_page INT NOT NULL,
-   rev_text_id INT  NOT NULL,
-   rev_comment NVARCHAR(max) NOT NULL,
-   rev_user INT  NOT NULL DEFAULT 0 /*REFERENCES [user](user_id)*/,
+CREATE TABLE /*_*/revision (
+   rev_id INT NOT NULL UNIQUE IDENTITY(0,1),
+   rev_page INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+   rev_text_id INT  NOT NULL, -- FK added later
+   rev_comment NVARCHAR(255) NOT NULL,
+   rev_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
    rev_user_text NVARCHAR(255) NOT NULL DEFAULT '',
-   rev_timestamp DATETIME NOT NULL DEFAULT GETDATE(),
+   rev_timestamp varchar(14) NOT NULL default '',
    rev_minor_edit BIT NOT NULL DEFAULT 0,
-   rev_deleted BIT  NOT NULL DEFAULT 0,
+   rev_deleted TINYINT  NOT NULL DEFAULT 0,
    rev_len INT,
-   rev_parent_id INT DEFAULT NULL,
-
+   rev_parent_id INT DEFAULT NULL REFERENCES /*_*/revision(rev_id),
+   rev_sha1 nvarchar(32) not null default '',
+   rev_content_model nvarchar(32) default null,
+   rev_content_format nvarchar(64) default null
 );
-CREATE UNIQUE clustered INDEX /*$wgDBprefix*/revision_unique ON /*$wgDBprefix*/revision(rev_page, rev_id);
-CREATE UNIQUE INDEX /*$wgDBprefix*/rev_id             ON /*$wgDBprefix*/revision(rev_id);
-CREATE        INDEX /*$wgDBprefix*/rev_timestamp      ON /*$wgDBprefix*/revision(rev_timestamp);
-CREATE        INDEX /*$wgDBprefix*/page_timestamp     ON /*$wgDBprefix*/revision(rev_page, rev_timestamp);
-CREATE        INDEX /*$wgDBprefix*/user_timestamp     ON /*$wgDBprefix*/revision(rev_user, rev_timestamp);
-CREATE        INDEX /*$wgDBprefix*/usertext_timestamp ON /*$wgDBprefix*/revision(rev_user_text, rev_timestamp);
-;
+CREATE UNIQUE CLUSTERED INDEX /*i*/rev_page_id ON /*_*/revision (rev_page, rev_id);
+CREATE INDEX /*i*/rev_timestamp ON /*_*/revision (rev_timestamp);
+CREATE INDEX /*i*/page_timestamp ON /*_*/revision (rev_page,rev_timestamp);
+CREATE INDEX /*i*/user_timestamp ON /*_*/revision (rev_user,rev_timestamp);
+CREATE INDEX /*i*/usertext_timestamp ON /*_*/revision (rev_user_text,rev_timestamp);
+CREATE INDEX /*i*/page_user_timestamp ON /*_*/revision (rev_page,rev_user,rev_timestamp);
+
+-- insert a dummy revision
+INSERT INTO /*_*/revision (rev_page,rev_text_id,rev_comment,rev_user,rev_len) VALUES (0,0,'',0,0);
+
+ALTER TABLE /*_*/page ADD CONSTRAINT FK_page_latest_page_id FOREIGN KEY (page_latest) REFERENCES /*_*/revision(rev_id);
 
 --
 -- Holds TEXT of individual page revisions.
@@ -145,12 +168,17 @@ CREATE        INDEX /*$wgDBprefix*/usertext_timestamp ON /*$wgDBprefix*/revision
 -- MediaWiki 1.4 and earlier: an upgrade will transform that
 -- table INTo the 'text' table to minimize unnecessary churning
 -- and downtime. If upgrading, the other fields will be left unused.
-CREATE TABLE /*$wgDBprefix*/text (
-   old_id INT NOT NULL  PRIMARY KEY clustered IDENTITY,
-   old_text TEXT NOT NULL,
+CREATE TABLE /*_*/text (
+   old_id INT NOT NULL  PRIMARY KEY IDENTITY(0,1),
+   old_text nvarchar(max) NOT NULL,
    old_flags NVARCHAR(255) NOT NULL,
 );
 
+-- insert a dummy text
+INSERT INTO /*_*/text (old_text,old_flags) VALUES ('','');
+
+ALTER TABLE /*_*/revision ADD CONSTRAINT FK_rev_text_id_old_id FOREIGN KEY (rev_text_id) REFERENCES /*_*/text(old_id) ON DELETE CASCADE;
+
 --
 -- Holding area for deleted articles, which may be viewed
 -- or restored by admins through the Special:Undelete interface.
@@ -158,577 +186,1142 @@ CREATE TABLE /*$wgDBprefix*/text (
 -- fields, with several caveats.
 -- Cannot reasonably create views on this table, due to the presence of TEXT
 -- columns.
-CREATE TABLE /*$wgDBprefix*/archive (
-   ar_id NOT NULL PRIMARY KEY clustered IDENTITY,
+CREATE TABLE /*_*/archive (
+   ar_id int NOT NULL PRIMARY KEY IDENTITY,
    ar_namespace SMALLINT NOT NULL DEFAULT 0,
    ar_title NVARCHAR(255) NOT NULL DEFAULT '',
    ar_text NVARCHAR(MAX) NOT NULL,
    ar_comment NVARCHAR(255) NOT NULL,
-   ar_user INT NULL REFERENCES /*$wgDBprefix*/[user](user_id) ON DELETE SET NULL,
+   ar_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
    ar_user_text NVARCHAR(255) NOT NULL,
-   ar_timestamp DATETIME NOT NULL DEFAULT GETDATE(),
+   ar_timestamp varchar(14) NOT NULL default '',
    ar_minor_edit BIT NOT NULL DEFAULT 0,
    ar_flags NVARCHAR(255) NOT NULL,
-   ar_rev_id INT,
-   ar_text_id INT,
-   ar_deleted BIT NOT NULL DEFAULT 0,
-   ar_len INT DEFAULT NULL,
-   ar_page_id INT NULL,
-   ar_parent_id INT NULL,
+   ar_rev_id INT NULL, -- NOT a FK, the row gets deleted from revision and moved here
+   ar_text_id INT REFERENCES /*_*/text(old_id) ON DELETE CASCADE,
+   ar_deleted TINYINT NOT NULL DEFAULT 0,
+   ar_len INT,
+   ar_page_id INT NULL, -- NOT a FK, the row gets deleted from page and moved here
+   ar_parent_id INT NULL REFERENCES /*_*/revision(rev_id),
+   ar_sha1 nvarchar(32) default null,
+   ar_content_model nvarchar(32) DEFAULT NULL,
+  ar_content_format nvarchar(64) DEFAULT NULL
 );
-CREATE INDEX /*$wgDBprefix*/ar_name_title_timestamp ON /*$wgDBprefix*/archive(ar_namespace,ar_title,ar_timestamp);
-CREATE INDEX /*$wgDBprefix*/ar_usertext_timestamp ON /*$wgDBprefix*/archive(ar_user_text,ar_timestamp);
-CREATE INDEX /*$wgDBprefix*/ar_user_text    ON /*$wgDBprefix*/archive(ar_user_text);
+CREATE INDEX /*i*/name_title_timestamp ON /*_*/archive (ar_namespace,ar_title,ar_timestamp);
+CREATE INDEX /*i*/ar_usertext_timestamp ON /*_*/archive (ar_user_text,ar_timestamp);
+CREATE INDEX /*i*/ar_revid ON /*_*/archive (ar_rev_id);
 
 
 --
 -- Track page-to-page hyperlinks within the wiki.
 --
-CREATE TABLE /*$wgDBprefix*/pagelinks (
-   pl_from INT NOT NULL DEFAULT 0 REFERENCES /*$wgDBprefix*/page(page_id) ON DELETE CASCADE,
-   pl_namespace SMALLINT NOT NULL DEFAULT 0,
+CREATE TABLE /*_*/pagelinks (
+   pl_from INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+   pl_namespace INT NOT NULL DEFAULT 0,
    pl_title NVARCHAR(255) NOT NULL DEFAULT '',
 );
-CREATE UNIQUE INDEX /*$wgDBprefix*/pl_from ON /*$wgDBprefix*/pagelinks(pl_from,pl_namespace,pl_title);
-CREATE UNIQUE INDEX /*$wgDBprefix*/pl_namespace ON /*$wgDBprefix*/pagelinks(pl_namespace,pl_title,pl_from);
+CREATE UNIQUE INDEX /*i*/pl_from ON /*_*/pagelinks (pl_from,pl_namespace,pl_title);
+CREATE UNIQUE INDEX /*i*/pl_namespace ON /*_*/pagelinks (pl_namespace,pl_title,pl_from);
+
 
 --
 -- Track template inclusions.
 --
-CREATE TABLE /*$wgDBprefix*/templatelinks (
-   tl_from INT NOT NULL DEFAULT 0 REFERENCES /*$wgDBprefix*/page(page_id) ON DELETE CASCADE,
-   tl_namespace SMALLINT NOT NULL DEFAULT 0,
-   tl_title NVARCHAR(255) NOT NULL DEFAULT '',
+CREATE TABLE /*_*/templatelinks (
+  tl_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+  tl_namespace int NOT NULL default 0,
+  tl_title nvarchar(255) NOT NULL default ''
 );
-CREATE UNIQUE INDEX /*$wgDBprefix*/tl_from ON /*$wgDBprefix*/templatelinks(tl_from,tl_namespace,tl_title);
-CREATE UNIQUE INDEX /*$wgDBprefix*/tl_namespace ON /*$wgDBprefix*/templatelinks(tl_namespace,tl_title,tl_from);
+
+CREATE UNIQUE INDEX /*i*/tl_from ON /*_*/templatelinks (tl_from,tl_namespace,tl_title);
+CREATE UNIQUE INDEX /*i*/tl_namespace ON /*_*/templatelinks (tl_namespace,tl_title,tl_from);
+
 
 --
 -- Track links to images *used inline*
 -- We don't distinguish live from broken links here, so
--- they do not need to be changed ON upload/removal.
+-- they do not need to be changed on upload/removal.
 --
-CREATE TABLE /*$wgDBprefix*/imagelinks (
-   il_from INT NOT NULL DEFAULT 0 REFERENCES /*$wgDBprefix*/page(page_id) ON DELETE CASCADE,
-   il_to NVARCHAR(255)  NOT NULL DEFAULT '',
-   CONSTRAINT /*$wgDBprefix*/il_from PRIMARY KEY(il_from,il_to),
+CREATE TABLE /*_*/imagelinks (
+  -- Key to page_id of the page containing the image / media link.
+  il_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+
+  -- Filename of target image.
+  -- This is also the page_title of the file's description page;
+  -- all such pages are in namespace 6 (NS_FILE).
+  il_to nvarchar(255) NOT NULL default ''
 );
-CREATE UNIQUE INDEX /*$wgDBprefix*/il_from_to ON /*$wgDBprefix*/imagelinks(il_from,il_to);
-CREATE UNIQUE INDEX /*$wgDBprefix*/il_to_from ON /*$wgDBprefix*/imagelinks(il_to,il_from);
+
+CREATE UNIQUE INDEX /*i*/il_from ON /*_*/imagelinks (il_from,il_to);
+CREATE UNIQUE INDEX /*i*/il_to ON /*_*/imagelinks (il_to,il_from);
 
 --
 -- Track category inclusions *used inline*
 -- This tracks a single level of category membership
--- (folksonomic tagging, really).
 --
-CREATE TABLE /*$wgDBprefix*/categorylinks (
-   cl_from INT NOT NULL DEFAULT 0,
-   cl_to NVARCHAR(255)  NOT NULL DEFAULT '',
-   cl_sortkey NVARCHAR(150)  NOT NULL DEFAULT '',
-   cl_timestamp DATETIME NOT NULL DEFAULT GETDATE(),
-   CONSTRAINT /*$wgDBprefix*/cl_from PRIMARY KEY(cl_from, cl_to),
+CREATE TABLE /*_*/categorylinks (
+  -- Key to page_id of the page defined as a category member.
+  cl_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+
+  -- Name of the category.
+  -- This is also the page_title of the category's description page;
+  -- all such pages are in namespace 14 (NS_CATEGORY).
+  cl_to nvarchar(255) NOT NULL default '',
+
+  -- A binary string obtained by applying a sortkey generation algorithm
+  -- (Collation::getSortKey()) to page_title, or cl_sortkey_prefix . "\n"
+  -- . page_title if cl_sortkey_prefix is nonempty.
+  cl_sortkey varbinary(230) NOT NULL default 0x,
+
+  -- A prefix for the raw sortkey manually specified by the user, either via
+  -- [[Category:Foo|prefix]] or {{defaultsort:prefix}}.  If nonempty, it's
+  -- concatenated with a line break followed by the page title before the sortkey
+  -- conversion algorithm is run.  We store this so that we can update
+  -- collations without reparsing all pages.
+  -- Note: If you change the length of this field, you also need to change
+  -- code in LinksUpdate.php. See bug 25254.
+  cl_sortkey_prefix varbinary(255) NOT NULL default 0x,
+
+  -- This isn't really used at present. Provided for an optional
+  -- sorting method by approximate addition time.
+  cl_timestamp varchar(14) NOT NULL,
+
+  -- Stores $wgCategoryCollation at the time cl_sortkey was generated.  This
+  -- can be used to install new collation versions, tracking which rows are not
+  -- yet updated.  '' means no collation, this is a legacy row that needs to be
+  -- updated by updateCollation.php.  In the future, it might be possible to
+  -- specify different collations per category.
+  cl_collation nvarchar(32) NOT NULL default '',
+
+  -- Stores whether cl_from is a category, file, or other page, so we can
+  -- paginate the three categories separately.  This never has to be updated
+  -- after the page is created, since none of these page types can be moved to
+  -- any other.
+  -- SQL server doesn't have enums, so we approximate with this
+  cl_type varchar(10) NOT NULL default 'page' CHECK (cl_type IN('page', 'subcat', 'file'))
 );
-CREATE UNIQUE INDEX /*$wgDBprefix*/cl_from_to   ON /*$wgDBprefix*/categorylinks(cl_from,cl_to);
--- We always sort within a given category...
-CREATE INDEX /*$wgDBprefix*/cl_sortkey   ON /*$wgDBprefix*/categorylinks(cl_to,cl_sortkey);
--- Not really used?
-CREATE INDEX /*$wgDBprefix*/cl_timestamp ON /*$wgDBprefix*/categorylinks(cl_to,cl_timestamp);
---;
+
+CREATE UNIQUE INDEX /*i*/cl_from ON /*_*/categorylinks (cl_from,cl_to);
+
+-- We always sort within a given category, and within a given type.  FIXME:
+-- Formerly this index didn't cover cl_type (since that didn't exist), so old
+-- callers won't be using an index: fix this?
+CREATE INDEX /*i*/cl_sortkey ON /*_*/categorylinks (cl_to,cl_type,cl_sortkey,cl_from);
+
+-- Used by the API (and some extensions)
+CREATE INDEX /*i*/cl_timestamp ON /*_*/categorylinks (cl_to,cl_timestamp);
+
+-- FIXME: Not used, delete this
+CREATE INDEX /*i*/cl_collation ON /*_*/categorylinks (cl_collation);
 
 --
 -- Track all existing categories.  Something is a category if 1) it has an en-
 -- try somewhere in categorylinks, or 2) it once did.  Categories might not
 -- have corresponding pages, so they need to be tracked separately.
 --
-CREATE TABLE /*$wgDBprefix*/category (
-  cat_id int NOT NULL IDENTITY(1,1),
-  cat_title nvarchar(255)  NOT NULL,
+CREATE TABLE /*_*/category (
+  -- Primary key
+  cat_id int NOT NULL PRIMARY KEY IDENTITY,
+
+  -- Name of the category, in the same form as page_title (with underscores).
+  -- If there is a category page corresponding to this category, by definition,
+  -- it has this name (in the Category namespace).
+  cat_title nvarchar(255) NOT NULL,
+
+  -- The numbers of member pages (including categories and media), subcatego-
+  -- ries, and Image: namespace members, respectively.  These are signed to
+  -- make underflow more obvious.  We make the first number include the second
+  -- two for better sorting: subtracting for display is easy, adding for order-
+  -- ing is not.
   cat_pages int NOT NULL default 0,
   cat_subcats int NOT NULL default 0,
-  cat_files int NOT NULL default 0,
-  cat_hidden tinyint NOT NULL default 0,
+  cat_files int NOT NULL default 0
 );
 
-CREATE UNIQUE INDEX /*$wgDBprefix*/cat_title   ON /*$wgDBprefix*/category(cat_title);
--- For Special:Mostlinkedcategories
-CREATE INDEX /*$wgDBprefix*/cat_pages   ON /*$wgDBprefix*/category(cat_pages);
+CREATE UNIQUE INDEX /*i*/cat_title ON /*_*/category (cat_title);
 
+-- For Special:Mostlinkedcategories
+CREATE INDEX /*i*/cat_pages ON /*_*/category (cat_pages);
 
-CREATE TABLE /*$wgDBprefix*/change_tag (
-  ct_rc_id   int  NOT NULL default 0,
-  ct_log_id  int  NOT NULL default 0,
-  ct_rev_id  int  NOT NULL default 0,
-  ct_tag     varchar(255)  NOT NULL,
-  ct_params  varchar(255)  NOT NULL,
-);
-CREATE UNIQUE INDEX /*$wgDBprefix*/change_tag_rc_tag ON /*$wgDBprefix*/change_tag(ct_rc_id,ct_tag);
-CREATE UNIQUE INDEX /*$wgDBprefix*/change_tag_log_tag ON /*$wgDBprefix*/change_tag(ct_log_id,ct_tag);
-CREATE UNIQUE INDEX /*$wgDBprefix*/change_tag_rev_tag ON /*$wgDBprefix*/change_tag(ct_rev_id,ct_tag);
-CREATE INDEX /*$wgDBprefix*/change_tag_tag_id ON /*$wgDBprefix*/change_tag(ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
 
-CREATE TABLE /*$wgDBprefix*/tag_summary (
-  ts_rc_id   INT NOT NULL default 0,
-  ts_log_id  INT NOT NULL default 0,
-  ts_rev_id  INT NOT NULL default 0,
-  ts_tags    varchar(255)  NOT NULL
+--
+-- Track links to external URLs
+--
+CREATE TABLE /*_*/externallinks (
+  -- Primary key
+  el_id int NOT NULL PRIMARY KEY IDENTITY,
+
+  -- page_id of the referring page
+  el_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+
+  -- The URL
+  el_to nvarchar(max) NOT NULL,
+
+  -- In the case of HTTP URLs, this is the URL with any username or password
+  -- removed, and with the labels in the hostname reversed and converted to
+  -- lower case. An extra dot is added to allow for matching of either
+  -- example.com or *.example.com in a single scan.
+  -- Example:
+  --      http://user:password@sub.example.com/page.html
+  --   becomes
+  --      http://com.example.sub./page.html
+  -- which allows for fast searching for all pages under example.com with the
+  -- clause:
+  --      WHERE el_index LIKE 'http://com.example.%'
+  el_index nvarchar(450) NOT NULL
 );
-CREATE UNIQUE INDEX /*$wgDBprefix*/tag_summary_rc_id ON /*$wgDBprefix*/tag_summary(ts_rc_id);
-CREATE UNIQUE INDEX /*$wgDBprefix*/tag_summary_log_id ON /*$wgDBprefix*/tag_summary(ts_log_id);
-CREATE UNIQUE INDEX /*$wgDBprefix*/tag_summary_rev_id ON /*$wgDBprefix*/tag_summary(ts_rev_id);
 
-CREATE TABLE /*$wgDBprefix*/valid_tag (
-  vt_tag varchar(255) NOT NULL PRIMARY KEY
-);
+CREATE INDEX /*i*/el_from ON /*_*/externallinks (el_from);
+CREATE INDEX /*i*/el_index ON /*_*/externallinks (el_index);
 
 --
--- Table for storing localisation data
+-- Track interlanguage links
 --
-CREATE TABLE /*$wgDBprefix*/l10n_cache (
-       -- language code
-       lc_lang NVARCHAR(32) NOT NULL,
+CREATE TABLE /*_*/langlinks (
+  -- page_id of the referring page
+  ll_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
 
-       -- cache key
-       lc_key NVARCHAR(255) NOT NULL,
+  -- Language code of the target
+  ll_lang nvarchar(20) NOT NULL default '',
 
-       -- Value
-       lc_value TEXT NOT NULL DEFAULT '',
+  -- Title of the target, including namespace
+  ll_title nvarchar(255) NOT NULL default ''
 );
-CREATE INDEX /*$wgDBprefix*/lc_lang_key ON /*$wgDBprefix*/l10n_cache (lc_lang, lc_key);
 
---
--- Track links to external URLs
--- IE >= 4 supports no more than 2083 characters in a URL
-CREATE TABLE /*$wgDBprefix*/externallinks (
-   el_id INT NOT NULL PRIMARY KEY clustered IDENTITY,
-   el_from INT NOT NULL DEFAULT '0',
-   el_to VARCHAR(2083) NOT NULL,
-   el_index VARCHAR(896) NOT NULL,
-);
--- Maximum key length ON SQL Server is 900 bytes
-CREATE INDEX /*$wgDBprefix*/externallinks_index   ON /*$wgDBprefix*/externallinks(el_index);
+CREATE UNIQUE INDEX /*i*/ll_from ON /*_*/langlinks (ll_from, ll_lang);
+CREATE INDEX /*i*/ll_lang ON /*_*/langlinks (ll_lang, ll_title);
 
---
--- Track INTerlanguage links
---
-CREATE TABLE /*$wgDBprefix*/langlinks (
-   ll_from  INT          NOT NULL DEFAULT 0,
-   ll_lang  NVARCHAR(20)  NOT NULL DEFAULT '',
-   ll_title NVARCHAR(255)  NOT NULL DEFAULT '',
-   CONSTRAINT /*$wgDBprefix*/langlinks_pk PRIMARY KEY(ll_from, ll_lang),
-);
-CREATE UNIQUE INDEX /*$wgDBprefix*/langlinks_reverse_key ON /*$wgDBprefix*/langlinks(ll_lang,ll_title);
 
 --
 -- Track inline interwiki links
 --
-CREATE TABLE /*$wgDBprefix*/iwlinks (
-       -- page_id of the referring page
-       iwl_from INT NOT NULL DEFAULT 0,
+CREATE TABLE /*_*/iwlinks (
+  -- page_id of the referring page
+  iwl_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
 
-       -- Interwiki prefix code of the target
-       iwl_prefix NVARCHAR(20) NOT NULL DEFAULT '',
+  -- Interwiki prefix code of the target
+  iwl_prefix nvarchar(20) NOT NULL default '',
 
-       -- Title of the target, including namespace
-       iwl_title NVARCHAR(255) NOT NULL DEFAULT '',
+  -- Title of the target, including namespace
+  iwl_title nvarchar(255) NOT NULL default ''
 );
 
-CREATE UNIQUE INDEX /*$wgDBprefix*/iwl_from ON /*$wgDBprefix*/iwlinks(iwl_from,iwl_prefix,iwl_title);
-CREATE UNIQUE INDEX /*$wgDBprefix*/iwl_prefix ON /*$wgDBprefix*/iwlinks(iwl_prefix,iwl_title);
+CREATE UNIQUE INDEX /*i*/iwl_from ON /*_*/iwlinks (iwl_from, iwl_prefix, iwl_title);
+CREATE INDEX /*i*/iwl_prefix_title_from ON /*_*/iwlinks (iwl_prefix, iwl_title, iwl_from);
+CREATE INDEX /*i*/iwl_prefix_from_title ON /*_*/iwlinks (iwl_prefix, iwl_from, iwl_title);
 
 
 --
 -- Contains a single row with some aggregate info
--- ON the state of the site.
+-- on the state of the site.
 --
-CREATE TABLE /*$wgDBprefix*/site_stats (
-   ss_row_id        INT  NOT NULL DEFAULT 1 PRIMARY KEY,
-   ss_total_views   BIGINT DEFAULT 0,
-   ss_total_edits   BIGINT DEFAULT 0,
-   ss_good_articles BIGINT DEFAULT 0,
-   ss_total_pages   BIGINT DEFAULT -1,
-   ss_users         BIGINT DEFAULT -1,
-   ss_active_users  BIGINT DEFAULT -1,
-   ss_admins        INT    DEFAULT -1,
-   ss_images INT DEFAULT 0,
+CREATE TABLE /*_*/site_stats (
+  -- The single row should contain 1 here.
+  ss_row_id int NOT NULL,
+
+  -- Total number of page views, if hit counters are enabled.
+  ss_total_views bigint default 0,
+
+  -- Total number of edits performed.
+  ss_total_edits bigint default 0,
+
+  -- An approximate count of pages matching the following criteria:
+  -- * in namespace 0
+  -- * not a redirect
+  -- * contains the text '[['
+  -- See Article::isCountable() in includes/Article.php
+  ss_good_articles bigint default 0,
+
+  -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster
+  ss_total_pages bigint default '-1',
+
+  -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
+  ss_users bigint default '-1',
+
+  -- Number of users that still edit
+  ss_active_users bigint default '-1',
+
+  -- Number of images, equivalent to SELECT COUNT(*) FROM image
+  ss_images int default 0
 );
 
--- INSERT INTO site_stats DEFAULT VALUES;
+-- Pointless index to assuage developer superstitions
+CREATE UNIQUE INDEX /*i*/ss_row_id ON /*_*/site_stats (ss_row_id);
+
 
 --
 -- Stores an ID for every time any article is visited;
--- depending ON $wgHitcounterUpdateFreq, it is
+-- depending on $wgHitcounterUpdateFreq, it is
 -- periodically cleared and the page_counter column
--- in the page table updated for the all articles
+-- in the page table updated for all the articles
 -- that have been visited.)
 --
-CREATE TABLE /*$wgDBprefix*/hitcounter (
-   hc_id BIGINT NOT NULL
+CREATE TABLE /*_*/hitcounter (
+  hc_id int NOT NULL
 );
 
+
 --
--- The Internet is full of jerks, alas. Sometimes it's handy
+-- The internet is full of jerks, alas. Sometimes it's handy
 -- to block a vandal or troll account.
 --
-CREATE TABLE /*$wgDBprefix*/ipblocks (
-       ipb_id      INT NOT NULL  PRIMARY KEY,
-       ipb_address NVARCHAR(255) NOT NULL,
-       ipb_user    INT NOT NULL DEFAULT 0,
-       ipb_by      INT NOT NULL DEFAULT 0,
-       ipb_by_text NVARCHAR(255) NOT NULL DEFAULT '',
-       ipb_reason  NVARCHAR(255) NOT NULL,
-       ipb_timestamp DATETIME NOT NULL DEFAULT GETDATE(),
-       ipb_auto BIT NOT NULL DEFAULT 0,
-       ipb_anon_only BIT NOT NULL DEFAULT 0,
-       ipb_create_account BIT NOT NULL DEFAULT 1,
-       ipb_enable_autoblock BIT NOT NULL DEFAULT 1,
-       ipb_expiry DATETIME NOT NULL DEFAULT GETDATE(),
-       ipb_range_start NVARCHAR(32) NOT NULL DEFAULT '',
-       ipb_range_end NVARCHAR(32) NOT NULL DEFAULT '',
-       ipb_deleted BIT NOT NULL DEFAULT 0,
-       ipb_block_email BIT NOT NULL DEFAULT 0,
-       ipb_allow_usertalk BIT NOT NULL DEFAULT 0,
-       ipb_parent_block_id   INT DEFAULT NULL,
+CREATE TABLE /*_*/ipblocks (
+  -- Primary key, introduced for privacy.
+  ipb_id int NOT NULL PRIMARY KEY IDENTITY,
+
+  -- Blocked IP address in dotted-quad form or user name.
+  ipb_address nvarchar(255) NOT NULL,
+
+  -- Blocked user ID or 0 for IP blocks.
+  ipb_user int REFERENCES /*_*/mwuser(user_id),
+
+  -- User ID who made the block.
+  ipb_by int REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
+
+  -- User name of blocker
+  ipb_by_text nvarchar(255) NOT NULL default '',
+
+  -- Text comment made by blocker.
+  ipb_reason nvarchar(255) NOT NULL,
+
+  -- Creation (or refresh) date in standard YMDHMS form.
+  -- IP blocks expire automatically.
+  ipb_timestamp varchar(14) NOT NULL default '',
+
+  -- Indicates that the IP address was banned because a banned
+  -- user accessed a page through it. If this is 1, ipb_address
+  -- will be hidden, and the block identified by block ID number.
+  ipb_auto bit NOT NULL default 0,
+
+  -- If set to 1, block applies only to logged-out users
+  ipb_anon_only bit NOT NULL default 0,
+
+  -- Block prevents account creation from matching IP addresses
+  ipb_create_account bit NOT NULL default 1,
+
+  -- Block triggers autoblocks
+  ipb_enable_autoblock bit NOT NULL default 1,
+
+  -- Time at which the block will expire.
+  -- May be "infinity"
+  ipb_expiry varchar(14) NOT NULL,
+
+  -- Start and end of an address range, in hexadecimal
+  -- Size chosen to allow IPv6
+  -- FIXME: these fields were originally blank for single-IP blocks,
+  -- but now they are populated. No migration was ever done. They
+  -- should be fixed to be blank again for such blocks (bug 49504).
+  ipb_range_start varchar(255) NOT NULL,
+  ipb_range_end varchar(255) NOT NULL,
+
+  -- Flag for entries hidden from users and Sysops
+  ipb_deleted bit NOT NULL default 0,
+
+  -- Block prevents user from accessing Special:Emailuser
+  ipb_block_email bit NOT NULL default 0,
+
+  -- Block allows user to edit their own talk page
+  ipb_allow_usertalk bit NOT NULL default 0,
+
+  -- ID of the block that caused this block to exist
+  -- Autoblocks set this to the original block
+  -- so that the original block being deleted also
+  -- deletes the autoblocks
+  ipb_parent_block_id int default NULL REFERENCES /*_*/ipblocks(ipb_id)
+
 );
+
 -- Unique index to support "user already blocked" messages
 -- Any new options which prevent collisions should be included
---UNIQUE INDEX ipb_address (ipb_address(255), ipb_user, ipb_auto, ipb_anon_only),
-CREATE UNIQUE INDEX /*$wgDBprefix*/ipb_address   ON /*$wgDBprefix*/ipblocks(ipb_address, ipb_user, ipb_auto, ipb_anon_only);
-CREATE        INDEX /*$wgDBprefix*/ipb_user      ON /*$wgDBprefix*/ipblocks(ipb_user);
-CREATE        INDEX /*$wgDBprefix*/ipb_range     ON /*$wgDBprefix*/ipblocks(ipb_range_start, ipb_range_end);
-CREATE        INDEX /*$wgDBprefix*/ipb_timestamp ON /*$wgDBprefix*/ipblocks(ipb_timestamp);
-CREATE        INDEX /*$wgDBprefix*/ipb_expiry    ON /*$wgDBprefix*/ipblocks(ipb_expiry);
-;
+CREATE UNIQUE INDEX /*i*/ipb_address ON /*_*/ipblocks (ipb_address, ipb_user, ipb_auto, ipb_anon_only);
+
+CREATE INDEX /*i*/ipb_user ON /*_*/ipblocks (ipb_user);
+CREATE INDEX /*i*/ipb_range ON /*_*/ipblocks (ipb_range_start, ipb_range_end);
+CREATE INDEX /*i*/ipb_timestamp ON /*_*/ipblocks (ipb_timestamp);
+CREATE INDEX /*i*/ipb_expiry ON /*_*/ipblocks (ipb_expiry);
+CREATE INDEX /*i*/ipb_parent_block_id ON /*_*/ipblocks (ipb_parent_block_id);
+
 
 --
 -- Uploaded images and other files.
-CREATE TABLE /*$wgDBprefix*/image (
-   img_name varchar(255) NOT NULL default '',
-   img_size INT  NOT NULL DEFAULT 0,
-   img_width INT NOT NULL DEFAULT 0,
-   img_height INT NOT NULL DEFAULT 0,
-   img_metadata TEXT NOT NULL, -- was MEDIUMBLOB
-   img_bits SMALLINT NOT NULL DEFAULT 0,
-   img_media_type NVARCHAR(MAX) DEFAULT 'UNKNOWN',
-   img_major_mime NVARCHAR(MAX) DEFAULT 'UNKNOWN',
-   img_minor_mime NVARCHAR(MAX) NOT NULL DEFAULT 'unknown',
-   img_description NVARCHAR(MAX) NOT NULL,
-   img_user INT NOT NULL DEFAULT 0,
-   img_user_text VARCHAR(255) NOT NULL DEFAULT '',
-   img_timestamp DATETIME NOT NULL DEFAULT GETDATE(),
-   img_sha1 VARCHAR(255) NOT NULL default '',
-);
--- Used by Special:Imagelist for sort-by-size
-CREATE INDEX /*$wgDBprefix*/img_size ON /*$wgDBprefix*/[image](img_size);
--- Used by Special:Newimages and Special:Imagelist
-CREATE INDEX /*$wgDBprefix*/img_timestamp ON /*$wgDBprefix*/[image](img_timestamp)
-CREATE INDEX /*$wgDBprefix*/[img_sha1] ON /*wgDBprefix*/[image](img_sha1)
+--
+CREATE TABLE /*_*/image (
+  -- Filename.
+  -- This is also the title of the associated description page,
+  -- which will be in namespace 6 (NS_FILE).
+  img_name varbinary(255) NOT NULL default 0x PRIMARY KEY,
+
+  -- File size in bytes.
+  img_size int NOT NULL default 0,
+
+  -- For images, size in pixels.
+  img_width int NOT NULL default 0,
+  img_height int NOT NULL default 0,
+
+  -- Extracted Exif metadata stored as a serialized PHP array.
+  img_metadata varbinary(max) NOT NULL,
+
+  -- For images, bits per pixel if known.
+  img_bits int NOT NULL default 0,
+
+  -- Media type as defined by the MEDIATYPE_xxx constants
+  img_media_type varchar(16) default null check (img_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')),
+
+  -- major part of a MIME media type as defined by IANA
+  -- see http://www.iana.org/assignments/media-types/
+  img_major_mime varchar(16) not null default 'unknown' check (img_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart')),
+
+  -- minor part of a MIME media type as defined by IANA
+  -- the minor parts are not required to adher to any standard
+  -- but should be consistent throughout the database
+  -- see http://www.iana.org/assignments/media-types/
+  img_minor_mime nvarchar(100) NOT NULL default 'unknown',
+
+  -- Description field as entered by the uploader.
+  -- This is displayed in image upload history and logs.
+  img_description nvarchar(255) NOT NULL,
+
+  -- user_id and user_name of uploader.
+  img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+  img_user_text nvarchar(255) NOT NULL,
+
+  -- Time of the upload.
+  img_timestamp nvarchar(14) NOT NULL default '',
+
+  -- SHA-1 content hash in base-36
+  img_sha1 nvarchar(32) NOT NULL default ''
+);
+
+CREATE INDEX /*i*/img_usertext_timestamp ON /*_*/image (img_user_text,img_timestamp);
+-- Used by Special:ListFiles for sort-by-size
+CREATE INDEX /*i*/img_size ON /*_*/image (img_size);
+-- Used by Special:Newimages and Special:ListFiles
+CREATE INDEX /*i*/img_timestamp ON /*_*/image (img_timestamp);
+-- Used in API and duplicate search
+CREATE INDEX /*i*/img_sha1 ON /*_*/image (img_sha1);
+-- Used to get media of one type
+CREATE INDEX /*i*/img_media_mime ON /*_*/image (img_media_type,img_major_mime,img_minor_mime);
+
 
 --
 -- Previous revisions of uploaded files.
 -- Awkwardly, image rows have to be moved into
 -- this table at re-upload time.
 --
-CREATE TABLE /*$wgDBprefix*/oldimage (
-   oi_name VARCHAR(255) NOT NULL DEFAULT '',
-   oi_archive_name VARCHAR(255) NOT NULL DEFAULT '',
-   oi_size INT NOT NULL DEFAULT 0,
-   oi_width INT NOT NULL DEFAULT 0,
-   oi_height INT NOT NULL DEFAULT 0,
-   oi_bits SMALLINT NOT NULL DEFAULT 0,
-   oi_description NVARCHAR(MAX) NOT NULL,
-   oi_user INT NOT NULL DEFAULT 0,
-   oi_user_text VARCHAR(255) NOT NULL DEFAULT '',
-   oi_timestamp DATETIME NOT NULL DEFAULT GETDATE(),
-   oi_metadata TEXT NOT NULL,
-   oi_media_type NVARCHAR(MAX) DEFAULT 'UNKNOWN',
-   oi_major_mime NVARCHAR(MAX) NOT NULL DEFAULT 'UNKNOWN',
-   oi_minor_mime NVARCHAR(MAX) NOT NULL DEFAULT 'unknown',
-   oi_deleted BIT NOT NULL default 0,
-   oi_sha1 VARCHAR(255) NOT NULL default '',
-);
-CREATE INDEX /*$wgDBprefix*/oi_usertext_timestamp ON /*$wgDBprefix*/oldimage(oi_user_text,oi_timestamp);
-CREATE INDEX /*$wgDBprefix*/oi_name_timestamp ON /*$wgDBprefix*/oldimage(oi_name, oi_timestamp);
-CREATE INDEX /*$wgDBprefix*/oi_name_archive_name ON /*$wgDBprefix*/oldimage(oi_name,oi_archive_name);
-CREATE INDEX /*$wgDBprefix*/[oi_sha1] ON /*$wgDBprefix*/oldimage(oi_sha1);
+CREATE TABLE /*_*/oldimage (
+  -- Base filename: key to image.img_name
+  oi_name varbinary(255) NOT NULL default 0x REFERENCES /*_*/image(img_name) ON DELETE CASCADE ON UPDATE CASCADE,
+
+  -- Filename of the archived file.
+  -- This is generally a timestamp and '!' prepended to the base name.
+  oi_archive_name varbinary(255) NOT NULL default 0x,
+
+  -- Other fields as in image...
+  oi_size int NOT NULL default 0,
+  oi_width int NOT NULL default 0,
+  oi_height int NOT NULL default 0,
+  oi_bits int NOT NULL default 0,
+  oi_description nvarchar(255) NOT NULL,
+  oi_user int REFERENCES /*_*/mwuser(user_id),
+  oi_user_text nvarchar(255) NOT NULL,
+  oi_timestamp varchar(14) NOT NULL default '',
+
+  oi_metadata nvarchar(max) NOT NULL,
+  oi_media_type varchar(16) default null check (oi_media_type IN('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')),
+  oi_major_mime varchar(16) not null default 'unknown' check (oi_major_mime IN('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart')),
+  oi_minor_mime nvarchar(100) NOT NULL default 'unknown',
+  oi_deleted tinyint NOT NULL default 0,
+  oi_sha1 nvarchar(32) NOT NULL default ''
+);
+
+CREATE INDEX /*i*/oi_usertext_timestamp ON /*_*/oldimage (oi_user_text,oi_timestamp);
+CREATE INDEX /*i*/oi_name_timestamp ON /*_*/oldimage (oi_name,oi_timestamp);
+-- oi_archive_name truncated to 14 to avoid key length overflow
+CREATE INDEX /*i*/oi_name_archive_name ON /*_*/oldimage (oi_name,oi_archive_name);
+CREATE INDEX /*i*/oi_sha1 ON /*_*/oldimage (oi_sha1);
+
 
 --
 -- Record of deleted file data
 --
-CREATE TABLE /*$wgDBprefix*/filearchive (
-   fa_id INT NOT NULL PRIMARY KEY,
-   fa_name NVARCHAR(255)  NOT NULL DEFAULT '',
-   fa_archive_name NVARCHAR(255)  DEFAULT '',
-   fa_storage_group NVARCHAR(16),
-   fa_storage_key NVARCHAR(64)  DEFAULT '',
-   fa_deleted_user INT,
-   fa_deleted_timestamp NVARCHAR(14) DEFAULT NULL,
-   fa_deleted_reason NVARCHAR(255),
-   fa_size SMALLINT  DEFAULT 0,
-   fa_width SMALLINT DEFAULT 0,
-   fa_height SMALLINT DEFAULT 0,
-   fa_metadata NVARCHAR(MAX), -- was mediumblob
-   fa_bits SMALLINT DEFAULT 0,
-   fa_media_type NVARCHAR(11) DEFAULT NULL,
-   fa_major_mime NVARCHAR(11) DEFAULT 'unknown',
-   fa_minor_mime NVARCHAR(32) DEFAULT 'unknown',
-   fa_description NVARCHAR(255),
-   fa_user INT DEFAULT 0,
-   fa_user_text NVARCHAR(255) DEFAULT '',
-   fa_timestamp DATETIME DEFAULT GETDATE(),
-   fa_deleted BIT NOT NULL DEFAULT 0,
-);
--- Pick by image name
-CREATE INDEX /*$wgDBprefix*/filearchive_name ON /*$wgDBprefix*/filearchive(fa_name,fa_timestamp);
--- Pick by dupe files
-CREATE INDEX /*$wgDBprefix*/filearchive_dupe ON /*$wgDBprefix*/filearchive(fa_storage_group,fa_storage_key);
--- Pick by deletion time
-CREATE INDEX /*$wgDBprefix*/filearchive_time ON /*$wgDBprefix*/filearchive(fa_deleted_timestamp);
--- Pick by deleter
-CREATE INDEX /*$wgDBprefix*/filearchive_user ON /*$wgDBprefix*/filearchive(fa_deleted_user);
+CREATE TABLE /*_*/filearchive (
+  -- Unique row id
+  fa_id int NOT NULL PRIMARY KEY IDENTITY,
+
+  -- Original base filename; key to image.img_name, page.page_title, etc
+  fa_name nvarchar(255) NOT NULL default '',
+
+  -- Filename of archived file, if an old revision
+  fa_archive_name nvarchar(255) default '',
+
+  -- Which storage bin (directory tree or object store) the file data
+  -- is stored in. Should be 'deleted' for files that have been deleted;
+  -- any other bin is not yet in use.
+  fa_storage_group nvarchar(16),
+
+  -- SHA-1 of the file contents plus extension, used as a key for storage.
+  -- eg 8f8a562add37052a1848ff7771a2c515db94baa9.jpg
+  --
+  -- If NULL, the file was missing at deletion time or has been purged
+  -- from the archival storage.
+  fa_storage_key nvarchar(64) default '',
+
+  -- Deletion information, if this file is deleted.
+  fa_deleted_user int,
+  fa_deleted_timestamp varchar(14) default '',
+  fa_deleted_reason nvarchar(max),
+
+  -- Duped fields from image
+  fa_size int default 0,
+  fa_width int default 0,
+  fa_height int default 0,
+  fa_metadata nvarchar(max),
+  fa_bits int default 0,
+  fa_media_type varchar(16) default null check (fa_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')),
+  fa_major_mime varchar(16) not null default 'unknown' check (fa_major_mime in('unknown', 'application', 'audio', 'image', 'text', 'video', 'message', 'model', 'multipart')),
+  fa_minor_mime nvarchar(100) default 'unknown',
+  fa_description nvarchar(255),
+  fa_user int default 0 REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+  fa_user_text nvarchar(255),
+  fa_timestamp varchar(14) default '',
+
+  -- Visibility of deleted revisions, bitfield
+  fa_deleted tinyint NOT NULL default 0,
+
+  -- sha1 hash of file content
+  fa_sha1 nvarchar(32) NOT NULL default ''
+);
+
+-- pick out by image name
+CREATE INDEX /*i*/fa_name ON /*_*/filearchive (fa_name, fa_timestamp);
+-- pick out dupe files
+CREATE INDEX /*i*/fa_storage_group ON /*_*/filearchive (fa_storage_group, fa_storage_key);
+-- sort by deletion time
+CREATE INDEX /*i*/fa_deleted_timestamp ON /*_*/filearchive (fa_deleted_timestamp);
+-- sort by uploader
+CREATE INDEX /*i*/fa_user_timestamp ON /*_*/filearchive (fa_user_text,fa_timestamp);
+-- find file by sha1, 10 bytes will be enough for hashes to be indexed
+CREATE INDEX /*i*/fa_sha1 ON /*_*/filearchive (fa_sha1);
+
+
+--
+-- Store information about newly uploaded files before they're
+-- moved into the actual filestore
+--
+CREATE TABLE /*_*/uploadstash (
+  us_id int NOT NULL PRIMARY KEY IDENTITY,
+
+  -- the user who uploaded the file.
+  us_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+
+  -- file key. this is how applications actually search for the file.
+  -- this might go away, or become the primary key.
+  us_key nvarchar(255) NOT NULL,
+
+  -- the original path
+  us_orig_path nvarchar(255) NOT NULL,
+
+  -- the temporary path at which the file is actually stored
+  us_path nvarchar(255) NOT NULL,
+
+  -- which type of upload the file came from (sometimes)
+  us_source_type nvarchar(50),
+
+  -- the date/time on which the file was added
+  us_timestamp varchar(14) NOT NULL,
+
+  us_status nvarchar(50) NOT NULL,
+
+  -- chunk counter starts at 0, current offset is stored in us_size
+  us_chunk_inx int NULL,
+
+  -- Serialized file properties from File::getPropsFromPath
+  us_props nvarchar(max),
+
+  -- file size in bytes
+  us_size int NOT NULL,
+  -- this hash comes from File::sha1Base36(), and is 31 characters
+  us_sha1 nvarchar(31) NOT NULL,
+  us_mime nvarchar(255),
+  -- Media type as defined by the MEDIATYPE_xxx constants, should duplicate definition in the image table
+  us_media_type varchar(16) default null check (us_media_type in('UNKNOWN', 'BITMAP', 'DRAWING', 'AUDIO', 'VIDEO', 'MULTIMEDIA', 'OFFICE', 'TEXT', 'EXECUTABLE', 'ARCHIVE')),
+  -- image-specific properties
+  us_image_width int,
+  us_image_height int,
+  us_image_bits smallint
+
+);
+
+-- sometimes there's a delete for all of a user's stuff.
+CREATE INDEX /*i*/us_user ON /*_*/uploadstash (us_user);
+-- pick out files by key, enforce key uniqueness
+CREATE UNIQUE INDEX /*i*/us_key ON /*_*/uploadstash (us_key);
+-- the abandoned upload cleanup script needs this
+CREATE INDEX /*i*/us_timestamp ON /*_*/uploadstash (us_timestamp);
+
 
 --
 -- Primarily a summary table for Special:Recentchanges,
 -- this table contains some additional info on edits from
 -- the last few days, see Article::editUpdates()
 --
-CREATE TABLE /*$wgDBprefix*/recentchanges (
-   rc_id INT NOT NULL,
-   rc_timestamp DATETIME DEFAULT GETDATE(),
-   rc_cur_time DATETIME DEFAULT GETDATE(),
-   rc_user INT DEFAULT 0,
-   rc_user_text NVARCHAR(255) DEFAULT '',
-   rc_namespace SMALLINT DEFAULT 0,
-   rc_title NVARCHAR(255)  DEFAULT '',
-   rc_comment NVARCHAR(255) DEFAULT '',
-   rc_minor BIT DEFAULT 0,
-   rc_bot BIT DEFAULT 0,
-   rc_new BIT DEFAULT 0,
-   rc_cur_id INT DEFAULT 0,
-   rc_this_oldid INT DEFAULT 0,
-   rc_last_oldid INT DEFAULT 0,
-   rc_type tinyint DEFAULT 0,
-   rc_patrolled BIT DEFAULT 0,
-   rc_ip NCHAR(40) DEFAULT '',
-   rc_old_len INT DEFAULT 0,
-   rc_new_len INT DEFAULT 0,
-   rc_deleted BIT DEFAULT 0,
-   rc_logid INT DEFAULT 0,
-   rc_log_type NVARCHAR(255) NULL DEFAULT NULL,
-   rc_log_action NVARCHAR(255) NULL DEFAULT NULL,
-   rc_params NVARCHAR(MAX) DEFAULT '',
-);
-CREATE INDEX /*$wgDBprefix*/rc_timestamp       ON /*$wgDBprefix*/recentchanges(rc_timestamp);
-CREATE INDEX /*$wgDBprefix*/rc_namespace_title ON /*$wgDBprefix*/recentchanges(rc_namespace, rc_title);
-CREATE INDEX /*$wgDBprefix*/rc_cur_id          ON /*$wgDBprefix*/recentchanges(rc_cur_id);
-CREATE INDEX /*$wgDBprefix*/new_name_timestamp ON /*$wgDBprefix*/recentchanges(rc_new,rc_namespace,rc_timestamp);
-CREATE INDEX /*$wgDBprefix*/rc_ip              ON /*$wgDBprefix*/recentchanges(rc_ip);
-CREATE INDEX /*$wgDBprefix*/rc_ns_usertext     ON /*$wgDBprefix*/recentchanges(rc_namespace, rc_user_text);
-CREATE INDEX /*$wgDBprefix*/rc_user_text       ON /*$wgDBprefix*/recentchanges(rc_user_text, rc_timestamp);
-;
-
-CREATE TABLE /*$wgDBprefix*/watchlist (
-   wl_user INT NOT NULL,
-   wl_namespace SMALLINT NOT NULL DEFAULT 0,
-   wl_title NVARCHAR(255)  NOT NULL DEFAULT '',
-   wl_notificationtimestamp NVARCHAR(14) DEFAULT NULL,
-
-);
-CREATE UNIQUE INDEX /*$wgDBprefix*/namespace_title ON /*$wgDBprefix*/watchlist(wl_namespace,wl_title);
-
--- Needs fulltext index.
-CREATE TABLE /*$wgDBprefix*/searchindex (
-   si_page INT NOT NULL unique REFERENCES /*$wgDBprefix*/page(page_id) ON DELETE CASCADE,
-   si_title varbinary(max) NOT NULL,
-   si_text varbinary(max) NOT NULL,
-   si_ext CHAR(4) NOT NULL DEFAULT '.txt',
-);
-CREATE FULLTEXT CATALOG wikidb AS DEFAULT;
-CREATE UNIQUE CLUSTERED INDEX searchindex_page ON searchindex (si_page);
-CREATE FULLTEXT INDEX on searchindex (si_title TYPE COLUMN si_ext, si_text  TYPE COLUMN si_ext)
-KEY INDEX searchindex_page
-;
-
--- This table is not used unless profiling is turned on
-CREATE TABLE profiling (
-  pf_count   INTEGER         NOT NULL DEFAULT 0,
-  pf_time    NUMERIC(18,10)  NOT NULL DEFAULT 0,
-  pf_name    NVARCHAR(200)            NOT NULL,
-  pf_server  NVARCHAR(200)            NULL
-);
-CREATE UNIQUE INDEX pf_name_server ON profiling (pf_name, pf_server);
-
---
--- Recognized INTerwiki link prefixes
---
-CREATE TABLE /*$wgDBprefix*/interwiki (
-   iw_prefix NCHAR(32) NOT NULL PRIMARY KEY,
-   iw_url NCHAR(127)   NOT NULL,
-   iw_api TEXT NOT NULL DEFAULT '',
-   iw_wikiid NVARCHAR(64) NOT NULL DEFAULT '',
-   iw_local BIT NOT NULL,
-   iw_trans BIT NOT NULL DEFAULT 0,
+CREATE TABLE /*_*/recentchanges (
+  rc_id int NOT NULL PRIMARY KEY IDENTITY,
+  rc_timestamp varchar(14) not null default '',
+
+  -- This is no longer used
+  -- Field kept in database for downgrades
+  -- @todo: add drop patch with 1.24
+  rc_cur_time varchar(14) NOT NULL default '',
+
+  -- As in revision
+  rc_user int NOT NULL default 0 REFERENCES /*_*/mwuser(user_id),
+  rc_user_text nvarchar(255) NOT NULL,
+
+  -- When pages are renamed, their RC entries do _not_ change.
+  rc_namespace int NOT NULL default 0,
+  rc_title nvarchar(255) NOT NULL default '',
+
+  -- as in revision...
+  rc_comment nvarchar(255) NOT NULL default '',
+  rc_minor bit NOT NULL default 0,
+
+  -- Edits by user accounts with the 'bot' rights key are
+  -- marked with a 1 here, and will be hidden from the
+  -- default view.
+  rc_bot bit NOT NULL default 0,
+
+  -- Set if this change corresponds to a page creation
+  rc_new bit NOT NULL default 0,
+
+  -- Key to page_id (was cur_id prior to 1.5).
+  -- This will keep links working after moves while
+  -- retaining the at-the-time name in the changes list.
+  rc_cur_id int REFERENCES /*_*/page(page_id),
+
+  -- rev_id of the given revision
+  rc_this_oldid int REFERENCES /*_*/revision(rev_id),
+
+  -- rev_id of the prior revision, for generating diff links.
+  rc_last_oldid int REFERENCES /*_*/revision(rev_id),
+
+  -- The type of change entry (RC_EDIT,RC_NEW,RC_LOG,RC_EXTERNAL)
+  rc_type tinyint NOT NULL default 0,
+
+  -- The source of the change entry (replaces rc_type)
+  -- default of '' is temporary, needed for initial migration
+  rc_source nvarchar(16) not null default '',
+
+  -- If the Recent Changes Patrol option is enabled,
+  -- users may mark edits as having been reviewed to
+  -- remove a warning flag on the RC list.
+  -- A value of 1 indicates the page has been reviewed.
+  rc_patrolled bit NOT NULL default 0,
+
+  -- Recorded IP address the edit was made from, if the
+  -- $wgPutIPinRC option is enabled.
+  rc_ip nvarchar(40) NOT NULL default '',
+
+  -- Text length in characters before
+  -- and after the edit
+  rc_old_len int,
+  rc_new_len int,
+
+  -- Visibility of recent changes items, bitfield
+  rc_deleted tinyint NOT NULL default 0,
+
+  -- Value corresponding to log_id, specific log entries
+  rc_logid int, -- FK added later
+  -- Store log type info here, or null
+  rc_log_type nvarchar(255) NULL default NULL,
+  -- Store log action or null
+  rc_log_action nvarchar(255) NULL default NULL,
+  -- Log params
+  rc_params nvarchar(max) NULL
+);
+
+CREATE INDEX /*i*/rc_timestamp ON /*_*/recentchanges (rc_timestamp);
+CREATE INDEX /*i*/rc_namespace_title ON /*_*/recentchanges (rc_namespace, rc_title);
+CREATE INDEX /*i*/rc_cur_id ON /*_*/recentchanges (rc_cur_id);
+CREATE INDEX /*i*/new_name_timestamp ON /*_*/recentchanges (rc_new,rc_namespace,rc_timestamp);
+CREATE INDEX /*i*/rc_ip ON /*_*/recentchanges (rc_ip);
+CREATE INDEX /*i*/rc_ns_usertext ON /*_*/recentchanges (rc_namespace, rc_user_text);
+CREATE INDEX /*i*/rc_user_text ON /*_*/recentchanges (rc_user_text, rc_timestamp);
+
+
+CREATE TABLE /*_*/watchlist (
+  -- Key to user.user_id
+  wl_user int NOT NULL REFERENCES /*_*/mwuser(user_id) ON DELETE CASCADE,
+
+  -- Key to page_namespace/page_title
+  -- Note that users may watch pages which do not exist yet,
+  -- or existed in the past but have been deleted.
+  wl_namespace int NOT NULL default 0,
+  wl_title nvarchar(255) NOT NULL default '',
+
+  -- Timestamp used to send notification e-mails and show "updated since last visit" markers on
+  -- history and recent changes / watchlist. Set to NULL when the user visits the latest revision
+  -- of the page, which means that they should be sent an e-mail on the next change.
+  wl_notificationtimestamp varchar(14)
+
+);
+
+CREATE UNIQUE INDEX /*i*/wl_user ON /*_*/watchlist (wl_user, wl_namespace, wl_title);
+CREATE INDEX /*i*/namespace_title ON /*_*/watchlist (wl_namespace, wl_title);
+
+
+--
+-- Our search index for the builtin MediaWiki search
+--
+CREATE TABLE /*_*/searchindex (
+  -- Key to page_id
+  si_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+
+  -- Munged version of title
+  si_title nvarchar(255) NOT NULL default '',
+
+  -- Munged version of body text
+  si_text nvarchar(max) NOT NULL
+);
+
+CREATE UNIQUE INDEX /*i*/si_page ON /*_*/searchindex (si_page);
+-- Fulltext index is defined in MssqlInstaller.php
+
+--
+-- Recognized interwiki link prefixes
+--
+CREATE TABLE /*_*/interwiki (
+  -- The interwiki prefix, (e.g. "Meatball", or the language prefix "de")
+  iw_prefix nvarchar(32) NOT NULL,
+
+  -- The URL of the wiki, with "$1" as a placeholder for an article name.
+  -- Any spaces in the name will be transformed to underscores before
+  -- insertion.
+  iw_url nvarchar(max) NOT NULL,
+
+  -- The URL of the file api.php
+  iw_api nvarchar(max) NOT NULL,
+
+  -- The name of the database (for a connection to be established with wfGetLB( 'wikiid' ))
+  iw_wikiid nvarchar(64) NOT NULL,
+
+  -- A boolean value indicating whether the wiki is in this project
+  -- (used, for example, to detect redirect loops)
+  iw_local bit NOT NULL,
+
+  -- Boolean value indicating whether interwiki transclusions are allowed.
+  iw_trans bit NOT NULL default 0
 );
 
+CREATE UNIQUE INDEX /*i*/iw_prefix ON /*_*/interwiki (iw_prefix);
+
+
 --
 -- Used for caching expensive grouped queries
 --
-CREATE TABLE /*$wgDBprefix*/querycache (
-   qc_type      NCHAR(32)  NOT NULL,
-   qc_value     INT       NOT NULL DEFAULT '0',
-   qc_namespace SMALLINT       NOT NULL DEFAULT 0,
-   qc_title     NCHAR(255)  NOT NULL DEFAULT '',
-   CONSTRAINT /*$wgDBprefix*/qc_pk PRIMARY KEY (qc_type,qc_value)
+CREATE TABLE /*_*/querycache (
+  -- A key name, generally the base name of of the special page.
+  qc_type nvarchar(32) NOT NULL,
+
+  -- Some sort of stored value. Sizes, counts...
+  qc_value int NOT NULL default 0,
+
+  -- Target namespace+title
+  qc_namespace int NOT NULL default 0,
+  qc_title nvarchar(255) NOT NULL default ''
 );
 
+CREATE INDEX /*i*/qc_type ON /*_*/querycache (qc_type,qc_value);
+
+
 --
 -- For a few generic cache operations if not using Memcached
 --
-CREATE TABLE /*$wgDBprefix*/objectcache (
-   keyname NCHAR(255)  NOT NULL DEFAULT '',
-   [value] NVARCHAR(MAX), -- IMAGE,
-   exptime DATETIME, -- This is treated as a DATETIME
-);
-CREATE CLUSTERED INDEX /*$wgDBprefix*/[objectcache_time] ON /*$wgDBprefix*/objectcache(exptime);
-CREATE UNIQUE INDEX /*$wgDBprefix*/[objectcache_PK] ON /*wgDBprefix*/objectcache(keyname);
---
--- Cache of INTerwiki transclusion
---
-CREATE TABLE /*$wgDBprefix*/transcache (
-   tc_url      NVARCHAR(255)  NOT NULL PRIMARY KEY,
-   tc_contents NVARCHAR(MAX),
-   tc_time     INT NOT NULL,
-);
-
-CREATE TABLE /*$wgDBprefix*/logging (
-   log_id INT  PRIMARY KEY IDENTITY,
-   log_type NCHAR(10) NOT NULL DEFAULT '',
-   log_action NCHAR(10) NOT NULL DEFAULT '',
-   log_timestamp DATETIME NOT NULL DEFAULT GETDATE(),
-   log_user INT NOT NULL DEFAULT 0,
-   log_user_text NVARCHAR(255) NOT NULL DEFAULT '',
-   log_namespace INT NOT NULL DEFAULT 0,
-   log_title NVARCHAR(255)  NOT NULL DEFAULT '',
-   log_page INT NULL DEFAULT NULL,
-   log_comment NVARCHAR(255) NOT NULL DEFAULT '',
-   log_params NVARCHAR(MAX) NOT NULL,
-   log_deleted BIT NOT NULL DEFAULT 0,
-);
-CREATE INDEX /*$wgDBprefix*/type_time ON /*$wgDBprefix*/logging (log_type, log_timestamp);
-CREATE INDEX /*$wgDBprefix*/user_time ON /*$wgDBprefix*/logging (log_user, log_timestamp);
-CREATE INDEX /*$wgDBprefix*/page_time ON /*$wgDBprefix*/logging (log_namespace, log_title, log_timestamp);
-CREATE INDEX /*$wgDBprefix*/times ON /*$wgDBprefix*/logging (log_timestamp);
-CREATE INDEX /*$wgDBprefix*/log_user_type_time ON /*$wgDBprefix*/logging (log_user, log_type, log_timestamp);
-CREATE INDEX /*$wgDBprefix*/log_page_id_time ON /*$wgDBprefix*/logging (log_page,log_timestamp);
-CREATE INDEX /*$wgDBprefix*/log_user_text_type_time ON /*$wgDBprefix*/logging (log_user_text, log_type, log_timestamp);
-CREATE INDEX /*$wgDBprefix*/log_user_text_time ON /*$wgDBprefix*/logging (log_user_text, log_timestamp);
-
-CREATE TABLE /*$wgDBprefix*/log_search (
-       -- The type of ID (rev ID, log ID, rev timestamp, username)
-       ls_field NVARCHAR(32) NOT NULL,
-       -- The value of the ID
-       ls_value NVARCHAR(255) NOT NULL,
-       -- Key to log_id
-       ls_log_id INT NOT NULL default 0,
-);
-CREATE UNIQUE INDEX /*$wgDBprefix*/ls_field_val ON /*$wgDBprefix*/log_search (ls_field,ls_value,ls_log_id);
-CREATE INDEX /*$wgDBprefix*/ls_log_id ON /*$wgDBprefix*/log_search (ls_log_id);
+CREATE TABLE /*_*/objectcache (
+  keyname nvarchar(255) NOT NULL default '' PRIMARY KEY,
+  value varbinary(max),
+  exptime varchar(14)
+);
+CREATE INDEX /*i*/exptime ON /*_*/objectcache (exptime);
+
+
+--
+-- Cache of interwiki transclusion
+--
+CREATE TABLE /*_*/transcache (
+  tc_url nvarchar(255) NOT NULL,
+  tc_contents nvarchar(max),
+  tc_time varchar(14) NOT NULL
+);
+
+CREATE UNIQUE INDEX /*i*/tc_url_idx ON /*_*/transcache (tc_url);
+
+
+CREATE TABLE /*_*/logging (
+  -- Log ID, for referring to this specific log entry, probably for deletion and such.
+  log_id int NOT NULL PRIMARY KEY IDENTITY(0,1),
+
+  -- Symbolic keys for the general log type and the action type
+  -- within the log. The output format will be controlled by the
+  -- action field, but only the type controls categorization.
+  log_type nvarchar(32) NOT NULL default '',
+  log_action nvarchar(32) NOT NULL default '',
+
+  -- Timestamp. Duh.
+  log_timestamp varchar(14) NOT NULL default '',
+
+  -- The user who performed this action; key to user_id
+  log_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+
+  -- Name of the user who performed this action
+  log_user_text nvarchar(255) NOT NULL default '',
+
+  -- Key to the page affected. Where a user is the target,
+  -- this will point to the user page.
+  log_namespace int NOT NULL default 0,
+  log_title nvarchar(255) NOT NULL default '',
+  log_page int NULL REFERENCES /*_*/page(page_id) ON DELETE SET NULL,
+
+  -- Freeform text. Interpreted as edit history comments.
+  log_comment nvarchar(255) NOT NULL default '',
+
+  -- miscellaneous parameters:
+  -- LF separated list (old system) or serialized PHP array (new system)
+  log_params nvarchar(max) NOT NULL,
+
+  -- rev_deleted for logs
+  log_deleted tinyint NOT NULL default 0
+);
+
+CREATE INDEX /*i*/type_time ON /*_*/logging (log_type, log_timestamp);
+CREATE INDEX /*i*/user_time ON /*_*/logging (log_user, log_timestamp);
+CREATE INDEX /*i*/page_time ON /*_*/logging (log_namespace, log_title, log_timestamp);
+CREATE INDEX /*i*/times ON /*_*/logging (log_timestamp);
+CREATE INDEX /*i*/log_user_type_time ON /*_*/logging (log_user, log_type, log_timestamp);
+CREATE INDEX /*i*/log_page_id_time ON /*_*/logging (log_page,log_timestamp);
+CREATE INDEX /*i*/type_action ON /*_*/logging (log_type, log_action, log_timestamp);
+CREATE INDEX /*i*/log_user_text_type_time ON /*_*/logging (log_user_text, log_type, log_timestamp);
+CREATE INDEX /*i*/log_user_text_time ON /*_*/logging (log_user_text, log_timestamp);
+
+INSERT INTO /*_*/logging (log_user,log_page,log_params) VALUES(0,0,'');
+
+ALTER TABLE /*_*/recentchanges ADD CONSTRAINT FK_rc_logid_log_id FOREIGN KEY (rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;
+
+CREATE TABLE /*_*/log_search (
+  -- The type of ID (rev ID, log ID, rev timestamp, username)
+  ls_field nvarchar(32) NOT NULL,
+  -- The value of the ID
+  ls_value nvarchar(255) NOT NULL,
+  -- Key to log_id
+  ls_log_id int REFERENCES /*_*/logging(log_id) ON DELETE CASCADE
+);
+CREATE UNIQUE INDEX /*i*/ls_field_val ON /*_*/log_search (ls_field,ls_value,ls_log_id);
+CREATE INDEX /*i*/ls_log_id ON /*_*/log_search (ls_log_id);
 
 
 -- Jobs performed by parallel apache threads or a command-line daemon
-CREATE TABLE /*$wgDBprefix*/job (
-   job_id INT NOT NULL  PRIMARY KEY,
-   job_cmd NVARCHAR(200)  NOT NULL DEFAULT '',
-   job_namespace INT NOT NULL,
-   job_title NVARCHAR(200)  NOT NULL,
-   job_params NVARCHAR(255)  NOT NULL,
+CREATE TABLE /*_*/job (
+  job_id int NOT NULL PRIMARY KEY IDENTITY,
+
+  -- Command name
+  -- Limited to 60 to prevent key length overflow
+  job_cmd nvarchar(60) NOT NULL default '',
+
+  -- Namespace and title to act on
+  -- Should be 0 and '' if the command does not operate on a title
+  job_namespace int NOT NULL,
+  job_title nvarchar(255) NOT NULL,
+
+  -- Timestamp of when the job was inserted
+  -- NULL for jobs added before addition of the timestamp
+  job_timestamp nvarchar(14) NULL default NULL,
+
+  -- Any other parameters to the command
+  -- Stored as a PHP serialized array, or an empty string if there are no parameters
+  job_params nvarchar(max) NOT NULL,
+
+  -- Random, non-unique, number used for job acquisition (for lock concurrency)
+  job_random int NOT NULL default 0,
+
+  -- The number of times this job has been locked
+  job_attempts int NOT NULL default 0,
+
+  -- Field that conveys process locks on rows via process UUIDs
+  job_token nvarchar(32) NOT NULL default '',
+
+  -- Timestamp when the job was locked
+  job_token_timestamp varchar(14) NULL default NULL,
+
+  -- Base 36 SHA1 of the job parameters relevant to detecting duplicates
+  job_sha1 nvarchar(32) NOT NULL default ''
 );
-CREATE INDEX /*$wgDBprefix*/job_idx ON /*$wgDBprefix*/job(job_cmd,job_namespace,job_title);
+
+CREATE INDEX /*i*/job_sha1 ON /*_*/job (job_sha1);
+CREATE INDEX /*i*/job_cmd_token ON /*_*/job (job_cmd,job_token,job_random);
+CREATE INDEX /*i*/job_cmd_token_id ON /*_*/job (job_cmd,job_token,job_id);
+CREATE INDEX /*i*/job_cmd ON /*_*/job (job_cmd, job_namespace, job_title);
+CREATE INDEX /*i*/job_timestamp ON /*_*/job (job_timestamp);
+
 
 -- Details of updates to cached special pages
-CREATE TABLE /*$wgDBprefix*/querycache_info (
-   qci_type NVARCHAR(32) NOT NULL DEFAULT '' PRIMARY KEY,
-   qci_timestamp NVARCHAR(14) NOT NULL DEFAULT '19700101000000',
+CREATE TABLE /*_*/querycache_info (
+  -- Special page name
+  -- Corresponds to a qc_type value
+  qci_type nvarchar(32) NOT NULL default '',
+
+  -- Timestamp of last update
+  qci_timestamp varchar(14) NOT NULL default ''
 );
 
+CREATE UNIQUE INDEX /*i*/qci_type ON /*_*/querycache_info (qci_type);
+
+
 -- For each redirect, this table contains exactly one row defining its target
-CREATE TABLE /*$wgDBprefix*/redirect (
-       rd_from INT NOT NULL DEFAULT 0 REFERENCES /*$wgDBprefix*/[page](page_id) ON DELETE CASCADE,
-       rd_namespace SMALLINT NOT NULL DEFAULT '0',
-       rd_title NVARCHAR(255)  NOT NULL DEFAULT '',
-       rd_interwiki NVARCHAR(32) DEFAULT NULL,
-       rd_fragment NVARCHAR(255) DEFAULT NULL,
+CREATE TABLE /*_*/redirect (
+  -- Key to the page_id of the redirect page
+  rd_from int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+
+  -- Key to page_namespace/page_title of the target page.
+  -- The target page may or may not exist, and due to renames
+  -- and deletions may refer to different page records as time
+  -- goes by.
+  rd_namespace int NOT NULL default 0,
+  rd_title nvarchar(255) NOT NULL default '',
+  rd_interwiki nvarchar(32) default NULL,
+  rd_fragment nvarchar(255) default NULL
 );
-CREATE UNIQUE INDEX /*$wgDBprefix*/rd_ns_title ON /*$wgDBprefix*/redirect(rd_namespace,rd_title,rd_from);
+
+CREATE INDEX /*i*/rd_ns_title ON /*_*/redirect (rd_namespace,rd_title,rd_from);
+
 
 -- Used for caching expensive grouped queries that need two links (for example double-redirects)
-CREATE TABLE /*$wgDBprefix*/querycachetwo (
-   qcc_type NCHAR(32) NOT NULL,
-   qcc_value INT NOT NULL DEFAULT 0,
-   qcc_namespace INT NOT NULL DEFAULT 0,
-   qcc_title NCHAR(255)  NOT NULL DEFAULT '',
-   qcc_namespacetwo INT NOT NULL DEFAULT 0,
-   qcc_titletwo NCHAR(255)  NOT NULL DEFAULT '',
-   CONSTRAINT /*$wgDBprefix*/qcc_type PRIMARY KEY(qcc_type,qcc_value),
-);
-CREATE UNIQUE INDEX /*$wgDBprefix*/qcc_title    ON /*$wgDBprefix*/querycachetwo(qcc_type,qcc_namespace,qcc_title);
-CREATE UNIQUE INDEX /*$wgDBprefix*/qcc_titletwo ON /*$wgDBprefix*/querycachetwo(qcc_type,qcc_namespacetwo,qcc_titletwo);
-
-
---- Used for storing page restrictions (i.e. protection levels)
-CREATE TABLE /*$wgDBprefix*/page_restrictions (
-   pr_id INT UNIQUE IDENTITY,
-   pr_page INT NOT NULL REFERENCES /*$wgDBprefix*/page(page_id) ON DELETE CASCADE,
-   pr_type NVARCHAR(200) NOT NULL,
-   pr_level NVARCHAR(200) NOT NULL,
-   pr_cascade SMALLINT NOT NULL,
-   pr_user INT NULL,
-   pr_expiry DATETIME NULL,
-   CONSTRAINT /*$wgDBprefix*/pr_pagetype PRIMARY KEY(pr_page,pr_type),
-);
-CREATE INDEX /*$wgDBprefix*/pr_page      ON /*$wgDBprefix*/page_restrictions(pr_page);
-CREATE INDEX /*$wgDBprefix*/pr_typelevel ON /*$wgDBprefix*/page_restrictions(pr_type,pr_level);
-CREATE INDEX /*$wgDBprefix*/pr_pagelevel ON /*$wgDBprefix*/page_restrictions(pr_level);
-CREATE INDEX /*$wgDBprefix*/pr_cascade   ON /*$wgDBprefix*/page_restrictions(pr_cascade);
-;
+CREATE TABLE /*_*/querycachetwo (
+  -- A key name, generally the base name of of the special page.
+  qcc_type nvarchar(32) NOT NULL,
+
+  -- Some sort of stored value. Sizes, counts...
+  qcc_value int NOT NULL default 0,
+
+  -- Target namespace+title
+  qcc_namespace int NOT NULL default 0,
+  qcc_title nvarchar(255) NOT NULL default '',
+
+  -- Target namespace+title2
+  qcc_namespacetwo int NOT NULL default 0,
+  qcc_titletwo nvarchar(255) NOT NULL default ''
+);
+
+CREATE INDEX /*i*/qcc_type ON /*_*/querycachetwo (qcc_type,qcc_value);
+CREATE INDEX /*i*/qcc_title ON /*_*/querycachetwo (qcc_type,qcc_namespace,qcc_title);
+CREATE INDEX /*i*/qcc_titletwo ON /*_*/querycachetwo (qcc_type,qcc_namespacetwo,qcc_titletwo);
+
+
+-- Used for storing page restrictions (i.e. protection levels)
+CREATE TABLE /*_*/page_restrictions (
+  -- Field for an ID for this restrictions row (sort-key for Special:ProtectedPages)
+  pr_id int NOT NULL PRIMARY KEY IDENTITY,
+  -- Page to apply restrictions to (Foreign Key to page).
+  pr_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+  -- The protection type (edit, move, etc)
+  pr_type nvarchar(60) NOT NULL,
+  -- The protection level (Sysop, autoconfirmed, etc)
+  pr_level nvarchar(60) NOT NULL,
+  -- Whether or not to cascade the protection down to pages transcluded.
+  pr_cascade bit NOT NULL,
+  -- Field for future support of per-user restriction.
+  pr_user int NULL,
+  -- Field for time-limited protection.
+  pr_expiry varchar(14) NULL
+);
+
+CREATE UNIQUE INDEX /*i*/pr_pagetype ON /*_*/page_restrictions (pr_page,pr_type);
+CREATE INDEX /*i*/pr_typelevel ON /*_*/page_restrictions (pr_type,pr_level);
+CREATE INDEX /*i*/pr_level ON /*_*/page_restrictions (pr_level);
+CREATE INDEX /*i*/pr_cascade ON /*_*/page_restrictions (pr_cascade);
+
 
 -- Protected titles - nonexistent pages that have been protected
-CREATE TABLE /*$wgDBprefix*/protected_titles (
+CREATE TABLE /*_*/protected_titles (
   pt_namespace int NOT NULL,
-  pt_title NVARCHAR(255) NOT NULL,
-  pt_user int NOT NULL,
-  pt_reason NVARCHAR(3555),
-  pt_timestamp DATETIME NOT NULL,
-  pt_expiry DATETIME NOT NULL default '',
-  pt_create_perm NVARCHAR(60) NOT NULL,
-  PRIMARY KEY (pt_namespace,pt_title),
+  pt_title nvarchar(255) NOT NULL,
+  pt_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+  pt_reason nvarchar(255),
+  pt_timestamp varchar(14) NOT NULL,
+  pt_expiry varchar(14) NOT NULL,
+  pt_create_perm nvarchar(60) NOT NULL
 );
-CREATE INDEX /*$wgDBprefix*/pt_timestamp   ON /*$wgDBprefix*/protected_titles(pt_timestamp);
-;
+
+CREATE UNIQUE INDEX /*i*/pt_namespace_title ON /*_*/protected_titles (pt_namespace,pt_title);
+CREATE INDEX /*i*/pt_timestamp ON /*_*/protected_titles (pt_timestamp);
+
 
 -- Name/value pairs indexed by page_id
-CREATE TABLE /*$wgDBprefix*/page_props (
-  pp_page int NOT NULL,
-  pp_propname NVARCHAR(60) NOT NULL,
-  pp_value NVARCHAR(MAX) NOT NULL,
-  PRIMARY KEY (pp_page,pp_propname)
+CREATE TABLE /*_*/page_props (
+  pp_page int NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
+  pp_propname nvarchar(60) NOT NULL,
+  pp_value nvarchar(max) NOT NULL
 );
 
+CREATE UNIQUE INDEX /*i*/pp_page_propname ON /*_*/page_props (pp_page,pp_propname);
+CREATE UNIQUE INDEX /*i*/pp_propname_page ON /*_*/page_props (pp_propname,pp_page);
+
+
 -- A table to log updates, one text key row per update.
-CREATE TABLE /*$wgDBprefix*/updatelog (
-  ul_key NVARCHAR(255) NOT NULL,
-  PRIMARY KEY (ul_key)
+CREATE TABLE /*_*/updatelog (
+  ul_key nvarchar(255) NOT NULL PRIMARY KEY,
+  ul_value nvarchar(max)
 );
 
--- NOTE To enable full text indexing on SQL 2008 you need to create an account FDH$MSSQLSERVER
--- AND assign a password for the FDHOST process to run under
--- Once you have assigned a password to that account, you need to run the following stored procedure
--- replacing XXXXX with the password you used.
--- EXEC sp_fulltext_resetfdhostaccount @username = 'FDH$MSSQLSERVER', @password = 'XXXXXX' ;
 
+-- A table to track tags for revisions, logs and recent changes.
+CREATE TABLE /*_*/change_tag (
+  -- RCID for the change
+  ct_rc_id int NULL REFERENCES /*_*/recentchanges(rc_id),
+  -- LOGID for the change
+  ct_log_id int NULL REFERENCES /*_*/logging(log_id),
+  -- REVID for the change
+  ct_rev_id int NULL REFERENCES /*_*/revision(rev_id),
+  -- Tag applied
+  ct_tag nvarchar(255) NOT NULL,
+  -- Parameters for the tag, presently unused
+  ct_params nvarchar(max) NULL
+);
+
+CREATE UNIQUE INDEX /*i*/change_tag_rc_tag ON /*_*/change_tag (ct_rc_id,ct_tag);
+CREATE UNIQUE INDEX /*i*/change_tag_log_tag ON /*_*/change_tag (ct_log_id,ct_tag);
+CREATE UNIQUE INDEX /*i*/change_tag_rev_tag ON /*_*/change_tag (ct_rev_id,ct_tag);
+-- Covering index, so we can pull all the info only out of the index.
+CREATE INDEX /*i*/change_tag_tag_id ON /*_*/change_tag (ct_tag,ct_rc_id,ct_rev_id,ct_log_id);
+
+
+-- Rollup table to pull a LIST of tags simply without ugly GROUP_CONCAT
+-- that only works on MySQL 4.1+
+CREATE TABLE /*_*/tag_summary (
+  -- RCID for the change
+  ts_rc_id int NULL REFERENCES /*_*/recentchanges(rc_id),
+  -- LOGID for the change
+  ts_log_id int NULL REFERENCES /*_*/logging(log_id),
+  -- REVID for the change
+  ts_rev_id int NULL REFERENCES /*_*/revision(rev_id),
+  -- Comma-separated list of tags
+  ts_tags nvarchar(max) NOT NULL
+);
+
+CREATE UNIQUE INDEX /*i*/tag_summary_rc_id ON /*_*/tag_summary (ts_rc_id);
+CREATE UNIQUE INDEX /*i*/tag_summary_log_id ON /*_*/tag_summary (ts_log_id);
+CREATE UNIQUE INDEX /*i*/tag_summary_rev_id ON /*_*/tag_summary (ts_rev_id);
+
+
+CREATE TABLE /*_*/valid_tag (
+  vt_tag nvarchar(255) NOT NULL PRIMARY KEY
+);
+
+-- Table for storing localisation data
+CREATE TABLE /*_*/l10n_cache (
+  -- Language code
+  lc_lang nvarchar(32) NOT NULL,
+  -- Cache key
+  lc_key nvarchar(255) NOT NULL,
+  -- Value
+  lc_value varbinary(max) NOT NULL
+);
+CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key);
+
+-- Table for caching JSON message texts for the resource loader
+CREATE TABLE /*_*/msg_resource (
+  -- Resource name
+  mr_resource nvarchar(255) NOT NULL,
+  -- Language code
+  mr_lang nvarchar(32) NOT NULL,
+  -- JSON blob
+  mr_blob varbinary(max) NOT NULL,
+  -- Timestamp of last update
+  mr_timestamp varchar(14) NOT NULL
+);
+CREATE UNIQUE INDEX /*i*/mr_resource_lang ON /*_*/msg_resource (mr_resource, mr_lang);
+
+-- Table for administering which message is contained in which resource
+CREATE TABLE /*_*/msg_resource_links (
+  mrl_resource varbinary(255) NOT NULL,
+  -- Message key
+  mrl_message varbinary(255) NOT NULL
+);
+CREATE UNIQUE INDEX /*i*/mrl_message_resource ON /*_*/msg_resource_links (mrl_message, mrl_resource);
+
+-- Table caching which local files a module depends on that aren't
+-- registered directly, used for fast retrieval of file dependency.
+-- Currently only used for tracking images that CSS depends on
+CREATE TABLE /*_*/module_deps (
+  -- Module name
+  md_module nvarchar(255) NOT NULL,
+  -- Skin name
+  md_skin nvarchar(32) NOT NULL,
+  -- JSON nvarchar(max) with file dependencies
+  md_deps nvarchar(max) NOT NULL
+);
+CREATE UNIQUE INDEX /*i*/md_module_skin ON /*_*/module_deps (md_module, md_skin);
+
+-- Holds all the sites known to the wiki.
+CREATE TABLE /*_*/sites (
+  -- Numeric id of the site
+  site_id                    int        NOT NULL PRIMARY KEY IDENTITY,
+
+  -- Global identifier for the site, ie 'enwiktionary'
+  site_global_key            nvarchar(32)       NOT NULL,
+
+  -- Type of the site, ie 'mediawiki'
+  site_type                  nvarchar(32)       NOT NULL,
+
+  -- Group of the site, ie 'wikipedia'
+  site_group                 nvarchar(32)       NOT NULL,
+
+  -- Source of the site data, ie 'local', 'wikidata', 'my-magical-repo'
+  site_source                nvarchar(32)       NOT NULL,
+
+  -- Language code of the sites primary language.
+  site_language              nvarchar(32)       NOT NULL,
+
+  -- Protocol of the site, ie 'http://', 'irc://', '//'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_protocol              nvarchar(32)       NOT NULL,
+
+  -- Domain of the site in reverse order, ie 'org.mediawiki.www.'
+  -- This field is an index for lookups and is build from type specific data in site_data.
+  site_domain                NVARCHAR(255)        NOT NULL,
+
+  -- Type dependent site data.
+  site_data                  nvarchar(max)                NOT NULL,
+
+  -- If site.tld/path/key:pageTitle should forward users to  the page on
+  -- the actual site, where "key" is the local identifier.
+  site_forward              bit                NOT NULL,
+
+  -- Type dependent site config.
+  -- For instance if template transclusion should be allowed if it's a MediaWiki.
+  site_config               nvarchar(max)                NOT NULL
+);
+
+CREATE UNIQUE INDEX /*i*/sites_global_key ON /*_*/sites (site_global_key);
+CREATE INDEX /*i*/sites_type ON /*_*/sites (site_type);
+CREATE INDEX /*i*/sites_group ON /*_*/sites (site_group);
+CREATE INDEX /*i*/sites_source ON /*_*/sites (site_source);
+CREATE INDEX /*i*/sites_language ON /*_*/sites (site_language);
+CREATE INDEX /*i*/sites_protocol ON /*_*/sites (site_protocol);
+CREATE INDEX /*i*/sites_domain ON /*_*/sites (site_domain);
+CREATE INDEX /*i*/sites_forward ON /*_*/sites (site_forward);
+
+-- Links local site identifiers to their corresponding site.
+CREATE TABLE /*_*/site_identifiers (
+  -- Key on site.site_id
+  si_site                    int        NOT NULL REFERENCES /*_*/sites(site_id) ON DELETE CASCADE,
+
+  -- local key type, ie 'interwiki' or 'langlink'
+  si_type                    nvarchar(32)       NOT NULL,
+
+  -- local key value, ie 'en' or 'wiktionary'
+  si_key                     nvarchar(32)       NOT NULL
+);
 
---- Add the full-text capabilities, depricated in SQL Server 2005, FTS is enabled on all user created tables by default unless you are using SQL Server 2005 Express
---sp_fulltext_database 'enable';
---sp_fulltext_catalog 'WikiCatalog', 'create'
---sp_fulltext_table
---sp_fulltext_column
---sp_fulltext_table 'Articles', 'activate'
+CREATE UNIQUE INDEX /*i*/site_ids_type ON /*_*/site_identifiers (si_type, si_key);
+CREATE INDEX /*i*/site_ids_site ON /*_*/site_identifiers (si_site);
+CREATE INDEX /*i*/site_ids_key ON /*_*/site_identifiers (si_key);
index f7cdbdc..7f5b75a 100644 (file)
@@ -339,6 +339,9 @@ return array(
                'scripts' => 'resources/jquery/jquery.textSelection.js',
                'dependencies' => 'jquery.client',
        ),
+       'jquery.throttle-debounce' => array(
+               'scripts' => 'resources/jquery/jquery.ba-throttle-debounce.js',
+       ),
        'jquery.validate' => array(
                'scripts' => 'resources/jquery/jquery.validate.js',
        ),
@@ -636,6 +639,81 @@ return array(
                'group' => 'jquery.ui',
        ),
 
+       /* Moment.js */
+
+       'moment' => array(
+               'scripts' => 'resources/moment/moment.js',
+               'languageScripts' => array(
+                       'ar-ma' => 'resources/moment/lang/ar-ma.js',
+                       'ar' => 'resources/moment/lang/ar.js',
+                       'bg' => 'resources/moment/lang/bg.js',
+                       'br' => 'resources/moment/lang/br.js',
+                       'bs' => 'resources/moment/lang/bs.js',
+                       'ca' => 'resources/moment/lang/ca.js',
+                       'cs' => 'resources/moment/lang/cs.js',
+                       'cv' => 'resources/moment/lang/cv.js',
+                       'cy' => 'resources/moment/lang/cy.js',
+                       'da' => 'resources/moment/lang/da.js',
+                       'de' => 'resources/moment/lang/de.js',
+                       'el' => 'resources/moment/lang/el.js',
+                       'en-au' => 'resources/moment/lang/en-au.js',
+                       'en-ca' => 'resources/moment/lang/en-ca.js',
+                       'en-gb' => 'resources/moment/lang/en-gb.js',
+                       'eo' => 'resources/moment/lang/eo.js',
+                       'es' => 'resources/moment/lang/es.js',
+                       'et' => 'resources/moment/lang/et.js',
+                       'eu' => 'resources/moment/lang/eu.js',
+                       'fa' => 'resources/moment/lang/fa.js',
+                       'fi' => 'resources/moment/lang/fi.js',
+                       'fo' => 'resources/moment/lang/fo.js',
+                       'fr-ca' => 'resources/moment/lang/fr-ca.js',
+                       'fr' => 'resources/moment/lang/fr.js',
+                       'gl' => 'resources/moment/lang/gl.js',
+                       'he' => 'resources/moment/lang/he.js',
+                       'hi' => 'resources/moment/lang/hi.js',
+                       'hr' => 'resources/moment/lang/hr.js',
+                       'hu' => 'resources/moment/lang/hu.js',
+                       'hy-am' => 'resources/moment/lang/hy-am.js',
+                       'id' => 'resources/moment/lang/id.js',
+                       'is' => 'resources/moment/lang/is.js',
+                       'it' => 'resources/moment/lang/it.js',
+                       'ja' => 'resources/moment/lang/ja.js',
+                       'ka' => 'resources/moment/lang/ka.js',
+                       'ko' => 'resources/moment/lang/ko.js',
+                       'lt' => 'resources/moment/lang/lt.js',
+                       'lv' => 'resources/moment/lang/lv.js',
+                       'mk' => 'resources/moment/lang/mk.js',
+                       'ml' => 'resources/moment/lang/ml.js',
+                       'mr' => 'resources/moment/lang/mr.js',
+                       'ms-my' => 'resources/moment/lang/ms-my.js',
+                       'nb' => 'resources/moment/lang/nb.js',
+                       'ne' => 'resources/moment/lang/ne.js',
+                       'nl' => 'resources/moment/lang/nl.js',
+                       'nn' => 'resources/moment/lang/nn.js',
+                       'pl' => 'resources/moment/lang/pl.js',
+                       'pt-br' => 'resources/moment/lang/pt-br.js',
+                       'pt' => 'resources/moment/lang/pt.js',
+                       'ro' => 'resources/moment/lang/ro.js',
+                       'rs' => 'resources/moment/lang/rs.js',
+                       'ru' => 'resources/moment/lang/ru.js',
+                       'sk' => 'resources/moment/lang/sk.js',
+                       'sl' => 'resources/moment/lang/sl.js',
+                       'sq' => 'resources/moment/lang/sq.js',
+                       'sv' => 'resources/moment/lang/sv.js',
+                       'ta' => 'resources/moment/lang/ta.js',
+                       'th' => 'resources/moment/lang/th.js',
+                       'tl-ph' => 'resources/moment/lang/tl-ph.js',
+                       'tr' => 'resources/moment/lang/tr.js',
+                       'tzm-la' => 'resources/moment/lang/tzm-la.js',
+                       'tzm' => 'resources/moment/lang/tzm.js',
+                       'uk' => 'resources/moment/lang/uk.js',
+                       'uz' => 'resources/moment/lang/uz.js',
+                       'vn' => 'resources/moment/lang/vn.js',
+                       'zh-cn' => 'resources/moment/lang/zh-cn.js',
+                       'zh-tw' => 'resources/moment/lang/zh-tw.js',
+               ),
+       ),
+
        /* MediaWiki */
 
        'mediawiki' => array(
@@ -897,8 +975,12 @@ return array(
        ),
        'mediawiki.action.edit.editWarning' => array(
                'scripts' => 'resources/mediawiki.action/mediawiki.action.edit.editWarning.js',
+               'dependencies' => array(
+                       'mediawiki.jqueryMsg'
+               ),
                'messages' => array(
                        'editwarning-warning',
+                       'prefs-editing'
                ),
        ),
        // Alias for backwards compatibility
index e3e4b9a..6e47c60 100644 (file)
         getTitle: function() {
             var title, $e = this.$element, o = this.options;
             fixTitle($e);
-            var title, o = this.options;
             if (typeof o.title == 'string') {
                 title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
             } else if (typeof o.title == 'function') {
diff --git a/resources/jquery/jquery.ba-throttle-debounce.js b/resources/jquery/jquery.ba-throttle-debounce.js
new file mode 100644 (file)
index 0000000..fa30bdf
--- /dev/null
@@ -0,0 +1,252 @@
+/*!
+ * jQuery throttle / debounce - v1.1 - 3/7/2010
+ * http://benalman.com/projects/jquery-throttle-debounce-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+
+// Script: jQuery throttle / debounce: Sometimes, less is more!
+//
+// *Version: 1.1, Last updated: 3/7/2010*
+// 
+// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/
+// GitHub       - http://github.com/cowboy/jquery-throttle-debounce/
+// Source       - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js
+// (Minified)   - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb)
+// 
+// About: License
+// 
+// Copyright (c) 2010 "Cowboy" Ben Alman,
+// Dual licensed under the MIT and GPL licenses.
+// http://benalman.com/about/license/
+// 
+// About: Examples
+// 
+// These working examples, complete with fully commented code, illustrate a few
+// ways in which this plugin can be used.
+// 
+// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
+// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
+// 
+// About: Support and Testing
+// 
+// Information about what version or versions of jQuery this plugin has been
+// tested with, what browsers it has been tested in, and where the unit tests
+// reside (so you can test it yourself).
+// 
+// jQuery Versions - none, 1.3.2, 1.4.2
+// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
+// Unit Tests      - http://benalman.com/code/projects/jquery-throttle-debounce/unit/
+// 
+// About: Release History
+// 
+// 1.1 - (3/7/2010) Fixed a bug in <jQuery.throttle> where trailing callbacks
+//       executed later than they should. Reworked a fair amount of internal
+//       logic as well.
+// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over
+//       from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the
+//       no_trailing throttle parameter and debounce functionality.
+// 
+// Topic: Note for non-jQuery users
+// 
+// jQuery isn't actually required for this plugin, because nothing internal
+// uses any jQuery methods or properties. jQuery is just used as a namespace
+// under which these methods can exist.
+// 
+// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist
+// when this plugin is loaded, the method described below will be created in
+// the `Cowboy` namespace. Usage will be exactly the same, but instead of
+// $.method() or jQuery.method(), you'll need to use Cowboy.method().
+
+(function(window,undefined){
+  '$:nomunge'; // Used by YUI compressor.
+  
+  // Since jQuery really isn't required for this plugin, use `jQuery` as the
+  // namespace only if it already exists, otherwise use the `Cowboy` namespace,
+  // creating it if necessary.
+  var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ),
+    
+    // Internal method reference.
+    jq_throttle;
+  
+  // Method: jQuery.throttle
+  // 
+  // Throttle execution of a function. Especially useful for rate limiting
+  // execution of handlers on events like resize and scroll. If you want to
+  // rate-limit execution of a function to a single time, see the
+  // <jQuery.debounce> method.
+  // 
+  // In this visualization, | is a throttled-function call and X is the actual
+  // callback execution:
+  // 
+  // > Throttled with `no_trailing` specified as false or unspecified:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // > X    X    X    X    X    X        X    X    X    X    X    X
+  // > 
+  // > Throttled with `no_trailing` specified as true:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // > X    X    X    X    X             X    X    X    X    X
+  // 
+  // Usage:
+  // 
+  // > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback );
+  // > 
+  // > jQuery('selector').bind( 'someevent', throttled );
+  // > jQuery('selector').unbind( 'someevent', throttled );
+  // 
+  // This also works in jQuery 1.4+:
+  // 
+  // > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) );
+  // > jQuery('selector').unbind( 'someevent', callback );
+  // 
+  // Arguments:
+  // 
+  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
+  //    callbacks, values around 100 or 250 (or even higher) are most useful.
+  //  no_trailing - (Boolean) Optional, defaults to false. If no_trailing is
+  //    true, callback will only execute every `delay` milliseconds while the
+  //    throttled-function is being called. If no_trailing is false or
+  //    unspecified, callback will be executed one final time after the last
+  //    throttled-function call. (After the throttled-function has not been
+  //    called for `delay` milliseconds, the internal counter is reset)
+  //  callback - (Function) A function to be executed after delay milliseconds.
+  //    The `this` context and all arguments are passed through, as-is, to
+  //    `callback` when the throttled-function is executed.
+  // 
+  // Returns:
+  // 
+  //  (Function) A new, throttled, function.
+  
+  $.throttle = jq_throttle = function( delay, no_trailing, callback, debounce_mode ) {
+    // After wrapper has stopped being called, this timeout ensures that
+    // `callback` is executed at the proper times in `throttle` and `end`
+    // debounce modes.
+    var timeout_id,
+      
+      // Keep track of the last time `callback` was executed.
+      last_exec = 0;
+    
+    // `no_trailing` defaults to falsy.
+    if ( typeof no_trailing !== 'boolean' ) {
+      debounce_mode = callback;
+      callback = no_trailing;
+      no_trailing = undefined;
+    }
+    
+    // The `wrapper` function encapsulates all of the throttling / debouncing
+    // functionality and when executed will limit the rate at which `callback`
+    // is executed.
+    function wrapper() {
+      var that = this,
+        elapsed = +new Date() - last_exec,
+        args = arguments;
+      
+      // Execute `callback` and update the `last_exec` timestamp.
+      function exec() {
+        last_exec = +new Date();
+        callback.apply( that, args );
+      };
+      
+      // If `debounce_mode` is true (at_begin) this is used to clear the flag
+      // to allow future `callback` executions.
+      function clear() {
+        timeout_id = undefined;
+      };
+      
+      if ( debounce_mode && !timeout_id ) {
+        // Since `wrapper` is being called for the first time and
+        // `debounce_mode` is true (at_begin), execute `callback`.
+        exec();
+      }
+      
+      // Clear any existing timeout.
+      timeout_id && clearTimeout( timeout_id );
+      
+      if ( debounce_mode === undefined && elapsed > delay ) {
+        // In throttle mode, if `delay` time has been exceeded, execute
+        // `callback`.
+        exec();
+        
+      } else if ( no_trailing !== true ) {
+        // In trailing throttle mode, since `delay` time has not been
+        // exceeded, schedule `callback` to execute `delay` ms after most
+        // recent execution.
+        // 
+        // If `debounce_mode` is true (at_begin), schedule `clear` to execute
+        // after `delay` ms.
+        // 
+        // If `debounce_mode` is false (at end), schedule `callback` to
+        // execute after `delay` ms.
+        timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? delay - elapsed : delay );
+      }
+    };
+    
+    // Set the guid of `wrapper` function to the same of original callback, so
+    // it can be removed in jQuery 1.4+ .unbind or .die by using the original
+    // callback as a reference.
+    if ( $.guid ) {
+      wrapper.guid = callback.guid = callback.guid || $.guid++;
+    }
+    
+    // Return the wrapper function.
+    return wrapper;
+  };
+  
+  // Method: jQuery.debounce
+  // 
+  // Debounce execution of a function. Debouncing, unlike throttling,
+  // guarantees that a function is only executed a single time, either at the
+  // very beginning of a series of calls, or at the very end. If you want to
+  // simply rate-limit execution of a function, see the <jQuery.throttle>
+  // method.
+  // 
+  // In this visualization, | is a debounced-function call and X is the actual
+  // callback execution:
+  // 
+  // > Debounced with `at_begin` specified as false or unspecified:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // >                          X                                 X
+  // > 
+  // > Debounced with `at_begin` specified as true:
+  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
+  // > X                                 X
+  // 
+  // Usage:
+  // 
+  // > var debounced = jQuery.debounce( delay, [ at_begin, ] callback );
+  // > 
+  // > jQuery('selector').bind( 'someevent', debounced );
+  // > jQuery('selector').unbind( 'someevent', debounced );
+  // 
+  // This also works in jQuery 1.4+:
+  // 
+  // > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) );
+  // > jQuery('selector').unbind( 'someevent', callback );
+  // 
+  // Arguments:
+  // 
+  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
+  //    callbacks, values around 100 or 250 (or even higher) are most useful.
+  //  at_begin - (Boolean) Optional, defaults to false. If at_begin is false or
+  //    unspecified, callback will only be executed `delay` milliseconds after
+  //    the last debounced-function call. If at_begin is true, callback will be
+  //    executed only at the first debounced-function call. (After the
+  //    throttled-function has not been called for `delay` milliseconds, the
+  //    internal counter is reset)
+  //  callback - (Function) A function to be executed after delay milliseconds.
+  //    The `this` context and all arguments are passed through, as-is, to
+  //    `callback` when the debounced-function is executed.
+  // 
+  // Returns:
+  // 
+  //  (Function) A new, debounced, function.
+  
+  $.debounce = function( delay, at_begin, callback ) {
+    return callback === undefined
+      ? jq_throttle( delay, at_begin, false )
+      : jq_throttle( delay, callback, at_begin !== false );
+  };
+  
+})(this);
index cdc6767..6012d93 100644 (file)
                                        } );
                                } )
                                // AJAX success just means "200 OK" response, also check API error codes
-                               .done( function ( result ) {
+                               .done( function ( result, textStatus, jqXHR ) {
                                        if ( result === undefined || result === null || result === '' ) {
                                                apiDeferred.reject( 'ok-but-empty',
                                                        'OK response but empty result (check HTTP headers?)'
                                                var code = result.error.code === undefined ? 'unknown' : result.error.code;
                                                apiDeferred.reject( code, result );
                                        } else {
-                                               apiDeferred.resolve( result );
+                                               apiDeferred.resolve( result, jqXHR );
                                        }
                                } );
 
index e21d21b..80b68cc 100644 (file)
@@ -28,6 +28,7 @@
 }
 
 /* Note gzip compression means that it is okay to embed twice */
+/* http://pauginer.tumblr.com/post/36614680636/invisible-gradient-technique */
 .background-image-svg(@svg, @fallback) {
        background-image: url(@fallback);
        /* SVG support using a transparent gradient to guarantee cross-browser
        -webkit-transition: @string;
        transition: @string;
 }
-
-@-webkit-keyframes rotate {
-       from {
-               -webkit-transform:rotate(0deg);
-       }
-       to {
-               -webkit-transform:rotate(360deg);
-       }
-}
-
-@keyframes rotate {
-       from {
-               transform: rotate(0deg);
-       }
-       to {
-               transform: rotate(360deg);
-       }
-}
-
-.rotation(@time) {
-       -webkit-animation-name: rotate;
-       -webkit-animation-duration: @time;
-       -webkit-animation-iteration-count: infinite;
-       -webkit-animation-timing-function: linear;
-       animation-name: rotate;
-       animation-duration: @time;
-       animation-iteration-count: infinite;
-       animation-timing-function: linear;
-}
diff --git a/resources/mediawiki.less/mediawiki.mixins.rotation.less b/resources/mediawiki.less/mediawiki.mixins.rotation.less
new file mode 100644 (file)
index 0000000..82de5de
--- /dev/null
@@ -0,0 +1,31 @@
+// This is a separate file because importing the mixin causes
+// the keyframes blocks to be included in the output, regardless
+// of whether .rotation is used.
+@-webkit-keyframes rotate {
+       from {
+               -webkit-transform:rotate(0deg);
+       }
+       to {
+               -webkit-transform:rotate(360deg);
+       }
+}
+
+@keyframes rotate {
+       from {
+               transform: rotate(0deg);
+       }
+       to {
+               transform: rotate(360deg);
+       }
+}
+
+.rotation(@time) {
+       -webkit-animation-name: rotate;
+       -webkit-animation-duration: @time;
+       -webkit-animation-iteration-count: infinite;
+       -webkit-animation-timing-function: linear;
+       animation-name: rotate;
+       animation-duration: @time;
+       animation-iteration-count: infinite;
+       animation-timing-function: linear;
+}
index 75908ee..5fb14dd 100644 (file)
@@ -16,6 +16,9 @@
                $patrolLinks.on( 'click', function ( e ) {
                        var $spinner, href, rcid, apiRequest;
 
+                       // Start preloading the notification module (normally loaded by mw.notify())
+                       mw.loader.load( ['mediawiki.notification'], null, true );
+
                        // Hide the link and create a spinner to show it inside the brackets.
                        $spinner = $.createSpinner( {
                                size: 'small',
index 998a8c2..9489403 100644 (file)
                $links.click( function ( e ) {
                        var action, api, $link;
 
+                       // Start preloading the notification module (normally loaded by mw.notify())
+                       mw.loader.load( ['mediawiki.notification'], null, true );
+
                        action = mwUriGetAction( this.href );
 
                        if ( action !== 'watch' && action !== 'unwatch' ) {
index b02e8f2..ee4fc06 100644 (file)
@@ -264,6 +264,18 @@ td.mw-statistics-numbers {
        text-align: right;
 }
 
+/**** Special:ProtectedPages ****/
+table.mw-protectedpages span.mw-usertoollinks,
+span.mw-protectedpages-length,
+span.mw-protectedpages-actions {
+       white-space: nowrap;
+       font-size: 90%;
+}
+span.mw-protectedpages-unknown {
+       color: grey;
+       font-size: 90%;
+}
+
 /**** Special:UserRights ****/
 .mw-userrights-disabled {
        color: #888;
index e4a9316..d7d90f4 100644 (file)
                                ] );
                                return result === null ? null : [ result[0], result[2] ];
                        }
+                       function templateWithOutFirstParameter() {
+                               var result = sequence( [
+                                       templateName,
+                                       colon
+                               ] );
+                               return result === null ? null : [ result[0], '' ];
+                       }
                        colon = makeStringParser( ':' );
                        templateContents = choice( [
                                function () {
                                        var res = sequence( [
                                                // templates can have placeholders for dynamic replacement eg: {{PLURAL:$1|one car|$1 cars}}
                                                // or no placeholders eg: {{GRAMMAR:genitive|{{SITENAME}}}
-                                               choice( [ templateWithReplacement, templateWithOutReplacement ] ),
+                                               choice( [ templateWithReplacement, templateWithOutReplacement, templateWithOutFirstParameter ] ),
                                                nOrMore( 0, templateParam )
                                        ] );
                                        return res === null ? null : res[0].concat( res[1] );
 
                /**
                 * Transform parsed structure according to gender.
-                * Usage {{gender:[ gender | mw.user object ] | masculine form|feminine form|neutral form}}.
-                * The first node is either a string, which can be "male" or "female",
-                * or a User object (not a username).
                 *
-                * @param {Array} nodes List of nodes, [ {string|mw.User}, {string}, {string}, {string} ]
-                * @return {string} selected gender form according to current language
+                * Usage: {{gender:[ mw.user object | '' | 'male' | 'female' | 'unknown' ] | masculine form | feminine form | neutral form}}.
+                *
+                * The first node must be one of:
+                * - the mw.user object (or a compatible one)
+                * - an empty string - indicating the current user, same effect as passing the mw.user object
+                * - a gender string ('male', 'female' or 'unknown')
+                *
+                * @param {Array} nodes List of nodes, [ {string|mw.user}, {string}, {string}, {string} ]
+                * @return {string} Selected gender form according to current language
                 */
                gender: function ( nodes ) {
-                       var gender, forms;
+                       var gender,
+                               maybeUser = nodes[0],
+                               forms = nodes.slice( 1 );
 
-                       if  ( nodes[0] && nodes[0].options instanceof mw.Map ) {
-                               gender = nodes[0].options.get( 'gender' );
-                       } else {
-                               gender = nodes[0];
+                       if ( maybeUser === '' ) {
+                               maybeUser = mw.user;
                        }
 
-                       forms = nodes.slice( 1 );
+                       // If we are passed a mw.user-like object, check their gender.
+                       // Otherwise, assume the gender string itself was passed .
+                       if ( maybeUser && maybeUser.options instanceof mw.Map ) {
+                               gender = maybeUser.options.get( 'gender' );
+                       } else {
+                               gender = maybeUser;
+                       }
 
                        return this.language.gender( gender, forms );
                },
                        return this.language.convertNumber( number, isInteger );
                }
        };
+
        // Deprecated! don't rely on gM existing.
        // The window.gM ought not to be required - or if required, not required here.
        // But moving it to extensions breaks it (?!)
        // Need to fix plugin so it could do attributes as well, then will be okay to remove this.
-       window.gM = mw.jqueryMsg.getMessageFunction();
+       // @deprecated since 1.23
+       mw.log.deprecate( window, 'gM', mw.jqueryMsg.getMessageFunction(), 'Use mw.message( ... ).parse() instead' );
 
        /**
         * @method
index 7879d6f..716c326 100644 (file)
@@ -23,6 +23,7 @@ template
 templateContents
   = twr:templateWithReplacement p:templateParam* { return twr.concat(p) }
   / twr:templateWithOutReplacement p:templateParam* { return twr.concat(p) }
+  / twr:templateWithOutFirstParameter p:templateParam* { return twr.concat(p) }
   / t:templateName p:templateParam* { return p.length ? [ t, p ] : [ t ] }
 
 templateWithReplacement
@@ -31,6 +32,9 @@ templateWithReplacement
 templateWithOutReplacement
   = t:templateName ":" p:paramExpression { return [ t, p ] }
 
+templateWithOutFirstParameter
+  = t:templateName ":" { return [ t, "" ] }
+
 templateParam
   = "|" e:paramExpression* { return e.length > 1 ? [ "CONCAT" ].concat(e) : e[0]; }
 
index d282a56..8b78370 100644 (file)
@@ -438,19 +438,6 @@ var mw = ( function ( $, undefined ) {
                        } );
                },
 
-               /**
-                * Dummy placeholder for {@link mw.log}
-                * @method
-                */
-               log: ( function () {
-                       var log = function () {};
-                       log.warn = function () {};
-                       log.deprecate = function ( obj, key, val ) {
-                               obj[key] = val;
-                       };
-                       return log;
-               }() ),
-
                // Make the Map constructor publicly available.
                Map: Map,
 
@@ -528,6 +515,75 @@ var mw = ( function ( $, undefined ) {
                        return mw.message.apply( mw.message, arguments ).toString();
                },
 
+               /**
+                * Dummy placeholder for {@link mw.log}
+                * @method
+                */
+               log: ( function () {
+                       // Also update the restoration of methods in mediawiki.log.js
+                       // when adding or removing methods here.
+                       var log = function () {};
+
+                       /**
+                        * @class mw.log
+                        * @singleton
+                        */
+
+                       /**
+                        * Write a message the console's warning channel.
+                        * Also logs a stacktrace for easier debugging.
+                        * Each action is silently ignored if the browser doesn't support it.
+                        *
+                        * @param {string...} msg Messages to output to console
+                        */
+                       log.warn = function () {
+                               var console = window.console;
+                               if ( console && console.warn ) {
+                                       console.warn.apply( console, arguments );
+                                       if ( console.trace ) {
+                                               console.trace();
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Create a property in a host object that, when accessed, will produce
+                        * a deprecation warning in the console with backtrace.
+                        *
+                        * @param {Object} obj Host object of deprecated property
+                        * @param {string} key Name of property to create in `obj`
+                        * @param {Mixed} val The value this property should return when accessed
+                        * @param {string} [msg] Optional text to include in the deprecation message.
+                        */
+                       log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
+                               obj[key] = val;
+                       } : function ( obj, key, val, msg ) {
+                               msg = 'MWDeprecationWarning: Use of "' + key + '" property is deprecated.' +
+                                       ( msg ? ( ' ' + msg ) : '' );
+                               try {
+                                       Object.defineProperty( obj, key, {
+                                               configurable: true,
+                                               enumerable: true,
+                                               get: function () {
+                                                       mw.track( 'mw.deprecate', key );
+                                                       log.warn( msg );
+                                                       return val;
+                                               },
+                                               set: function ( newVal ) {
+                                                       mw.track( 'mw.deprecate', key );
+                                                       log.warn( msg );
+                                                       val = newVal;
+                                               }
+                                       } );
+                               } catch ( err ) {
+                                       // IE8 can throw on Object.defineProperty
+                                       obj[key] = val;
+                               }
+                       };
+
+                       return log;
+               }() ),
+
                /**
                 * Client-side module loader which integrates with the MediaWiki ResourceLoader
                 * @class mw.loader
@@ -984,6 +1040,8 @@ var mw = ( function ( $, undefined ) {
                         * @private
                         * @param {string} src URL to script, will be used as the src attribute in the script tag
                         * @param {Function} [callback] Callback which will be run when the script is done
+                        * @param {boolean} [async=false] Whether to load modules asynchronously.
+                        *  Ignored (and defaulted to `true`) if the document-ready event has already occurred.
                         */
                        function addScript( src, callback, async ) {
                                /*jshint evil:true */
@@ -1235,8 +1293,8 @@ var mw = ( function ( $, undefined ) {
                         * @param {string|string[]} dependencies Module name or array of string module names
                         * @param {Function} [ready] Callback to execute when all dependencies are ready
                         * @param {Function} [error] Callback to execute when any dependency fails
-                        * @param {boolean} [async] If true, load modules asynchronously even if
-                        *  document ready has not yet occurred.
+                        * @param {boolean} [async=false] Whether to load modules asynchronously.
+                        *  Ignored (and defaulted to `true`) if the document-ready event has already occurred.
                         */
                        function request( dependencies, ready, error, async ) {
                                var n;
@@ -1309,7 +1367,8 @@ var mw = ( function ( $, undefined ) {
                         * @param {Object} moduleMap Module map, see #buildModulesString
                         * @param {Object} currReqBase Object with other parameters (other than 'modules') to use in the request
                         * @param {string} sourceLoadScript URL of load.php
-                        * @param {boolean} async If true, use an asynchronous request even if document ready has not yet occurred
+                        * @param {boolean} async Whether to load modules asynchronously.
+                        *  Ignored (and defaulted to `true`) if the document-ready event has already occurred.
                         */
                        function doRequest( moduleMap, currReqBase, sourceLoadScript, async ) {
                                var request = $.extend(
@@ -1317,7 +1376,6 @@ var mw = ( function ( $, undefined ) {
                                        currReqBase
                                );
                                request = sortQuery( request );
-                               // Asynchronously append a script tag to the end of the body
                                // Append &* to avoid triggering the IE6 extension check
                                addScript( sourceLoadScript + '?' + $.param( request ) + '&*', null, async );
                        }
@@ -1685,10 +1743,9 @@ var mw = ( function ( $, undefined ) {
                                 * @param {string} [type='text/javascript'] mime-type to use if calling with a URL of an
                                 *  external script or style; acceptable values are "text/css" and
                                 *  "text/javascript"; if no type is provided, text/javascript is assumed.
-                                * @param {boolean} [async] If true, load modules asynchronously
-                                *  even if document ready has not yet occurred. If false, block before
-                                *  document ready and load async after. If not set, true will be
-                                *  assumed if loading a URL, and false will be assumed otherwise.
+                                * @param {boolean} [async] Whether to load modules asynchronously.
+                                *  Ignored (and defaulted to `true`) if the document-ready event has already occurred.
+                                *  Defaults to `true` if loading a URL, `false` otherwise.
                                 */
                                load: function ( modules, type, async ) {
                                        var filtered, m, module, l;
@@ -1708,7 +1765,7 @@ var mw = ( function ( $, undefined ) {
                                                        if ( type === 'text/css' ) {
                                                                // IE7-8 throws security warnings when inserting a <link> tag
                                                                // with a protocol-relative URL set though attributes (instead of
-                                                               // properties) - when on HTTPS. See also bug #.
+                                                               // properties) - when on HTTPS. See also bug 41331.
                                                                l = document.createElement( 'link' );
                                                                l.rel = 'stylesheet';
                                                                l.href = modules;
@@ -1800,14 +1857,6 @@ var mw = ( function ( $, undefined ) {
                                        return null;
                                },
 
-                               /**
-                                * @inheritdoc #getVersion
-                                * @deprecated since 1.18 use #getVersion instead
-                                */
-                               version: function () {
-                                       return mw.loader.getVersion.apply( mw.loader, arguments );
-                               },
-
                                /**
                                 * Get the state of a module.
                                 *
@@ -1831,19 +1880,6 @@ var mw = ( function ( $, undefined ) {
                                        } );
                                },
 
-                               /**
-                                * Load the `mediawiki.user` module.
-                                *
-                                * For backwards-compatibility with cached pages from before 2013 where:
-                                *
-                                * - the `mediawiki.user` module didn't exist yet
-                                * - `mw.user` was still part of mediawiki.js
-                                * - `mw.loader.go` still existed and called after `mw.loader.load()`
-                                */
-                               go: function () {
-                                       mw.loader.load( 'mediawiki.user' );
-                               },
-
                                /**
                                 * @inheritdoc mw.inspect#runReports
                                 * @method
index 75e4c96..dd22e35 100644 (file)
@@ -8,28 +8,32 @@
 
 ( function ( mw, $ ) {
 
-       /**
-        * @class mw.log
-        * @singleton
-        */
+       // Reference to dummy
+       // We don't need the dummy, but it has other methods on it
+       // that we need to restore afterwards.
+       var original = mw.log,
+               slice = Array.prototype.slice;
 
        /**
-        * Logs a message to the console.
+        * Logs a message to the console in debug mode.
         *
         * In the case the browser does not have a console API, a console is created on-the-fly by appending
         * a `<div id="mw-log-console">` element to the bottom of the body and then appending this and future
         * messages to that, instead of the console.
         *
+        * @member mw.log
         * @param {string...} msg Messages to output to console.
         */
        mw.log = function () {
                // Turn arguments into an array
-               var     args = Array.prototype.slice.call( arguments ),
+               var args = slice.call( arguments ),
                        // Allow log messages to use a configured prefix to identify the source window (ie. frame)
                        prefix = mw.config.exists( 'mw.log.prefix' ) ? mw.config.get( 'mw.log.prefix' ) + '> ' : '';
 
                // Try to use an existing console
-               if ( window.console !== undefined && $.isFunction( window.console.log ) ) {
+               // Generally we can cache this, but in this case we want to re-evaluate this as a
+               // global property live so that things like Firebug Lite can take precedence.
+               if ( window.console && window.console.log ) {
                        args.unshift( prefix );
                        window.console.log.apply( window.console, args );
                        return;
                } );
        };
 
-       /**
-        * Write a message the console's warning channel.
-        * Also logs a stacktrace for easier debugging.
-        * Each action is silently ignored if the browser doesn't support it.
-        *
-        * @param {string...} msg Messages to output to console
-        */
-       mw.log.warn = function () {
-               var console = window.console;
-               if ( console && console.warn ) {
-                       console.warn.apply( console, arguments );
-                       if ( console.trace ) {
-                               console.trace();
-                       }
-               }
-       };
-
-       /**
-        * Create a property in a host object that, when accessed, will produce
-        * a deprecation warning in the console with backtrace.
-        *
-        * @param {Object} obj Host object of deprecated property
-        * @param {string} key Name of property to create in `obj`
-        * @param {Mixed} val The value this property should return when accessed
-        * @param {string} [msg] Optional text to include in the deprecation message.
-        */
-       mw.log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
-               obj[key] = val;
-       } : function ( obj, key, val, msg ) {
-               msg = 'MWDeprecationWarning: Use of "' + key + '" property is deprecated.' +
-                       ( msg ? ( ' ' + msg ) : '' );
-               try {
-                       Object.defineProperty( obj, key, {
-                               configurable: true,
-                               enumerable: true,
-                               get: function () {
-                                       mw.log.warn( msg );
-                                       return val;
-                               },
-                               set: function ( newVal ) {
-                                       mw.log.warn( msg );
-                                       val = newVal;
-                               }
-                       } );
-               } catch ( err ) {
-                       // IE8 can throw on Object.defineProperty
-                       obj[key] = val;
-               }
-       };
+       // Restore original methods
+       mw.log.warn = original.warn;
+       mw.log.deprecate = original.deprecate;
 
 }( mediaWiki, jQuery ) );
index 4ede809..f142fa4 100644 (file)
@@ -8,17 +8,17 @@
                preReadyNotifQueue = [];
 
        /**
-        * Creates a Notification object for 1 message.
-        * Does not insert anything into the document (see #start).
+        * A Notification object for 1 message.
         *
-        * The "_" in the name is to avoid a bug (http://github.com/senchalabs/jsduck/issues/304)
+        * The "_" in the name is to avoid a bug (http://github.com/senchalabs/jsduck/issues/304).
         * It is not part of the actual class name.
         *
         * @class mw.Notification_
         * @alternateClassName mw.Notification
-        * @private
         *
-        * @constructor
+        * @constructor The constructor is not publicly accessible; use mw.notification#notify instead.
+        *  This does not insert anything into the document (see #start).
+        * @private
         */
        function Notification( message, options ) {
                var $notification, $notificationTitle, $notificationContent;
        }
 
        /**
-        * Start the notification.
-        * This inserts it into the page, closes any matching tagged notifications,
-        * handles the fadeIn animations and repacement transitions, and starts autoHide timers.
+        * Start the notification. Called automatically by mw.notification#notify
+        * (possibly asynchronously on document-ready).
+        *
+        * This inserts the notification into the page, closes any matching tagged notifications,
+        * handles the fadeIn animations and replacement transitions, and starts autoHide timers.
+        *
+        * @private
         */
        Notification.prototype.start = function () {
                var
         * Close/hide the notification.
         *
         * @param {Object} options An object containing options for the closing of the notification.
-        *  These are typically only used internally.
         *
         *  - speed: Use a close speed different than the default 'slow'.
         *  - placeholder: Set to false to disable the placeholder transition.
         * Helper function, take a list of notification divs and call
         * a function on the Notification instance attached to them.
         *
+        * @private
+        * @static
         * @param {jQuery} $notifications A jQuery object containing notification divs
         * @param {string} fn The name of the function to call on the Notification instance
         */
                 * @param {HTMLElement|jQuery|mw.Message|string} message
                 * @param {Object} options The options to use for the notification.
                 *  See #defaults for details.
-                * @return {Object} Object with a close function to close the notification
+                * @return {mw.Notification} Notification object
                 */
                notify: function ( message, options ) {
                        var notif;
                        } else {
                                preReadyNotifQueue.push( notif );
                        }
-                       return { close: $.proxy( notif.close, notif ) };
+
+                       return notif;
                },
 
                /**
index 3b360af..8d950a0 100644 (file)
 
                // Compute form data for search suggestions functionality.
                function computeResultRenderCache( context ) {
-                       var $form, formAction, baseHref, linkParams;
+                       var $form, baseHref, linkParams;
 
                        // Compute common parameters for links' hrefs
                        $form = context.config.$region.closest( 'form' );
 
-                       formAction = $form.attr( 'action' );
-                       baseHref = formAction + ( formAction.match( /\?/ ) ? '&' : '?' );
+                       baseHref = $form.attr( 'action' );
+                       baseHref += baseHref.indexOf( '?' ) > -1 ? '&' : '?';
 
                        linkParams = {};
                        $.each( $form.serializeArray(), function ( idx, obj ) {
                        special: {
                                render: specialRenderFunction,
                                select: function ( $input ) {
-                                       $input.closest( 'form' ).append(
-                                               $( '<input type="hidden" name="fulltext" value="1"/>' )
-                                       );
-                                       $input.closest( 'form' ).submit();
+                                       $input.closest( 'form' )
+                                               .append( $( '<input type="hidden" name="fulltext" value="1"/>' ) )
+                                               .submit();
                                }
                        },
                        $region: $searchRegion
diff --git a/resources/moment/LICENSE b/resources/moment/LICENSE
new file mode 100644 (file)
index 0000000..b44e3a6
--- /dev/null
@@ -0,0 +1,22 @@
+Copyright (c) 2011-2013 Tim Wood, Iskren Chernev, Moment.js contributors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/resources/moment/lang/ar-ma.js b/resources/moment/lang/ar-ma.js
new file mode 100644 (file)
index 0000000..1c159f1
--- /dev/null
@@ -0,0 +1,56 @@
+// moment.js language configuration
+// language : Moroccan Arabic (ar-ma)
+// author : ElFadili Yassine : https://github.com/ElFadiliY
+// author : Abdel Said : https://github.com/abdelsaid
+
+(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.lang('ar-ma', {
+        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 سنوات"
+        },
+        week : {
+            dow : 6, // Saturday is the first day of the week.
+            doy : 12  // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ar.js b/resources/moment/lang/ar.js
new file mode 100644 (file)
index 0000000..6e27d29
--- /dev/null
@@ -0,0 +1,56 @@
+// moment.js language configuration
+// language : Arabic (ar)
+// author : Abdel Said : https://github.com/abdelsaid
+// changes in months, weekdays : Ahmed Elkhatib
+
+(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.lang('ar', {
+        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 سنوات"
+        },
+        week : {
+            dow : 6, // Saturday is the first day of the week.
+            doy : 12  // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/bg.js b/resources/moment/lang/bg.js
new file mode 100644 (file)
index 0000000..f47ed65
--- /dev/null
@@ -0,0 +1,86 @@
+// moment.js language configuration
+// language : bulgarian (bg)
+// author : Krasen Borisov : https://github.com/kraz
+
+(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.lang('bg', {
+        months : "януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),
+        monthsShort : "янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),
+        weekdays : "неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),
+        weekdaysShort : "нед_пон_вто_сря_чет_пет_съб".split("_"),
+        weekdaysMin : "нд_пн_вт_ср_чт_пт_сб".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "D.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 : function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                case 6:
+                    return '[В изминалата] dddd [в] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[В изминалия] 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 години"
+        },
+        ordinal : function (number) {
+            var lastDigit = number % 10,
+                last2Digits = number % 100;
+            if (number === 0) {
+                return number + '-ев';
+            } else if (last2Digits === 0) {
+                return number + '-ен';
+            } else if (last2Digits > 10 && last2Digits < 20) {
+                return number + '-ти';
+            } else if (lastDigit === 1) {
+                return number + '-ви';
+            } else if (lastDigit === 2) {
+                return number + '-ри';
+            } else if (lastDigit === 7 || lastDigit === 8) {
+                return number + '-ми';
+            } else {
+                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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/br.js b/resources/moment/lang/br.js
new file mode 100644 (file)
index 0000000..39c60df
--- /dev/null
@@ -0,0 +1,107 @@
+// moment.js language configuration
+// language : breton (br)
+// author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
+
+(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 relativeTimeWithMutation(number, withoutSuffix, key) {
+        var format = {
+            'mm': "munutenn",
+            'MM': "miz",
+            'dd': "devezh"
+        };
+        return number + ' ' + mutation(format[key], number);
+    }
+
+    function specialMutationForYears(number) {
+        switch (lastNumber(number)) {
+        case 1:
+        case 3:
+        case 4:
+        case 5:
+        case 9:
+            return number + ' bloaz';
+        default:
+            return number + ' vloaz';
+        }
+    }
+
+    function lastNumber(number) {
+        if (number > 9) {
+            return lastNumber(number % 10);
+        }
+        return number;
+    }
+
+    function mutation(text, number) {
+        if (number === 2) {
+            return softMutation(text);
+        }
+        return text;
+    }
+
+    function softMutation(text) {
+        var mutationTable = {
+            'm': 'v',
+            'b': 'v',
+            'd': 'z'
+        };
+        if (mutationTable[text.charAt(0)] === undefined) {
+            return text;
+        }
+        return mutationTable[text.charAt(0)] + text.substring(1);
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),
+        weekdaysMin : "Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),
+        longDateFormat : {
+            LT : "h[e]mm A",
+            L : "DD/MM/YYYY",
+            LL : "D [a viz] MMMM YYYY",
+            LLL : "D [a viz] MMMM YYYY LT",
+            LLLL : "dddd, D [a viz] MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay : '[Hiziv da] LT',
+            nextDay : '[Warc\'hoazh da] LT',
+            nextWeek : 'dddd [da] LT',
+            lastDay : '[Dec\'h da] LT',
+            lastWeek : 'dddd [paset da] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "a-benn %s",
+            past : "%s 'zo",
+            s : "un nebeud segondennoù",
+            m : "ur vunutenn",
+            mm : relativeTimeWithMutation,
+            h : "un eur",
+            hh : "%d eur",
+            d : "un devezh",
+            dd : relativeTimeWithMutation,
+            M : "ur miz",
+            MM : relativeTimeWithMutation,
+            y : "ur bloaz",
+            yy : specialMutationForYears
+        },
+        ordinal : function (number) {
+            var output = (number === 1) ? 'añ' : 'vet';
+            return number + output;
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/bs.js b/resources/moment/lang/bs.js
new file mode 100644 (file)
index 0000000..83a9b4c
--- /dev/null
@@ -0,0 +1,139 @@
+// moment.js language configuration
+// language : bosnian (bs)
+// author : Nedim Cholich : https://github.com/frontyard
+// based on (hr) translation by Bojan Marković
+
+(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 translate(number, withoutSuffix, key) {
+        var result = number + " ";
+        switch (key) {
+        case 'm':
+            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
+        case 'mm':
+            if (number === 1) {
+                result += 'minuta';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'minute';
+            } else {
+                result += 'minuta';
+            }
+            return result;
+        case 'h':
+            return withoutSuffix ? 'jedan sat' : 'jednog sata';
+        case 'hh':
+            if (number === 1) {
+                result += 'sat';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'sata';
+            } else {
+                result += 'sati';
+            }
+            return result;
+        case 'dd':
+            if (number === 1) {
+                result += 'dan';
+            } else {
+                result += 'dana';
+            }
+            return result;
+        case 'MM':
+            if (number === 1) {
+                result += 'mjesec';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'mjeseca';
+            } else {
+                result += 'mjeseci';
+            }
+            return result;
+        case 'yy':
+            if (number === 1) {
+                result += 'godina';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'godine';
+            } else {
+                result += 'godina';
+            }
+            return result;
+        }
+    }
+
+    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("_"),
+        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("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD. MM. YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY LT",
+            LLLL : "dddd, D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay  : '[danas u] LT',
+            nextDay  : '[sutra u] LT',
+
+            nextWeek : function () {
+                switch (this.day()) {
+                case 0:
+                    return '[u] [nedjelju] [u] LT';
+                case 3:
+                    return '[u] [srijedu] [u] LT';
+                case 6:
+                    return '[u] [subotu] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[u] dddd [u] LT';
+                }
+            },
+            lastDay  : '[jučer u] LT',
+            lastWeek : function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                    return '[prošlu] dddd [u] LT';
+                case 6:
+                    return '[prošle] [subote] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[prošli] dddd [u] LT';
+                }
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "za %s",
+            past   : "prije %s",
+            s      : "par sekundi",
+            m      : translate,
+            mm     : translate,
+            h      : translate,
+            hh     : translate,
+            d      : "dan",
+            dd     : translate,
+            M      : "mjesec",
+            MM     : translate,
+            y      : "godinu",
+            yy     : translate
+        },
+        ordinal : '%d.',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ca.js b/resources/moment/lang/ca.js
new file mode 100644 (file)
index 0000000..cf47113
--- /dev/null
@@ -0,0 +1,66 @@
+// moment.js language configuration
+// language : catalan (ca)
+// author : Juan G. Hurtado : https://github.com/juanghurtado
+
+(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.lang('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("_"),
+        weekdaysShort : "dg._dl._dt._dc._dj._dv._ds.".split("_"),
+        weekdaysMin : "Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY LT",
+            LLLL : "dddd D MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay : function () {
+                return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+            },
+            nextDay : function () {
+                return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+            },
+            nextWeek : function () {
+                return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+            },
+            lastDay : function () {
+                return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+            },
+            lastWeek : function () {
+                return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "en %s",
+            past : "fa %s",
+            s : "uns segons",
+            m : "un minut",
+            mm : "%d minuts",
+            h : "una hora",
+            hh : "%d hores",
+            d : "un dia",
+            dd : "%d dies",
+            M : "un mes",
+            MM : "%d mesos",
+            y : "un any",
+            yy : "%d anys"
+        },
+        ordinal : '%dº',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/cs.js b/resources/moment/lang/cs.js
new file mode 100644 (file)
index 0000000..c1396cf
--- /dev/null
@@ -0,0 +1,155 @@
+// moment.js language configuration
+// language : czech (cs)
+// author : petrbela : https://github.com/petrbela
+
+(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 months = "leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),
+        monthsShort = "led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_");
+
+    function plural(n) {
+        return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
+    }
+
+    function translate(number, withoutSuffix, key, isFuture) {
+        var result = number + " ";
+        switch (key) {
+        case 's':  // a few seconds / in a few seconds / a few seconds ago
+            return (withoutSuffix || isFuture) ? 'pár vteřin' : 'pár vteřinami';
+        case 'm':  // a minute / in a minute / a minute ago
+            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
+        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'minuty' : 'minut');
+            } else {
+                return result + 'minutami';
+            }
+            break;
+        case 'h':  // an hour / in an hour / an hour ago
+            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
+        case 'hh': // 9 hours / in 9 hours / 9 hours ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'hodiny' : 'hodin');
+            } else {
+                return result + 'hodinami';
+            }
+            break;
+        case 'd':  // a day / in a day / a day ago
+            return (withoutSuffix || isFuture) ? 'den' : 'dnem';
+        case 'dd': // 9 days / in 9 days / 9 days ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'dny' : 'dní');
+            } else {
+                return result + 'dny';
+            }
+            break;
+        case 'M':  // a month / in a month / a month ago
+            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
+        case 'MM': // 9 months / in 9 months / 9 months ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'měsíce' : 'měsíců');
+            } else {
+                return result + 'měsíci';
+            }
+            break;
+        case 'y':  // a year / in a year / a year ago
+            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
+        case 'yy': // 9 years / in 9 years / 9 years ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'roky' : 'let');
+            } else {
+                return result + 'lety';
+            }
+            break;
+        }
+    }
+
+    return moment.lang('cs', {
+        months : months,
+        monthsShort : monthsShort,
+        monthsParse : (function (months, monthsShort) {
+            var i, _monthsParse = [];
+            for (i = 0; i < 12; i++) {
+                // use custom parser to solve problem with July (červenec)
+                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
+            }
+            return _monthsParse;
+        }(months, monthsShort)),
+        weekdays : "neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),
+        weekdaysShort : "ne_po_út_st_čt_pá_so".split("_"),
+        weekdaysMin : "ne_po_út_st_čt_pá_so".split("_"),
+        longDateFormat : {
+            LT: "H:mm",
+            L : "DD.MM.YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY LT",
+            LLLL : "dddd D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay: "[dnes v] LT",
+            nextDay: '[zítra v] LT',
+            nextWeek: function () {
+                switch (this.day()) {
+                case 0:
+                    return '[v neděli v] LT';
+                case 1:
+                case 2:
+                    return '[v] dddd [v] LT';
+                case 3:
+                    return '[ve středu v] LT';
+                case 4:
+                    return '[ve čtvrtek v] LT';
+                case 5:
+                    return '[v pátek v] LT';
+                case 6:
+                    return '[v sobotu v] LT';
+                }
+            },
+            lastDay: '[včera v] LT',
+            lastWeek: function () {
+                switch (this.day()) {
+                case 0:
+                    return '[minulou neděli v] LT';
+                case 1:
+                case 2:
+                    return '[minulé] dddd [v] LT';
+                case 3:
+                    return '[minulou středu v] LT';
+                case 4:
+                case 5:
+                    return '[minulý] dddd [v] LT';
+                case 6:
+                    return '[minulou sobotu v] LT';
+                }
+            },
+            sameElse: "L"
+        },
+        relativeTime : {
+            future : "za %s",
+            past : "před %s",
+            s : translate,
+            m : translate,
+            mm : translate,
+            h : translate,
+            hh : translate,
+            d : translate,
+            dd : translate,
+            M : translate,
+            MM : translate,
+            y : translate,
+            yy : translate
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/cv.js b/resources/moment/lang/cv.js
new file mode 100644 (file)
index 0000000..a5812de
--- /dev/null
@@ -0,0 +1,59 @@
+// moment.js language configuration
+// language : chuvash (cv)
+// author : Anatoly Mironov : https://github.com/mirontoli
+
+(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.lang('cv', {
+        months : "кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав".split("_"),
+        monthsShort : "кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш".split("_"),
+        weekdays : "вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун".split("_"),
+        weekdaysShort : "выр_тун_ытл_юн_кĕç_эрн_шăм".split("_"),
+        weekdaysMin : "вр_тн_ыт_юн_кç_эр_шм".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "DD-MM-YYYY",
+            LL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]",
+            LLL : "YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT",
+            LLLL : "dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT"
+        },
+        calendar : {
+            sameDay: '[Паян] LT [сехетре]',
+            nextDay: '[Ыран] LT [сехетре]',
+            lastDay: '[Ĕнер] LT [сехетре]',
+            nextWeek: '[Çитес] dddd LT [сехетре]',
+            lastWeek: '[Иртнĕ] dddd LT [сехетре]',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : function (output) {
+                var affix = /сехет$/i.exec(output) ? "рен" : /çул$/i.exec(output) ? "тан" : "ран";
+                return output + affix;
+            },
+            past : "%s каялла",
+            s : "пĕр-ик çеккунт",
+            m : "пĕр минут",
+            mm : "%d минут",
+            h : "пĕр сехет",
+            hh : "%d сехет",
+            d : "пĕр кун",
+            dd : "%d кун",
+            M : "пĕр уйăх",
+            MM : "%d уйăх",
+            y : "пĕр çул",
+            yy : "%d çул"
+        },
+        ordinal : '%d-мĕш',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/cy.js b/resources/moment/lang/cy.js
new file mode 100644 (file)
index 0000000..b47d7c2
--- /dev/null
@@ -0,0 +1,77 @@
+// moment.js language configuration
+// language : Welsh (cy)
+// author : Robert Allen
+
+(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.lang("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("_"),
+        weekdaysShort: "Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),
+        weekdaysMin: "Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),
+        // time formats are the same as en-gb
+        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: '[Heddiw am] LT',
+            nextDay: '[Yfory am] LT',
+            nextWeek: 'dddd [am] LT',
+            lastDay: '[Ddoe am] LT',
+            lastWeek: 'dddd [diwethaf am] LT',
+            sameElse: 'L'
+        },
+        relativeTime: {
+            future: "mewn %s",
+            past: "%s yn àl",
+            s: "ychydig eiliadau",
+            m: "munud",
+            mm: "%d munud",
+            h: "awr",
+            hh: "%d awr",
+            d: "diwrnod",
+            dd: "%d diwrnod",
+            M: "mis",
+            MM: "%d mis",
+            y: "blwyddyn",
+            yy: "%d flynedd"
+        },
+        // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
+        ordinal: function (number) {
+            var b = number,
+                output = '',
+                lookup = [
+                    '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
+                    'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
+                ];
+
+            if (b > 20) {
+                if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
+                    output = 'fed'; // not 30ain, 70ain or 90ain
+                } else {
+                    output = 'ain';
+                }
+            } else if (b > 0) {
+                output = lookup[b];
+            }
+
+            return number + output;
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/da.js b/resources/moment/lang/da.js
new file mode 100644 (file)
index 0000000..2fa8244
--- /dev/null
@@ -0,0 +1,56 @@
+// moment.js language configuration
+// language : danish (da)
+// author : Ulrik Nielsen : https://github.com/mrbase
+
+(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.lang('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("_"),
+        weekdaysShort : "søn_man_tir_ons_tor_fre_lør".split("_"),
+        weekdaysMin : "sø_ma_ti_on_to_fr_lø".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 : '[I dag kl.] LT',
+            nextDay : '[I morgen kl.] LT',
+            nextWeek : 'dddd [kl.] LT',
+            lastDay : '[I går kl.] LT',
+            lastWeek : '[sidste] dddd [kl] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "om %s",
+            past : "%s siden",
+            s : "få sekunder",
+            m : "et minut",
+            mm : "%d minutter",
+            h : "en time",
+            hh : "%d timer",
+            d : "en dag",
+            dd : "%d dage",
+            M : "en måned",
+            MM : "%d måneder",
+            y : "et år",
+            yy : "%d år"
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/de.js b/resources/moment/lang/de.js
new file mode 100644 (file)
index 0000000..988f328
--- /dev/null
@@ -0,0 +1,71 @@
+// moment.js language configuration
+// language : german (de)
+// author : lluchs : https://github.com/lluchs
+// 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 processRelativeTime(number, withoutSuffix, key, isFuture) {
+        var format = {
+            'm': ['eine Minute', 'einer Minute'],
+            'h': ['eine Stunde', 'einer Stunde'],
+            'd': ['ein Tag', 'einem Tag'],
+            'dd': [number + ' Tage', number + ' Tagen'],
+            'M': ['ein Monat', 'einem Monat'],
+            'MM': [number + ' Monate', number + ' Monaten'],
+            'y': ['ein Jahr', 'einem Jahr'],
+            'yy': [number + ' Jahre', number + ' Jahren']
+        };
+        return withoutSuffix ? format[key][0] : format[key][1];
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),
+        weekdaysMin : "So_Mo_Di_Mi_Do_Fr_Sa".split("_"),
+        longDateFormat : {
+            LT: "H:mm [Uhr]",
+            L : "DD.MM.YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY LT",
+            LLLL : "dddd, D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay: "[Heute um] LT",
+            sameElse: "L",
+            nextDay: '[Morgen um] LT',
+            nextWeek: 'dddd [um] LT',
+            lastDay: '[Gestern um] LT',
+            lastWeek: '[letzten] dddd [um] LT'
+        },
+        relativeTime : {
+            future : "in %s",
+            past : "vor %s",
+            s : "ein paar Sekunden",
+            m : processRelativeTime,
+            mm : "%d Minuten",
+            h : processRelativeTime,
+            hh : "%d Stunden",
+            d : processRelativeTime,
+            dd : processRelativeTime,
+            M : processRelativeTime,
+            MM : processRelativeTime,
+            y : processRelativeTime,
+            yy : processRelativeTime
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/el.js b/resources/moment/lang/el.js
new file mode 100644 (file)
index 0000000..9dfea23
--- /dev/null
@@ -0,0 +1,79 @@
+// moment.js language configuration
+// language : modern greek (el)
+// author : Aggelos Karalias : https://github.com/mehiel
+
+(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.lang('el', {
+        monthsNominativeEl : "Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),
+        monthsGenitiveEl : "Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),
+        months : function (momentToFormat, format) {
+            if (/D/.test(format.substring(0, format.indexOf("MMMM")))) { // if there is a day number before 'MMMM'
+                return this._monthsGenitiveEl[momentToFormat.month()];
+            } else {
+                return this._monthsNominativeEl[momentToFormat.month()];
+            }
+        },
+        monthsShort : "Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),
+        weekdays : "Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),
+        weekdaysShort : "Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),
+        weekdaysMin : "Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),
+        meridiem : function (hours, minutes, isLower) {
+            if (hours > 11) {
+                return isLower ? 'μμ' : 'ΜΜ';
+            } else {
+                return isLower ? 'πμ' : 'ΠΜ';
+            }
+        },
+        longDateFormat : {
+            LT : "h:mm A",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY LT",
+            LLLL : "dddd, D MMMM YYYY LT"
+        },
+        calendarEl : {
+            sameDay : '[Σήμερα {}] LT',
+            nextDay : '[Αύριο {}] LT',
+            nextWeek : 'dddd [{}] LT',
+            lastDay : '[Χθες {}] LT',
+            lastWeek : '[την προηγούμενη] dddd [{}] LT',
+            sameElse : 'L'
+        },
+        calendar : function (key, mom) {
+            var output = this._calendarEl[key],
+                hours = mom && mom.hours();
+
+            return output.replace("{}", (hours % 12 === 1 ? "στη" : "στις"));
+        },
+        relativeTime : {
+            future : "σε %s",
+            past : "%s πριν",
+            s : "δευτερόλεπτα",
+            m : "ένα λεπτό",
+            mm : "%d λεπτά",
+            h : "μία ώρα",
+            hh : "%d ώρες",
+            d : "μία μέρα",
+            dd : "%d μέρες",
+            M : "ένας μήνας",
+            MM : "%d μήνες",
+            y : "ένας χρόνος",
+            yy : "%d χρόνια"
+        },
+        ordinal : function (number) {
+            return number + 'η';
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4st is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/en-au.js b/resources/moment/lang/en-au.js
new file mode 100644 (file)
index 0000000..4d91e25
--- /dev/null
@@ -0,0 +1,62 @@
+// moment.js language configuration
+// language : australian english (en-au)
+
+(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.lang('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("_"),
+        weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+        weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+        longDateFormat : {
+            LT : "h:mm A",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY LT",
+            LLLL : "dddd, D MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay : '[Today at] LT',
+            nextDay : '[Tomorrow at] LT',
+            nextWeek : 'dddd [at] LT',
+            lastDay : '[Yesterday at] LT',
+            lastWeek : '[Last] dddd [at] LT',
+            sameElse : 'L'
+        },
+        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"
+        },
+        ordinal : function (number) {
+            var b = number % 10,
+                output = (~~ (number % 100 / 10) === 1) ? 'th' :
+                (b === 1) ? 'st' :
+                (b === 2) ? 'nd' :
+                (b === 3) ? 'rd' : 'th';
+            return number + output;
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/en-ca.js b/resources/moment/lang/en-ca.js
new file mode 100644 (file)
index 0000000..a97e9f3
--- /dev/null
@@ -0,0 +1,59 @@
+// moment.js language configuration
+// language : canadian english (en-ca)
+// author : Jonathan Abourbih : https://github.com/jonbca
+
+(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.lang('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("_"),
+        weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+        weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+        longDateFormat : {
+            LT : "h:mm A",
+            L : "YYYY-MM-DD",
+            LL : "D MMMM, YYYY",
+            LLL : "D MMMM, YYYY LT",
+            LLLL : "dddd, D MMMM, YYYY LT"
+        },
+        calendar : {
+            sameDay : '[Today at] LT',
+            nextDay : '[Tomorrow at] LT',
+            nextWeek : 'dddd [at] LT',
+            lastDay : '[Yesterday at] LT',
+            lastWeek : '[Last] dddd [at] LT',
+            sameElse : 'L'
+        },
+        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"
+        },
+        ordinal : function (number) {
+            var b = number % 10,
+                output = (~~ (number % 100 / 10) === 1) ? 'th' :
+                (b === 1) ? 'st' :
+                (b === 2) ? 'nd' :
+                (b === 3) ? 'rd' : 'th';
+            return number + output;
+        }
+    });
+}));
diff --git a/resources/moment/lang/en-gb.js b/resources/moment/lang/en-gb.js
new file mode 100644 (file)
index 0000000..3a7907b
--- /dev/null
@@ -0,0 +1,63 @@
+// moment.js language configuration
+// language : great britain english (en-gb)
+// author : Chris Gedrim : https://github.com/chrisgedrim
+
+(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.lang('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("_"),
+        weekdaysShort : "Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),
+        weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".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 : '[Today at] LT',
+            nextDay : '[Tomorrow at] LT',
+            nextWeek : 'dddd [at] LT',
+            lastDay : '[Yesterday at] LT',
+            lastWeek : '[Last] dddd [at] LT',
+            sameElse : 'L'
+        },
+        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"
+        },
+        ordinal : function (number) {
+            var b = number % 10,
+                output = (~~ (number % 100 / 10) === 1) ? 'th' :
+                (b === 1) ? 'st' :
+                (b === 2) ? 'nd' :
+                (b === 3) ? 'rd' : 'th';
+            return number + output;
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/eo.js b/resources/moment/lang/eo.js
new file mode 100644 (file)
index 0000000..03b1abf
--- /dev/null
@@ -0,0 +1,65 @@
+// moment.js language configuration
+// language : 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!
+
+(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.lang('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("_"),
+        weekdaysShort : "Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab".split("_"),
+        weekdaysMin : "Di_Lu_Ma_Me_Ĵa_Ve_Sa".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "YYYY-MM-DD",
+            LL : "D[-an de] MMMM, YYYY",
+            LLL : "D[-an de] MMMM, YYYY LT",
+            LLLL : "dddd, [la] D[-an de] MMMM, YYYY LT"
+        },
+        meridiem : function (hours, minutes, isLower) {
+            if (hours > 11) {
+                return isLower ? 'p.t.m.' : 'P.T.M.';
+            } else {
+                return isLower ? 'a.t.m.' : 'A.T.M.';
+            }
+        },
+        calendar : {
+            sameDay : '[Hodiaŭ je] LT',
+            nextDay : '[Morgaŭ je] LT',
+            nextWeek : 'dddd [je] LT',
+            lastDay : '[Hieraŭ je] LT',
+            lastWeek : '[pasinta] dddd [je] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "je %s",
+            past : "antaŭ %s",
+            s : "sekundoj",
+            m : "minuto",
+            mm : "%d minutoj",
+            h : "horo",
+            hh : "%d horoj",
+            d : "tago",//ne 'diurno', ĉar estas uzita por proksimumo
+            dd : "%d tagoj",
+            M : "monato",
+            MM : "%d monatoj",
+            y : "jaro",
+            yy : "%d jaroj"
+        },
+        ordinal : "%da",
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/es.js b/resources/moment/lang/es.js
new file mode 100644 (file)
index 0000000..0a38396
--- /dev/null
@@ -0,0 +1,66 @@
+// moment.js language configuration
+// language : spanish (es)
+// author : Julio Napurí : https://github.com/julionc
+
+(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.lang('es', {
+        months : "enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),
+        monthsShort : "ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),
+        weekdays : "domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),
+        weekdaysShort : "dom._lun._mar._mié._jue._vie._sáb.".split("_"),
+        weekdaysMin : "Do_Lu_Ma_Mi_Ju_Vi_Sá".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD/MM/YYYY",
+            LL : "D [de] MMMM [de] YYYY",
+            LLL : "D [de] MMMM [de] YYYY LT",
+            LLLL : "dddd, D [de] MMMM [de] YYYY LT"
+        },
+        calendar : {
+            sameDay : function () {
+                return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+            },
+            nextDay : function () {
+                return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+            },
+            nextWeek : function () {
+                return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+            },
+            lastDay : function () {
+                return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+            },
+            lastWeek : function () {
+                return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "en %s",
+            past : "hace %s",
+            s : "unos segundos",
+            m : "un minuto",
+            mm : "%d minutos",
+            h : "una hora",
+            hh : "%d horas",
+            d : "un día",
+            dd : "%d días",
+            M : "un mes",
+            MM : "%d meses",
+            y : "un año",
+            yy : "%d años"
+        },
+        ordinal : '%dº',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/et.js b/resources/moment/lang/et.js
new file mode 100644 (file)
index 0000000..fb410ef
--- /dev/null
@@ -0,0 +1,76 @@
+// moment.js language configuration
+// language : estonian (et)
+// author : Henry Kehlmann : https://github.com/madhenry
+// improvements : Illimar Tambek : https://github.com/ragulka
+
+(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 processRelativeTime(number, withoutSuffix, key, isFuture) {
+        var format = {
+            's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],
+            'm' : ['ühe minuti', 'üks minut'],
+            'mm': [number + ' minuti', number + ' minutit'],
+            'h' : ['ühe tunni', 'tund aega', 'üks tund'],
+            'hh': [number + ' tunni', number + ' tundi'],
+            'd' : ['ühe päeva', 'üks päev'],
+            'M' : ['kuu aja', 'kuu aega', 'üks kuu'],
+            'MM': [number + ' kuu', number + ' kuud'],
+            'y' : ['ühe aasta', 'aasta', 'üks aasta'],
+            'yy': [number + ' aasta', number + ' aastat']
+        };
+        if (withoutSuffix) {
+            return format[key][2] ? format[key][2] : format[key][1];
+        }
+        return isFuture ? format[key][0] : format[key][1];
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "P_E_T_K_N_R_L".split("_"),
+        weekdaysMin   : "P_E_T_K_N_R_L".split("_"),
+        longDateFormat : {
+            LT   : "H:mm",
+            L    : "DD.MM.YYYY",
+            LL   : "D. MMMM YYYY",
+            LLL  : "D. MMMM YYYY LT",
+            LLLL : "dddd, D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay  : '[Täna,] LT',
+            nextDay  : '[Homme,] LT',
+            nextWeek : '[Järgmine] dddd LT',
+            lastDay  : '[Eile,] LT',
+            lastWeek : '[Eelmine] dddd LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s pärast",
+            past   : "%s tagasi",
+            s      : processRelativeTime,
+            m      : processRelativeTime,
+            mm     : processRelativeTime,
+            h      : processRelativeTime,
+            hh     : processRelativeTime,
+            d      : processRelativeTime,
+            dd     : '%d päeva',
+            M      : processRelativeTime,
+            MM     : processRelativeTime,
+            y      : processRelativeTime,
+            yy     : processRelativeTime
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/eu.js b/resources/moment/lang/eu.js
new file mode 100644 (file)
index 0000000..659b739
--- /dev/null
@@ -0,0 +1,60 @@
+// moment.js language configuration
+// language : euskara (eu)
+// author : Eneko Illarramendi : https://github.com/eillarra
+
+(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.lang('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("_"),
+        weekdaysShort : "ig._al._ar._az._og._ol._lr.".split("_"),
+        weekdaysMin : "ig_al_ar_az_og_ol_lr".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "YYYY-MM-DD",
+            LL : "YYYY[ko] MMMM[ren] D[a]",
+            LLL : "YYYY[ko] MMMM[ren] D[a] LT",
+            LLLL : "dddd, YYYY[ko] MMMM[ren] D[a] LT",
+            l : "YYYY-M-D",
+            ll : "YYYY[ko] MMM D[a]",
+            lll : "YYYY[ko] MMM D[a] LT",
+            llll : "ddd, YYYY[ko] MMM D[a] LT"
+        },
+        calendar : {
+            sameDay : '[gaur] LT[etan]',
+            nextDay : '[bihar] LT[etan]',
+            nextWeek : 'dddd LT[etan]',
+            lastDay : '[atzo] LT[etan]',
+            lastWeek : '[aurreko] dddd LT[etan]',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s barru",
+            past : "duela %s",
+            s : "segundo batzuk",
+            m : "minutu bat",
+            mm : "%d minutu",
+            h : "ordu bat",
+            hh : "%d ordu",
+            d : "egun bat",
+            dd : "%d egun",
+            M : "hilabete bat",
+            MM : "%d hilabete",
+            y : "urte bat",
+            yy : "%d urte"
+        },
+        ordinal : '%d.',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/fa.js b/resources/moment/lang/fa.js
new file mode 100644 (file)
index 0000000..4a690c4
--- /dev/null
@@ -0,0 +1,97 @@
+// moment.js language configuration
+// language : Persian Language
+// author : Ebrahim Byagowi : https://github.com/ebraminio
+
+(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.lang('fa', {
+        months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
+        monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),
+        weekdays : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.split('_'),
+        weekdaysShort : 'یک\u200cشنبه_دوشنبه_سه\u200cشنبه_چهارشنبه_پنج\u200cشنبه_جمعه_شنبه'.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'
+        },
+        meridiem : function (hour, minute, isLower) {
+            if (hour < 12) {
+                return "قبل از ظهر";
+            } else {
+                return "بعد از ظهر";
+            }
+        },
+        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];
+            }).replace(/،/g, ',');
+        },
+        postformat: function (string) {
+            return string.replace(/\d/g, function (match) {
+                return symbolMap[match];
+            }).replace(/,/g, '،');
+        },
+        ordinal : '%dم',
+        week : {
+            dow : 6, // Saturday is the first day of the week.
+            doy : 12 // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/fi.js b/resources/moment/lang/fi.js
new file mode 100644 (file)
index 0000000..18529c1
--- /dev/null
@@ -0,0 +1,103 @@
+// moment.js language configuration
+// language : finnish (fi)
+// author : Tarmo Aidantausta : https://github.com/bleadof
+
+(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 numbers_past = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),
+        numbers_future = ['nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',
+                          numbers_past[7], numbers_past[8], numbers_past[9]];
+
+    function translate(number, withoutSuffix, key, isFuture) {
+        var result = "";
+        switch (key) {
+        case 's':
+            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';
+        case 'm':
+            return isFuture ? 'minuutin' : 'minuutti';
+        case 'mm':
+            result = isFuture ? 'minuutin' : 'minuuttia';
+            break;
+        case 'h':
+            return isFuture ? 'tunnin' : 'tunti';
+        case 'hh':
+            result = isFuture ? 'tunnin' : 'tuntia';
+            break;
+        case 'd':
+            return isFuture ? 'päivän' : 'päivä';
+        case 'dd':
+            result = isFuture ? 'päivän' : 'päivää';
+            break;
+        case 'M':
+            return isFuture ? 'kuukauden' : 'kuukausi';
+        case 'MM':
+            result = isFuture ? 'kuukauden' : 'kuukautta';
+            break;
+        case 'y':
+            return isFuture ? 'vuoden' : 'vuosi';
+        case 'yy':
+            result = isFuture ? 'vuoden' : 'vuotta';
+            break;
+        }
+        result = verbal_number(number, isFuture) + " " + result;
+        return result;
+    }
+
+    function verbal_number(number, isFuture) {
+        return number < 10 ? (isFuture ? numbers_future[number] : numbers_past[number]) : number;
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "su_ma_ti_ke_to_pe_la".split("_"),
+        weekdaysMin : "su_ma_ti_ke_to_pe_la".split("_"),
+        longDateFormat : {
+            LT : "HH.mm",
+            L : "DD.MM.YYYY",
+            LL : "Do MMMM[ta] YYYY",
+            LLL : "Do MMMM[ta] YYYY, [klo] LT",
+            LLLL : "dddd, Do MMMM[ta] YYYY, [klo] LT",
+            l : "D.M.YYYY",
+            ll : "Do MMM YYYY",
+            lll : "Do MMM YYYY, [klo] LT",
+            llll : "ddd, Do MMM YYYY, [klo] LT"
+        },
+        calendar : {
+            sameDay : '[tänään] [klo] LT',
+            nextDay : '[huomenna] [klo] LT',
+            nextWeek : 'dddd [klo] LT',
+            lastDay : '[eilen] [klo] LT',
+            lastWeek : '[viime] dddd[na] [klo] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s päästä",
+            past : "%s sitten",
+            s : translate,
+            m : translate,
+            mm : translate,
+            h : translate,
+            hh : translate,
+            d : translate,
+            dd : translate,
+            M : translate,
+            MM : translate,
+            y : translate,
+            yy : translate
+        },
+        ordinal : "%d.",
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/fo.js b/resources/moment/lang/fo.js
new file mode 100644 (file)
index 0000000..2f1cbb8
--- /dev/null
@@ -0,0 +1,56 @@
+// moment.js language configuration
+// language : faroese (fo)
+// author : Ragnar Johannesen : https://github.com/ragnar123
+
+(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.lang('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("_"),
+        weekdaysShort : "sun_mán_týs_mik_hós_frí_ley".split("_"),
+        weekdaysMin : "su_má_tý_mi_hó_fr_le".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 : '[Í dag kl.] LT',
+            nextDay : '[Í morgin kl.] LT',
+            nextWeek : 'dddd [kl.] LT',
+            lastDay : '[Í gjár kl.] LT',
+            lastWeek : '[síðstu] dddd [kl] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "um %s",
+            past : "%s síðani",
+            s : "fá sekund",
+            m : "ein minutt",
+            mm : "%d minuttir",
+            h : "ein tími",
+            hh : "%d tímar",
+            d : "ein dagur",
+            dd : "%d dagar",
+            M : "ein mánaði",
+            MM : "%d mánaðir",
+            y : "eitt ár",
+            yy : "%d ár"
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/fr-ca.js b/resources/moment/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..3280d79
--- /dev/null
@@ -0,0 +1,54 @@
+// moment.js language configuration
+// language : canadian french (fr-ca)
+// author : Jonathan Abourbih : https://github.com/jonbca
+
+(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.lang('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("_"),
+        weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"),
+        weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "YYYY-MM-DD",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY LT",
+            LLLL : "dddd D MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay: "[Aujourd'hui à] LT",
+            nextDay: '[Demain à] LT',
+            nextWeek: 'dddd [à] LT',
+            lastDay: '[Hier à] LT',
+            lastWeek: 'dddd [dernier à] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "dans %s",
+            past : "il y a %s",
+            s : "quelques secondes",
+            m : "une minute",
+            mm : "%d minutes",
+            h : "une heure",
+            hh : "%d heures",
+            d : "un jour",
+            dd : "%d jours",
+            M : "un mois",
+            MM : "%d mois",
+            y : "un an",
+            yy : "%d ans"
+        },
+        ordinal : function (number) {
+            return number + (number === 1 ? 'er' : '');
+        }
+    });
+}));
diff --git a/resources/moment/lang/fr.js b/resources/moment/lang/fr.js
new file mode 100644 (file)
index 0000000..6b3dc52
--- /dev/null
@@ -0,0 +1,58 @@
+// moment.js language configuration
+// language : french (fr)
+// author : John Fischer : https://github.com/jfroffice
+
+(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.lang('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("_"),
+        weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"),
+        weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".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: "[Aujourd'hui à] LT",
+            nextDay: '[Demain à] LT',
+            nextWeek: 'dddd [à] LT',
+            lastDay: '[Hier à] LT',
+            lastWeek: 'dddd [dernier à] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "dans %s",
+            past : "il y a %s",
+            s : "quelques secondes",
+            m : "une minute",
+            mm : "%d minutes",
+            h : "une heure",
+            hh : "%d heures",
+            d : "un jour",
+            dd : "%d jours",
+            M : "un mois",
+            MM : "%d mois",
+            y : "un an",
+            yy : "%d ans"
+        },
+        ordinal : function (number) {
+            return number + (number === 1 ? 'er' : '');
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/gl.js b/resources/moment/lang/gl.js
new file mode 100644 (file)
index 0000000..8b14127
--- /dev/null
@@ -0,0 +1,71 @@
+// moment.js language configuration
+// language : galician (gl)
+// author : Juan G. Hurtado : https://github.com/juanghurtado
+
+(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.lang('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("_"),
+        weekdaysShort : "Dom._Lun._Mar._Mér._Xov._Ven._Sáb.".split("_"),
+        weekdaysMin : "Do_Lu_Ma_Mé_Xo_Ve_Sá".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY LT",
+            LLLL : "dddd D MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay : function () {
+                return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
+            },
+            nextDay : function () {
+                return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';
+            },
+            nextWeek : function () {
+                return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
+            },
+            lastDay : function () {
+                return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';
+            },
+            lastWeek : function () {
+                return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : function (str) {
+                if (str === "uns segundos") {
+                    return "nuns segundos";
+                }
+                return "en " + str;
+            },
+            past : "hai %s",
+            s : "uns segundos",
+            m : "un minuto",
+            mm : "%d minutos",
+            h : "unha hora",
+            hh : "%d horas",
+            d : "un día",
+            dd : "%d días",
+            M : "un mes",
+            MM : "%d meses",
+            y : "un ano",
+            yy : "%d anos"
+        },
+        ordinal : '%dº',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/he.js b/resources/moment/lang/he.js
new file mode 100644 (file)
index 0000000..b85dbe8
--- /dev/null
@@ -0,0 +1,77 @@
+// moment.js language configuration
+// language : Hebrew (he)
+// author : Tomer Cohen : https://github.com/tomer
+// author : Moshe Simantov : https://github.com/DevelopmentIL
+// author : Tal Ater : https://github.com/TalAter
+
+(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.lang('he', {
+        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",
+            l : "D/M/YYYY",
+            ll : "D MMM YYYY",
+            lll : "D MMM YYYY LT",
+            llll : "ddd, D MMM 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 : function (number) {
+                if (number === 2) {
+                    return "שעתיים";
+                }
+                return number + " שעות";
+            },
+            d : "יום",
+            dd : function (number) {
+                if (number === 2) {
+                    return "יומיים";
+                }
+                return number + " ימים";
+            },
+            M : "חודש",
+            MM : function (number) {
+                if (number === 2) {
+                    return "חודשיים";
+                }
+                return number + " חודשים";
+            },
+            y : "שנה",
+            yy : function (number) {
+                if (number === 2) {
+                    return "שנתיים";
+                }
+                return number + " שנים";
+            }
+        }
+    });
+}));
diff --git a/resources/moment/lang/hi.js b/resources/moment/lang/hi.js
new file mode 100644 (file)
index 0000000..8e6e99c
--- /dev/null
@@ -0,0 +1,105 @@
+// moment.js language configuration
+// language : hindi (hi)
+// author : Mayank Singhal : https://github.com/mayanksinghal
+
+(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.lang('hi', {
+        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 : '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];
+            });
+        },
+        // Hindi notation for meridiems are quite fuzzy in practice. While there exists
+        // a rigid notion of a 'Pahar' it is not used as rigidly in modern Hindi.
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/hr.js b/resources/moment/lang/hr.js
new file mode 100644 (file)
index 0000000..2e3bf11
--- /dev/null
@@ -0,0 +1,140 @@
+// moment.js language configuration
+// language : hrvatski (hr)
+// author : Bojan Marković : https://github.com/bmarkovic
+
+// based on (sl) translation by Robert Sedovšek
+
+(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 translate(number, withoutSuffix, key) {
+        var result = number + " ";
+        switch (key) {
+        case 'm':
+            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
+        case 'mm':
+            if (number === 1) {
+                result += 'minuta';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'minute';
+            } else {
+                result += 'minuta';
+            }
+            return result;
+        case 'h':
+            return withoutSuffix ? 'jedan sat' : 'jednog sata';
+        case 'hh':
+            if (number === 1) {
+                result += 'sat';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'sata';
+            } else {
+                result += 'sati';
+            }
+            return result;
+        case 'dd':
+            if (number === 1) {
+                result += 'dan';
+            } else {
+                result += 'dana';
+            }
+            return result;
+        case 'MM':
+            if (number === 1) {
+                result += 'mjesec';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'mjeseca';
+            } else {
+                result += 'mjeseci';
+            }
+            return result;
+        case 'yy':
+            if (number === 1) {
+                result += 'godina';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'godine';
+            } else {
+                result += 'godina';
+            }
+            return result;
+        }
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "ned._pon._uto._sri._čet._pet._sub.".split("_"),
+        weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD. MM. YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY LT",
+            LLLL : "dddd, D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay  : '[danas u] LT',
+            nextDay  : '[sutra u] LT',
+
+            nextWeek : function () {
+                switch (this.day()) {
+                case 0:
+                    return '[u] [nedjelju] [u] LT';
+                case 3:
+                    return '[u] [srijedu] [u] LT';
+                case 6:
+                    return '[u] [subotu] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[u] dddd [u] LT';
+                }
+            },
+            lastDay  : '[jučer u] LT',
+            lastWeek : function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                    return '[prošlu] dddd [u] LT';
+                case 6:
+                    return '[prošle] [subote] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[prošli] dddd [u] LT';
+                }
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "za %s",
+            past   : "prije %s",
+            s      : "par sekundi",
+            m      : translate,
+            mm     : translate,
+            h      : translate,
+            hh     : translate,
+            d      : "dan",
+            dd     : translate,
+            M      : "mjesec",
+            MM     : translate,
+            y      : "godinu",
+            yy     : translate
+        },
+        ordinal : '%d.',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/hu.js b/resources/moment/lang/hu.js
new file mode 100644 (file)
index 0000000..4d84ebd
--- /dev/null
@@ -0,0 +1,98 @@
+// moment.js language configuration
+// language : hungarian (hu)
+// author : Adam Brunner : https://github.com/adambrunner
+
+(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 weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');
+
+    function translate(number, withoutSuffix, key, isFuture) {
+        var num = number,
+            suffix;
+
+        switch (key) {
+        case 's':
+            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';
+        case 'm':
+            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');
+        case 'mm':
+            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');
+        case 'h':
+            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');
+        case 'hh':
+            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');
+        case 'd':
+            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');
+        case 'dd':
+            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');
+        case 'M':
+            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
+        case 'MM':
+            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');
+        case 'y':
+            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');
+        case 'yy':
+            return num + (isFuture || withoutSuffix ? ' év' : ' éve');
+        }
+
+        return '';
+    }
+
+    function week(isFuture) {
+        return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "vas_hét_kedd_sze_csüt_pén_szo".split("_"),
+        weekdaysMin : "v_h_k_sze_cs_p_szo".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "YYYY.MM.DD.",
+            LL : "YYYY. MMMM D.",
+            LLL : "YYYY. MMMM D., LT",
+            LLLL : "YYYY. MMMM D., dddd LT"
+        },
+        calendar : {
+            sameDay : '[ma] LT[-kor]',
+            nextDay : '[holnap] LT[-kor]',
+            nextWeek : function () {
+                return week.call(this, true);
+            },
+            lastDay : '[tegnap] LT[-kor]',
+            lastWeek : function () {
+                return week.call(this, false);
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s múlva",
+            past : "%s",
+            s : translate,
+            m : translate,
+            mm : translate,
+            h : translate,
+            hh : translate,
+            d : translate,
+            dd : translate,
+            M : translate,
+            MM : translate,
+            y : translate,
+            yy : translate
+        },
+        ordinal : '%d.',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/hy-am.js b/resources/moment/lang/hy-am.js
new file mode 100644 (file)
index 0000000..951655b
--- /dev/null
@@ -0,0 +1,113 @@
+// moment.js language configuration
+// language : Armenian (hy-am)
+// author : Armendarabyan : https://github.com/armendarabyan
+
+(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 monthsCaseReplace(m, format) {
+        var months = {
+            'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),
+            'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')
+        },
+
+        nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+            'accusative' :
+            'nominative';
+
+        return months[nounCase][m.month()];
+    }
+
+    function monthsShortCaseReplace(m, format) {
+        var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');
+
+        return monthsShort[m.month()];
+    }
+
+    function weekdaysCaseReplace(m, format) {
+        var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');
+
+        return weekdays[m.day()];
+    }
+
+    return moment.lang('hy-am', {
+        months : monthsCaseReplace,
+        monthsShort : monthsShortCaseReplace,
+        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 () {
+                return '[անցած] 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 տարի"
+        },
+
+        meridiem : function (hour) {
+            if (hour < 4) {
+                return "գիշերվա";
+            } else if (hour < 12) {
+                return "առավոտվա";
+            } else if (hour < 17) {
+                return "ցերեկվա";
+            } else {
+                return "երեկոյան";
+            }
+        },
+
+        ordinal: function (number, period) {
+            switch (period) {
+            case 'DDD':
+            case 'w':
+            case 'W':
+            case 'DDDo':
+                if (number === 1) {
+                    return number + '-ին';
+                }
+                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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/id.js b/resources/moment/lang/id.js
new file mode 100644 (file)
index 0000000..f186280
--- /dev/null
@@ -0,0 +1,67 @@
+// moment.js language configuration
+// language : Bahasa Indonesia (id)
+// author : Mohammad Satrio Utomo : https://github.com/tyok
+// reference: http://id.wikisource.org/wiki/Pedoman_Umum_Ejaan_Bahasa_Indonesia_yang_Disempurnakan
+
+(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.lang('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("_"),
+        weekdaysShort : "Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),
+        weekdaysMin : "Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),
+        longDateFormat : {
+            LT : "HH.mm",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY [pukul] LT",
+            LLLL : "dddd, D MMMM YYYY [pukul] LT"
+        },
+        meridiem : function (hours, minutes, isLower) {
+            if (hours < 11) {
+                return 'pagi';
+            } else if (hours < 15) {
+                return 'siang';
+            } else if (hours < 19) {
+                return 'sore';
+            } else {
+                return 'malam';
+            }
+        },
+        calendar : {
+            sameDay : '[Hari ini pukul] LT',
+            nextDay : '[Besok pukul] LT',
+            nextWeek : 'dddd [pukul] LT',
+            lastDay : '[Kemarin pukul] LT',
+            lastWeek : 'dddd [lalu pukul] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "dalam %s",
+            past : "%s yang lalu",
+            s : "beberapa detik",
+            m : "semenit",
+            mm : "%d menit",
+            h : "sejam",
+            hh : "%d jam",
+            d : "sehari",
+            dd : "%d hari",
+            M : "sebulan",
+            MM : "%d bulan",
+            y : "setahun",
+            yy : "%d tahun"
+        },
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/is.js b/resources/moment/lang/is.js
new file mode 100644 (file)
index 0000000..5b6b2a8
--- /dev/null
@@ -0,0 +1,124 @@
+// moment.js language configuration
+// language : icelandic (is)
+// author : Hinrik Örn Sigurðsson : https://github.com/hinrik
+
+(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(n) {
+        if (n % 100 === 11) {
+            return true;
+        } else if (n % 10 === 1) {
+            return false;
+        }
+        return true;
+    }
+
+    function translate(number, withoutSuffix, key, isFuture) {
+        var result = number + " ";
+        switch (key) {
+        case 's':
+            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';
+        case 'm':
+            return withoutSuffix ? 'mínúta' : 'mínútu';
+        case 'mm':
+            if (plural(number)) {
+                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');
+            } else if (withoutSuffix) {
+                return result + 'mínúta';
+            }
+            return result + 'mínútu';
+        case 'hh':
+            if (plural(number)) {
+                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');
+            }
+            return result + 'klukkustund';
+        case 'd':
+            if (withoutSuffix) {
+                return 'dagur';
+            }
+            return isFuture ? 'dag' : 'degi';
+        case 'dd':
+            if (plural(number)) {
+                if (withoutSuffix) {
+                    return result + 'dagar';
+                }
+                return result + (isFuture ? 'daga' : 'dögum');
+            } else if (withoutSuffix) {
+                return result + 'dagur';
+            }
+            return result + (isFuture ? 'dag' : 'degi');
+        case 'M':
+            if (withoutSuffix) {
+                return 'mánuður';
+            }
+            return isFuture ? 'mánuð' : 'mánuði';
+        case 'MM':
+            if (plural(number)) {
+                if (withoutSuffix) {
+                    return result + 'mánuðir';
+                }
+                return result + (isFuture ? 'mánuði' : 'mánuðum');
+            } else if (withoutSuffix) {
+                return result + 'mánuður';
+            }
+            return result + (isFuture ? 'mánuð' : 'mánuði');
+        case 'y':
+            return withoutSuffix || isFuture ? 'ár' : 'ári';
+        case 'yy':
+            if (plural(number)) {
+                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');
+            }
+            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');
+        }
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "sun_mán_þri_mið_fim_fös_lau".split("_"),
+        weekdaysMin : "Su_Má_Þr_Mi_Fi_Fö_La".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD/MM/YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY [kl.] LT",
+            LLLL : "dddd, D. MMMM YYYY [kl.] LT"
+        },
+        calendar : {
+            sameDay : '[í dag kl.] LT',
+            nextDay : '[á morgun kl.] LT',
+            nextWeek : 'dddd [kl.] LT',
+            lastDay : '[í gær kl.] LT',
+            lastWeek : '[síðasta] dddd [kl.] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "eftir %s",
+            past : "fyrir %s síðan",
+            s : translate,
+            m : translate,
+            mm : translate,
+            h : "klukkustund",
+            hh : translate,
+            d : translate,
+            dd : translate,
+            M : translate,
+            MM : translate,
+            y : translate,
+            yy : translate
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/it.js b/resources/moment/lang/it.js
new file mode 100644 (file)
index 0000000..84b7698
--- /dev/null
@@ -0,0 +1,59 @@
+// moment.js language configuration
+// language : italian (it)
+// author : Lorenzo : https://github.com/aliem
+// author: Mattia Larentis: https://github.com/nostalgiaz
+
+(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.lang('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("_"),
+        weekdaysShort : "Dom_Lun_Mar_Mer_Gio_Ven_Sab".split("_"),
+        weekdaysMin : "D_L_Ma_Me_G_V_S".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: '[Oggi alle] LT',
+            nextDay: '[Domani alle] LT',
+            nextWeek: 'dddd [alle] LT',
+            lastDay: '[Ieri alle] LT',
+            lastWeek: '[lo scorso] dddd [alle] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : function (s) {
+                return ((/^[0-9].+$/).test(s) ? "tra" : "in") + " " + s;
+            },
+            past : "%s fa",
+            s : "alcuni secondi",
+            m : "un minuto",
+            mm : "%d minuti",
+            h : "un'ora",
+            hh : "%d ore",
+            d : "un giorno",
+            dd : "%d giorni",
+            M : "un mese",
+            MM : "%d mesi",
+            y : "un anno",
+            yy : "%d anni"
+        },
+        ordinal: '%dº',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ja.js b/resources/moment/lang/ja.js
new file mode 100644 (file)
index 0000000..9cd7e9e
--- /dev/null
@@ -0,0 +1,58 @@
+// moment.js language configuration
+// language : japanese (ja)
+// author : LI Long : https://github.com/baryon
+
+(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.lang('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("_"),
+        weekdaysShort : "日_月_火_水_木_金_土".split("_"),
+        weekdaysMin : "日_月_火_水_木_金_土".split("_"),
+        longDateFormat : {
+            LT : "Ah時m分",
+            L : "YYYY/MM/DD",
+            LL : "YYYY年M月D日",
+            LLL : "YYYY年M月D日LT",
+            LLLL : "YYYY年M月D日LT dddd"
+        },
+        meridiem : function (hour, minute, isLower) {
+            if (hour < 12) {
+                return "午前";
+            } else {
+                return "午後";
+            }
+        },
+        calendar : {
+            sameDay : '[今日] LT',
+            nextDay : '[明日] LT',
+            nextWeek : '[来週]dddd LT',
+            lastDay : '[昨日] LT',
+            lastWeek : '[前週]dddd LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s後",
+            past : "%s前",
+            s : "数秒",
+            m : "1分",
+            mm : "%d分",
+            h : "1時間",
+            hh : "%d時間",
+            d : "1日",
+            dd : "%d日",
+            M : "1ヶ月",
+            MM : "%dヶ月",
+            y : "1年",
+            yy : "%d年"
+        }
+    });
+}));
diff --git a/resources/moment/lang/ka.js b/resources/moment/lang/ka.js
new file mode 100644 (file)
index 0000000..0cebdaa
--- /dev/null
@@ -0,0 +1,108 @@
+// moment.js language configuration
+// language : Georgian (ka)
+// author : Irakli Janiashvili : https://github.com/irakli-janiashvili
+
+(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 monthsCaseReplace(m, format) {
+        var months = {
+            'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),
+            'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')
+        },
+
+        nounCase = (/D[oD] *MMMM?/).test(format) ?
+            'accusative' :
+            'nominative';
+
+        return months[nounCase][m.month()];
+    }
+
+    function weekdaysCaseReplace(m, format) {
+        var weekdays = {
+            'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),
+            'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')
+        },
+
+        nounCase = (/(წინა|შემდეგ)/).test(format) ?
+            'accusative' :
+            'nominative';
+
+        return weekdays[nounCase][m.day()];
+    }
+
+    return moment.lang('ka', {
+        months : monthsCaseReplace,
+        monthsShort : "იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),
+        weekdays : weekdaysCaseReplace,
+        weekdaysShort : "კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"),
+        weekdaysMin : "კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"),
+        longDateFormat : {
+            LT : "h:mm A",
+            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 : '[შემდეგ] dddd LT[-ზე]',
+            lastWeek : '[წინა] dddd LT-ზე',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : function (s) {
+                return (/(წამი|წუთი|საათი|წელი)/).test(s) ?
+                    s.replace(/ი$/, "ში") :
+                    s + "ში";
+            },
+            past : function (s) {
+                if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {
+                    return s.replace(/(ი|ე)$/, "ის წინ");
+                }
+                if ((/წელი/).test(s)) {
+                    return s.replace(/წელი$/, "წლის წინ");
+                }
+            },
+            s : "რამდენიმე წამი",
+            m : "წუთი",
+            mm : "%d წუთი",
+            h : "საათი",
+            hh : "%d საათი",
+            d : "დღე",
+            dd : "%d დღე",
+            M : "თვე",
+            MM : "%d თვე",
+            y : "წელი",
+            yy : "%d წელი"
+        },
+        ordinal : function (number) {
+            if (number === 0) {
+                return number;
+            }
+
+            if (number === 1) {
+                return number + "-ლი";
+            }
+
+            if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {
+                return "მე-" + number;
+            }
+
+            return number + "-ე";
+        },
+        week : {
+            dow : 1,
+            doy : 7
+        }
+    });
+}));
diff --git a/resources/moment/lang/ko.js b/resources/moment/lang/ko.js
new file mode 100644 (file)
index 0000000..3b469df
--- /dev/null
@@ -0,0 +1,63 @@
+// moment.js language configuration
+// language : korean (ko)
+//
+// authors 
+//
+// - Kyungwook, Park : https://github.com/kyungw00k
+// - Jeeeyul Lee <jeeeyul@gmail.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) {
+    return moment.lang('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("_"),
+        weekdaysShort : "일_월_화_수_목_금_토".split("_"),
+        weekdaysMin : "일_월_화_수_목_금_토".split("_"),
+        longDateFormat : {
+            LT : "A h시 mm분",
+            L : "YYYY.MM.DD",
+            LL : "YYYY년 MMMM D일",
+            LLL : "YYYY년 MMMM D일 LT",
+            LLLL : "YYYY년 MMMM D일 dddd LT"
+        },
+        meridiem : function (hour, minute, isUpper) {
+            return hour < 12 ? '오전' : '오후';
+        },
+        calendar : {
+            sameDay : '오늘 LT',
+            nextDay : '내일 LT',
+            nextWeek : 'dddd LT',
+            lastDay : '어제 LT',
+            lastWeek : '지난주 dddd LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s 후",
+            past : "%s 전",
+            s : "몇초",
+            ss : "%d초",
+            m : "일분",
+            mm : "%d분",
+            h : "한시간",
+            hh : "%d시간",
+            d : "하루",
+            dd : "%d일",
+            M : "한달",
+            MM : "%d달",
+            y : "일년",
+            yy : "%d년"
+        },
+        ordinal : '%d일',
+        meridiemParse : /(오전|오후)/,
+        isPM : function (token) {
+            return token === "오후";
+        }
+    });
+}));
diff --git a/resources/moment/lang/lb.js b/resources/moment/lang/lb.js
new file mode 100644 (file)
index 0000000..946ba13
--- /dev/null
@@ -0,0 +1,160 @@
+// moment.js language configuration
+// language : Luxembourgish (lb)
+// author : mweimerskirch : https://github.com/mweimerskirch
+
+// 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"
+// and "eifelerRegelAppliesToNumber" methods are meant for
+
+(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 processRelativeTime(number, withoutSuffix, key, isFuture) {
+        var format = {
+            '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']
+        };
+        return withoutSuffix ? format[key][0] : format[key][1];
+    }
+
+    function processFutureTime(string) {
+        var number = string.substr(0, string.indexOf(' '));
+        if (eifelerRegelAppliesToNumber(number)) {
+            return "a " + string;
+        }
+        return "an " + string;
+    }
+
+    function processPastTime(string) {
+        var number = string.substr(0, string.indexOf(' '));
+        if (eifelerRegelAppliesToNumber(number)) {
+            return "viru " + string;
+        }
+        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"
+     *
+     * @param number {integer}
+     * @returns {boolean}
+     */
+    function eifelerRegelAppliesToNumber(number) {
+        number = parseInt(number, 10);
+        if (isNaN(number)) {
+            return false;
+        }
+        if (number < 0) {
+            // Negative Number --> always true
+            return true;
+        } else if (number < 10) {
+            // Only 1 digit
+            if (4 <= number && number <= 7) {
+                return true;
+            }
+            return false;
+        } else if (number < 100) {
+            // 2 digits
+            var lastDigit = number % 10, firstDigit = number / 10;
+            if (lastDigit === 0) {
+                return eifelerRegelAppliesToNumber(firstDigit);
+            }
+            return eifelerRegelAppliesToNumber(lastDigit);
+        } else if (number < 10000) {
+            // 3 or 4 digits --> recursively check first digit
+            while (number >= 10) {
+                number = number / 10;
+            }
+            return eifelerRegelAppliesToNumber(number);
+        } else {
+            // Anything larger than 4 digits: recursively check first n-3 digits
+            number = number / 1000;
+            return eifelerRegelAppliesToNumber(number);
+        }
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort: "So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),
+        weekdaysMin: "So_Mé_Dë_Më_Do_Fr_Sa".split("_"),
+        longDateFormat: {
+            LT: "H:mm [Auer]",
+            L: "DD.MM.YYYY",
+            LL: "D. MMMM YYYY",
+            LLL: "D. MMMM YYYY LT",
+            LLLL: "dddd, D. MMMM YYYY LT"
+        },
+        calendar: {
+            sameDay: "[Haut um] LT",
+            sameElse: "L",
+            nextDay: '[Muer um] LT',
+            nextWeek: 'dddd [um] LT',
+            lastDay: '[Gëschter um] LT',
+            lastWeek: processLastWeek
+        },
+        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
+        },
+        ordinal: '%d.',
+        week: {
+            dow: 1, // Monday is the first day of the week.
+            doy: 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/lt.js b/resources/moment/lang/lt.js
new file mode 100644 (file)
index 0000000..1cf6457
--- /dev/null
@@ -0,0 +1,118 @@
+// moment.js language configuration
+// language : Lithuanian (lt)
+// author : Mindaugas Mozūras : https://github.com/mmozuras
+
+(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 units = {
+        "m" : "minutė_minutės_minutę",
+        "mm": "minutės_minučių_minutes",
+        "h" : "valanda_valandos_valandą",
+        "hh": "valandos_valandų_valandas",
+        "d" : "diena_dienos_dieną",
+        "dd": "dienos_dienų_dienas",
+        "M" : "mėnuo_mėnesio_mėnesį",
+        "MM": "mėnesiai_mėnesių_mėnesius",
+        "y" : "metai_metų_metus",
+        "yy": "metai_metų_metus"
+    },
+    weekDays = "pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis_sekmadienis".split("_");
+
+    function translateSeconds(number, withoutSuffix, key, isFuture) {
+        if (withoutSuffix) {
+            return "kelios sekundės";
+        } else {
+            return isFuture ? "kelių sekundžių" : "kelias sekundes";
+        }
+    }
+
+    function translateSingular(number, withoutSuffix, key, isFuture) {
+        return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);
+    }
+
+    function special(number) {
+        return number % 10 === 0 || (number > 10 && number < 20);
+    }
+
+    function forms(key) {
+        return units[key].split("_");
+    }
+
+    function translate(number, withoutSuffix, key, isFuture) {
+        var result = number + " ";
+        if (number === 1) {
+            return result + translateSingular(number, withoutSuffix, key[0], isFuture);
+        } else if (withoutSuffix) {
+            return result + (special(number) ? forms(key)[1] : forms(key)[0]);
+        } else {
+            if (isFuture) {
+                return result + forms(key)[1];
+            } else {
+                return result + (special(number) ? forms(key)[1] : forms(key)[2]);
+            }
+        }
+    }
+
+    function relativeWeekDay(moment, format) {
+        var nominative = format.indexOf('dddd LT') === -1,
+            weekDay = weekDays[moment.weekday()];
+
+        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("_"),
+        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("_"),
+        weekdaysMin : "S_P_A_T_K_Pn_Š".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "YYYY-MM-DD",
+            LL : "YYYY [m.] MMMM D [d.]",
+            LLL : "YYYY [m.] MMMM D [d.], LT [val.]",
+            LLLL : "YYYY [m.] MMMM D [d.], dddd, LT [val.]",
+            l : "YYYY-MM-DD",
+            ll : "YYYY [m.] MMMM D [d.]",
+            lll : "YYYY [m.] MMMM D [d.], LT [val.]",
+            llll : "YYYY [m.] MMMM D [d.], ddd, LT [val.]"
+        },
+        calendar : {
+            sameDay : "[Šiandien] LT",
+            nextDay : "[Rytoj] LT",
+            nextWeek : "dddd LT",
+            lastDay : "[Vakar] LT",
+            lastWeek : "[Praėjusį] dddd LT",
+            sameElse : "L"
+        },
+        relativeTime : {
+            future : "po %s",
+            past : "prieš %s",
+            s : translateSeconds,
+            m : translateSingular,
+            mm : translate,
+            h : translateSingular,
+            hh : translate,
+            d : translateSingular,
+            dd : translate,
+            M : translateSingular,
+            MM : translate,
+            y : translateSingular,
+            yy : translate
+        },
+        ordinal : function (number) {
+            return number + '-oji';
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/lv.js b/resources/moment/lang/lv.js
new file mode 100644 (file)
index 0000000..ffe25cf
--- /dev/null
@@ -0,0 +1,77 @@
+// moment.js language configuration
+// language : latvian (lv)
+// author : Kristaps Karlsons : https://github.com/skakri
+
+(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 units = {
+        'mm': 'minūti_minūtes_minūte_minūtes',
+        'hh': 'stundu_stundas_stunda_stundas',
+        'dd': 'dienu_dienas_diena_dienas',
+        'MM': 'mēnesi_mēnešus_mēnesis_mēneši',
+        'yy': 'gadu_gadus_gads_gadi'
+    };
+
+    function format(word, number, withoutSuffix) {
+        var forms = word.split('_');
+        if (withoutSuffix) {
+            return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];
+        } else {
+            return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];
+        }
+    }
+
+    function relativeTimeWithPlural(number, withoutSuffix, key) {
+        return number + ' ' + format(units[key], number, withoutSuffix);
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "Sv_P_O_T_C_Pk_S".split("_"),
+        weekdaysMin : "Sv_P_O_T_C_Pk_S".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "DD.MM.YYYY",
+            LL : "YYYY. [gada] D. MMMM",
+            LLL : "YYYY. [gada] D. MMMM, LT",
+            LLLL : "YYYY. [gada] D. MMMM, dddd, LT"
+        },
+        calendar : {
+            sameDay : '[Šodien pulksten] LT',
+            nextDay : '[Rīt pulksten] LT',
+            nextWeek : 'dddd [pulksten] LT',
+            lastDay : '[Vakar pulksten] LT',
+            lastWeek : '[Pagājušā] dddd [pulksten] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s vēlāk",
+            past : "%s agrāk",
+            s : "dažas sekundes",
+            m : "minūti",
+            mm : relativeTimeWithPlural,
+            h : "stundu",
+            hh : relativeTimeWithPlural,
+            d : "dienu",
+            dd : relativeTimeWithPlural,
+            M : "mēnesi",
+            MM : relativeTimeWithPlural,
+            y : "gadu",
+            yy : relativeTimeWithPlural
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/mk.js b/resources/moment/lang/mk.js
new file mode 100644 (file)
index 0000000..5f272fa
--- /dev/null
@@ -0,0 +1,86 @@
+// moment.js language configuration
+// language : macedonian (mk)
+// author : Borislav Mickov : https://github.com/B0k0
+
+(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.lang('mk', {
+        months : "јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),
+        monthsShort : "јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),
+        weekdays : "недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),
+        weekdaysShort : "нед_пон_вто_сре_чет_пет_саб".split("_"),
+        weekdaysMin : "нe_пo_вт_ср_че_пе_сa".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "D.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 : function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                case 6:
+                    return '[Во изминатата] dddd [во] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[Во изминатиот] 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 години"
+        },
+        ordinal : function (number) {
+            var lastDigit = number % 10,
+                last2Digits = number % 100;
+            if (number === 0) {
+                return number + '-ев';
+            } else if (last2Digits === 0) {
+                return number + '-ен';
+            } else if (last2Digits > 10 && last2Digits < 20) {
+                return number + '-ти';
+            } else if (lastDigit === 1) {
+                return number + '-ви';
+            } else if (lastDigit === 2) {
+                return number + '-ри';
+            } else if (lastDigit === 7 || lastDigit === 8) {
+                return number + '-ми';
+            } else {
+                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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ml.js b/resources/moment/lang/ml.js
new file mode 100644 (file)
index 0000000..cc7db9a
--- /dev/null
@@ -0,0 +1,64 @@
+// moment.js language configuration
+// language : malayalam (ml)
+// author : Floyd Pink : https://github.com/floydpink
+
+(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.lang('ml', {
+        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 : '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 വർഷം"
+        },
+        meridiem : function (hour, minute, isLower) {
+            if (hour < 4) {
+                return "രാത്രി";
+            } else if (hour < 12) {
+                return "രാവിലെ";
+            } else if (hour < 17) {
+                return "ഉച്ച കഴിഞ്ഞ്";
+            } else if (hour < 20) {
+                return "വൈകുന്നേരം";
+            } else {
+                return "രാത്രി";
+            }
+        }
+    });
+}));
diff --git a/resources/moment/lang/mr.js b/resources/moment/lang/mr.js
new file mode 100644 (file)
index 0000000..0d1adfd
--- /dev/null
@@ -0,0 +1,104 @@
+// moment.js language configuration
+// language : Marathi (mr)
+// author : Harshad Kale : https://github.com/kalehv
+
+(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.lang('mr', {
+        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 : '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];
+            });
+        },
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ms-my.js b/resources/moment/lang/ms-my.js
new file mode 100644 (file)
index 0000000..501d5aa
--- /dev/null
@@ -0,0 +1,66 @@
+// moment.js language configuration
+// language : Bahasa Malaysia (ms-MY)
+// author : Weldan Jamili : https://github.com/weldan
+
+(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.lang('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("_"),
+        weekdaysShort : "Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),
+        weekdaysMin : "Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),
+        longDateFormat : {
+            LT : "HH.mm",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY [pukul] LT",
+            LLLL : "dddd, D MMMM YYYY [pukul] LT"
+        },
+        meridiem : function (hours, minutes, isLower) {
+            if (hours < 11) {
+                return 'pagi';
+            } else if (hours < 15) {
+                return 'tengahari';
+            } else if (hours < 19) {
+                return 'petang';
+            } else {
+                return 'malam';
+            }
+        },
+        calendar : {
+            sameDay : '[Hari ini pukul] LT',
+            nextDay : '[Esok pukul] LT',
+            nextWeek : 'dddd [pukul] LT',
+            lastDay : '[Kelmarin pukul] LT',
+            lastWeek : 'dddd [lepas pukul] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "dalam %s",
+            past : "%s yang lepas",
+            s : "beberapa saat",
+            m : "seminit",
+            mm : "%d minit",
+            h : "sejam",
+            hh : "%d jam",
+            d : "sehari",
+            dd : "%d hari",
+            M : "sebulan",
+            MM : "%d bulan",
+            y : "setahun",
+            yy : "%d tahun"
+        },
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/nb.js b/resources/moment/lang/nb.js
new file mode 100644 (file)
index 0000000..2f652ef
--- /dev/null
@@ -0,0 +1,57 @@
+// moment.js language configuration
+// language : norwegian bokmål (nb)
+// authors : Espen Hovlandsdal : https://github.com/rexxars
+//           Sigurd Gartmann : https://github.com/sigurdga
+
+(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.lang('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("_"),
+        weekdaysShort : "sø._ma._ti._on._to._fr._lø.".split("_"),
+        weekdaysMin : "sø_ma_ti_on_to_fr_lø".split("_"),
+        longDateFormat : {
+            LT : "H.mm",
+            L : "DD.MM.YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY [kl.] LT",
+            LLLL : "dddd D. MMMM YYYY [kl.] LT"
+        },
+        calendar : {
+            sameDay: '[i dag kl.] LT',
+            nextDay: '[i morgen kl.] LT',
+            nextWeek: 'dddd [kl.] LT',
+            lastDay: '[i går kl.] LT',
+            lastWeek: '[forrige] dddd [kl.] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "om %s",
+            past : "for %s siden",
+            s : "noen sekunder",
+            m : "ett minutt",
+            mm : "%d minutter",
+            h : "en time",
+            hh : "%d timer",
+            d : "en dag",
+            dd : "%d dager",
+            M : "en måned",
+            MM : "%d måneder",
+            y : "ett år",
+            yy : "%d år"
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ne.js b/resources/moment/lang/ne.js
new file mode 100644 (file)
index 0000000..1d57b8c
--- /dev/null
@@ -0,0 +1,105 @@
+// moment.js language configuration
+// language : nepali/nepalese
+// author : suvash : https://github.com/suvash
+
+(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.lang('ne', {
+        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"
+        },
+        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 < 3) {
+                return "राती";
+            } else if (hour < 10) {
+                return "बिहान";
+            } else if (hour < 15) {
+                return "दिउँसो";
+            } else if (hour < 18) {
+                return "बेलुका";
+            } else if (hour < 20) {
+                return "साँझ";
+            } else {
+                return "राती";
+            }
+        },
+        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 बर्ष"
+        },
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/nl.js b/resources/moment/lang/nl.js
new file mode 100644 (file)
index 0000000..ffd454f
--- /dev/null
@@ -0,0 +1,67 @@
+// moment.js language configuration
+// language : dutch (nl)
+// author : Joris Röling : https://github.com/jjupiter
+
+(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 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', {
+        months : "januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),
+        monthsShort : function (m, format) {
+            if (/-MMM-/.test(format)) {
+                return monthsShortWithoutDots[m.month()];
+            } else {
+                return monthsShortWithDots[m.month()];
+            }
+        },
+        weekdays : "zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),
+        weekdaysShort : "zo._ma._di._wo._do._vr._za.".split("_"),
+        weekdaysMin : "Zo_Ma_Di_Wo_Do_Vr_Za".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: '[vandaag om] LT',
+            nextDay: '[morgen om] LT',
+            nextWeek: 'dddd [om] LT',
+            lastDay: '[gisteren om] LT',
+            lastWeek: '[afgelopen] dddd [om] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "over %s",
+            past : "%s geleden",
+            s : "een paar seconden",
+            m : "één minuut",
+            mm : "%d minuten",
+            h : "één uur",
+            hh : "%d uur",
+            d : "één dag",
+            dd : "%d dagen",
+            M : "één maand",
+            MM : "%d maanden",
+            y : "één jaar",
+            yy : "%d jaar"
+        },
+        ordinal : function (number) {
+            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/nn.js b/resources/moment/lang/nn.js
new file mode 100644 (file)
index 0000000..f59c415
--- /dev/null
@@ -0,0 +1,56 @@
+// moment.js language configuration
+// language : norwegian nynorsk (nn)
+// author : https://github.com/mechuwind
+
+(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.lang('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("_"),
+        weekdaysShort : "sun_mån_tys_ons_tor_fre_lau".split("_"),
+        weekdaysMin : "su_må_ty_on_to_fr_lø".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: '[I dag klokka] LT',
+            nextDay: '[I morgon klokka] LT',
+            nextWeek: 'dddd [klokka] LT',
+            lastDay: '[I går klokka] LT',
+            lastWeek: '[Føregående] dddd [klokka] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "om %s",
+            past : "for %s siden",
+            s : "noen sekund",
+            m : "ett minutt",
+            mm : "%d minutt",
+            h : "en time",
+            hh : "%d timar",
+            d : "en dag",
+            dd : "%d dagar",
+            M : "en månad",
+            MM : "%d månader",
+            y : "ett år",
+            yy : "%d år"
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/pl.js b/resources/moment/lang/pl.js
new file mode 100644 (file)
index 0000000..97770d2
--- /dev/null
@@ -0,0 +1,98 @@
+// moment.js language configuration
+// language : polish (pl)
+// author : Rafal Hirsz : https://github.com/evoL
+
+(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 monthsNominative = "styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),
+        monthsSubjective = "stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_");
+
+    function plural(n) {
+        return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);
+    }
+
+    function translate(number, withoutSuffix, key) {
+        var result = number + " ";
+        switch (key) {
+        case 'm':
+            return withoutSuffix ? 'minuta' : 'minutę';
+        case 'mm':
+            return result + (plural(number) ? 'minuty' : 'minut');
+        case 'h':
+            return withoutSuffix  ? 'godzina'  : 'godzinę';
+        case 'hh':
+            return result + (plural(number) ? 'godziny' : 'godzin');
+        case 'MM':
+            return result + (plural(number) ? 'miesiące' : 'miesięcy');
+        case 'yy':
+            return result + (plural(number) ? 'lata' : 'lat');
+        }
+    }
+
+    return moment.lang('pl', {
+        months : function (momentToFormat, format) {
+            if (/D MMMM/.test(format)) {
+                return monthsSubjective[momentToFormat.month()];
+            } else {
+                return monthsNominative[momentToFormat.month()];
+            }
+        },
+        monthsShort : "sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),
+        weekdays : "niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),
+        weekdaysShort : "nie_pon_wt_śr_czw_pt_sb".split("_"),
+        weekdaysMin : "N_Pn_Wt_Śr_Cz_Pt_So".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: '[Dziś o] LT',
+            nextDay: '[Jutro o] LT',
+            nextWeek: '[W] dddd [o] LT',
+            lastDay: '[Wczoraj o] LT',
+            lastWeek: function () {
+                switch (this.day()) {
+                case 0:
+                    return '[W zeszłą niedzielę o] LT';
+                case 3:
+                    return '[W zeszłą środę o] LT';
+                case 6:
+                    return '[W zeszłą sobotę o] LT';
+                default:
+                    return '[W zeszły] dddd [o] LT';
+                }
+            },
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "za %s",
+            past : "%s temu",
+            s : "kilka sekund",
+            m : translate,
+            mm : translate,
+            h : translate,
+            hh : translate,
+            d : "1 dzień",
+            dd : '%d dni',
+            M : "miesiąc",
+            MM : translate,
+            y : "rok",
+            yy : translate
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/pt-br.js b/resources/moment/lang/pt-br.js
new file mode 100644 (file)
index 0000000..5cac19b
--- /dev/null
@@ -0,0 +1,56 @@
+// moment.js language configuration
+// language : brazilian portuguese (pt-br)
+// author : Caio Ribeiro Pereira : https://github.com/caio-ribeiro-pereira
+
+(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.lang('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("_"),
+        weekdaysShort : "Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),
+        weekdaysMin : "Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "DD/MM/YYYY",
+            LL : "D [de] MMMM [de] YYYY",
+            LLL : "D [de] MMMM [de] YYYY LT",
+            LLLL : "dddd, D [de] MMMM [de] YYYY LT"
+        },
+        calendar : {
+            sameDay: '[Hoje às] LT',
+            nextDay: '[Amanhã às] LT',
+            nextWeek: 'dddd [às] LT',
+            lastDay: '[Ontem às] LT',
+            lastWeek: function () {
+                return (this.day() === 0 || this.day() === 6) ?
+                    '[Último] dddd [às] LT' : // Saturday + Sunday
+                    '[Última] dddd [às] LT'; // Monday - Friday
+            },
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "em %s",
+            past : "%s atrás",
+            s : "segundos",
+            m : "um minuto",
+            mm : "%d minutos",
+            h : "uma hora",
+            hh : "%d horas",
+            d : "um dia",
+            dd : "%d dias",
+            M : "um mês",
+            MM : "%d meses",
+            y : "um ano",
+            yy : "%d anos"
+        },
+        ordinal : '%dº'
+    });
+}));
diff --git a/resources/moment/lang/pt.js b/resources/moment/lang/pt.js
new file mode 100644 (file)
index 0000000..7c1f2b5
--- /dev/null
@@ -0,0 +1,60 @@
+// moment.js language configuration
+// language : portuguese (pt)
+// author : Jefferson : https://github.com/jalex79
+
+(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.lang('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("_"),
+        weekdaysShort : "Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),
+        weekdaysMin : "Dom_2ª_3ª_4ª_5ª_6ª_Sáb".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "DD/MM/YYYY",
+            LL : "D [de] MMMM [de] YYYY",
+            LLL : "D [de] MMMM [de] YYYY LT",
+            LLLL : "dddd, D [de] MMMM [de] YYYY LT"
+        },
+        calendar : {
+            sameDay: '[Hoje às] LT',
+            nextDay: '[Amanhã às] LT',
+            nextWeek: 'dddd [às] LT',
+            lastDay: '[Ontem às] LT',
+            lastWeek: function () {
+                return (this.day() === 0 || this.day() === 6) ?
+                    '[Último] dddd [às] LT' : // Saturday + Sunday
+                    '[Última] dddd [às] LT'; // Monday - Friday
+            },
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "em %s",
+            past : "%s atrás",
+            s : "segundos",
+            m : "um minuto",
+            mm : "%d minutos",
+            h : "uma hora",
+            hh : "%d horas",
+            d : "um dia",
+            dd : "%d dias",
+            M : "um mês",
+            MM : "%d meses",
+            y : "um ano",
+            yy : "%d anos"
+        },
+        ordinal : '%dº',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ro.js b/resources/moment/lang/ro.js
new file mode 100644 (file)
index 0000000..77d7355
--- /dev/null
@@ -0,0 +1,72 @@
+// moment.js language configuration
+// language : romanian (ro)
+// author : Vlad Gurdiga : https://github.com/gurdiga
+// author : Valentin Agachi : https://github.com/avaly
+
+(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 relativeTimeWithPlural(number, withoutSuffix, key) {
+        var format = {
+            'mm': 'minute',
+            'hh': 'ore',
+            'dd': 'zile',
+            'MM': 'luni',
+            'yy': 'ani'
+        },
+            separator = ' ';
+        if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {
+            separator = ' de ';
+        }
+
+        return number + separator + format[key];
+    }
+
+    return moment.lang('ro', {
+        months : "ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),
+        monthsShort : "ian_feb_mar_apr_mai_iun_iul_aug_sep_oct_noi_dec".split("_"),
+        weekdays : "duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),
+        weekdaysShort : "Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),
+        weekdaysMin : "Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD.MM.YYYY",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY H:mm",
+            LLLL : "dddd, D MMMM YYYY H:mm"
+        },
+        calendar : {
+            sameDay: "[azi la] LT",
+            nextDay: '[mâine la] LT',
+            nextWeek: 'dddd [la] LT',
+            lastDay: '[ieri la] LT',
+            lastWeek: '[fosta] dddd [la] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "peste %s",
+            past : "%s în urmă",
+            s : "câteva secunde",
+            m : "un minut",
+            mm : relativeTimeWithPlural,
+            h : "o oră",
+            hh : relativeTimeWithPlural,
+            d : "o zi",
+            dd : relativeTimeWithPlural,
+            M : "o lună",
+            MM : relativeTimeWithPlural,
+            y : "un an",
+            yy : relativeTimeWithPlural
+        },
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/rs.js b/resources/moment/lang/rs.js
new file mode 100644 (file)
index 0000000..8627553
--- /dev/null
@@ -0,0 +1,139 @@
+// moment.js language configuration
+// language : serbian (rs)
+// author : Limon Monte : https://github.com/limonte
+// based on (bs) translation by Nedim Cholich
+
+(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 translate(number, withoutSuffix, key) {
+        var result = number + " ";
+        switch (key) {
+        case 'm':
+            return withoutSuffix ? 'jedna minuta' : 'jedne minute';
+        case 'mm':
+            if (number === 1) {
+                result += 'minuta';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'minute';
+            } else {
+                result += 'minuta';
+            }
+            return result;
+        case 'h':
+            return withoutSuffix ? 'jedan sat' : 'jednog sata';
+        case 'hh':
+            if (number === 1) {
+                result += 'sat';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'sata';
+            } else {
+                result += 'sati';
+            }
+            return result;
+        case 'dd':
+            if (number === 1) {
+                result += 'dan';
+            } else {
+                result += 'dana';
+            }
+            return result;
+        case 'MM':
+            if (number === 1) {
+                result += 'mesec';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'meseca';
+            } else {
+                result += 'meseci';
+            }
+            return result;
+        case 'yy':
+            if (number === 1) {
+                result += 'godina';
+            } else if (number === 2 || number === 3 || number === 4) {
+                result += 'godine';
+            } else {
+                result += 'godina';
+            }
+            return result;
+        }
+    }
+
+    return moment.lang('rs', {
+        months : "januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),
+        monthsShort : "jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),
+        weekdays : "nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota".split("_"),
+        weekdaysShort : "ned._pon._uto._sre._čet._pet._sub.".split("_"),
+        weekdaysMin : "ne_po_ut_sr_če_pe_su".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD. MM. YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY LT",
+            LLLL : "dddd, D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay  : '[danas u] LT',
+            nextDay  : '[sutra u] LT',
+
+            nextWeek : function () {
+                switch (this.day()) {
+                case 0:
+                    return '[u] [nedelju] [u] LT';
+                case 3:
+                    return '[u] [sredu] [u] LT';
+                case 6:
+                    return '[u] [subotu] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[u] dddd [u] LT';
+                }
+            },
+            lastDay  : '[juče u] LT',
+            lastWeek : function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                    return '[prošlu] dddd [u] LT';
+                case 6:
+                    return '[prošle] [subote] [u] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[prošli] dddd [u] LT';
+                }
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "za %s",
+            past   : "pre %s",
+            s      : "par sekundi",
+            m      : translate,
+            mm     : translate,
+            h      : translate,
+            hh     : translate,
+            d      : "dan",
+            dd     : translate,
+            M      : "mesec",
+            MM     : translate,
+            y      : "godinu",
+            yy     : translate
+        },
+        ordinal : '%d.',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ru.js b/resources/moment/lang/ru.js
new file mode 100644 (file)
index 0000000..1d1816c
--- /dev/null
@@ -0,0 +1,163 @@
+// moment.js language configuration
+// language : russian (ru)
+// author : Viktorminator : https://github.com/Viktorminator
+// 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': 'минута_минуты_минут',
+            'hh': 'час_часа_часов',
+            'dd': 'день_дня_дней',
+            'MM': 'месяц_месяца_месяцев',
+            'yy': 'год_года_лет'
+        };
+        if (key === 'm') {
+            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 monthsShortCaseReplace(m, format) {
+        var monthsShort = {
+            'nominative': 'янв_фев_мар_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),
+            'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')
+        },
+
+        nounCase = (/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/).test(format) ?
+            'accusative' :
+            'nominative';
+
+        return monthsShort[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.lang('ru', {
+        months : monthsCaseReplace,
+        monthsShort : monthsShortCaseReplace,
+        weekdays : weekdaysCaseReplace,
+        weekdaysShort : "вс_пн_вт_ср_чт_пт_сб".split("_"),
+        weekdaysMin : "вс_пн_вт_ср_чт_пт_сб".split("_"),
+        monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],
+        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 this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';
+            },
+            lastWeek: function () {
+                switch (this.day()) {
+                case 0:
+                    return '[В прошлое] dddd [в] LT';
+                case 1:
+                case 2:
+                case 4:
+                    return '[В прошлый] dddd [в] LT';
+                case 3:
+                case 5:
+                case 6:
+                    return '[В прошлую] dddd [в] LT';
+                }
+            },
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "через %s",
+            past : "%s назад",
+            s : "несколько секунд",
+            m : relativeTimeWithPlural,
+            mm : relativeTimeWithPlural,
+            h : "час",
+            hh : relativeTimeWithPlural,
+            d : "день",
+            dd : relativeTimeWithPlural,
+            M : "месяц",
+            MM : relativeTimeWithPlural,
+            y : "год",
+            yy : relativeTimeWithPlural
+        },
+
+        // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
+
+        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':
+                return number + '-й';
+            case 'D':
+                return number + '-го';
+            case 'w':
+            case 'W':
+                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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/sk.js b/resources/moment/lang/sk.js
new file mode 100644 (file)
index 0000000..ed8a41d
--- /dev/null
@@ -0,0 +1,156 @@
+// moment.js language configuration
+// language : slovak (sk)
+// author : Martin Minka : https://github.com/k2s
+// based on work of petrbela : https://github.com/petrbela
+
+(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 months = "január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),
+        monthsShort = "jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_");
+
+    function plural(n) {
+        return (n > 1) && (n < 5);
+    }
+
+    function translate(number, withoutSuffix, key, isFuture) {
+        var result = number + " ";
+        switch (key) {
+        case 's':  // a few seconds / in a few seconds / a few seconds ago
+            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';
+        case 'm':  // a minute / in a minute / a minute ago
+            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');
+        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'minúty' : 'minút');
+            } else {
+                return result + 'minútami';
+            }
+            break;
+        case 'h':  // an hour / in an hour / an hour ago
+            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
+        case 'hh': // 9 hours / in 9 hours / 9 hours ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'hodiny' : 'hodín');
+            } else {
+                return result + 'hodinami';
+            }
+            break;
+        case 'd':  // a day / in a day / a day ago
+            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';
+        case 'dd': // 9 days / in 9 days / 9 days ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'dni' : 'dní');
+            } else {
+                return result + 'dňami';
+            }
+            break;
+        case 'M':  // a month / in a month / a month ago
+            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';
+        case 'MM': // 9 months / in 9 months / 9 months ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'mesiace' : 'mesiacov');
+            } else {
+                return result + 'mesiacmi';
+            }
+            break;
+        case 'y':  // a year / in a year / a year ago
+            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';
+        case 'yy': // 9 years / in 9 years / 9 years ago
+            if (withoutSuffix || isFuture) {
+                return result + (plural(number) ? 'roky' : 'rokov');
+            } else {
+                return result + 'rokmi';
+            }
+            break;
+        }
+    }
+
+    return moment.lang('sk', {
+        months : months,
+        monthsShort : monthsShort,
+        monthsParse : (function (months, monthsShort) {
+            var i, _monthsParse = [];
+            for (i = 0; i < 12; i++) {
+                // use custom parser to solve problem with July (červenec)
+                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
+            }
+            return _monthsParse;
+        }(months, monthsShort)),
+        weekdays : "nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),
+        weekdaysShort : "ne_po_ut_st_št_pi_so".split("_"),
+        weekdaysMin : "ne_po_ut_st_št_pi_so".split("_"),
+        longDateFormat : {
+            LT: "H:mm",
+            L : "DD.MM.YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY LT",
+            LLLL : "dddd D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay: "[dnes o] LT",
+            nextDay: '[zajtra o] LT',
+            nextWeek: function () {
+                switch (this.day()) {
+                case 0:
+                    return '[v nedeľu o] LT';
+                case 1:
+                case 2:
+                    return '[v] dddd [o] LT';
+                case 3:
+                    return '[v stredu o] LT';
+                case 4:
+                    return '[vo štvrtok o] LT';
+                case 5:
+                    return '[v piatok o] LT';
+                case 6:
+                    return '[v sobotu o] LT';
+                }
+            },
+            lastDay: '[včera o] LT',
+            lastWeek: function () {
+                switch (this.day()) {
+                case 0:
+                    return '[minulú nedeľu o] LT';
+                case 1:
+                case 2:
+                    return '[minulý] dddd [o] LT';
+                case 3:
+                    return '[minulú stredu o] LT';
+                case 4:
+                case 5:
+                    return '[minulý] dddd [o] LT';
+                case 6:
+                    return '[minulú sobotu o] LT';
+                }
+            },
+            sameElse: "L"
+        },
+        relativeTime : {
+            future : "za %s",
+            past : "pred %s",
+            s : translate,
+            m : translate,
+            mm : translate,
+            h : translate,
+            hh : translate,
+            d : translate,
+            dd : translate,
+            M : translate,
+            MM : translate,
+            y : translate,
+            yy : translate
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/sl.js b/resources/moment/lang/sl.js
new file mode 100644 (file)
index 0000000..d260f80
--- /dev/null
@@ -0,0 +1,144 @@
+// moment.js language configuration
+// language : slovenian (sl)
+// author : Robert Sedovšek : https://github.com/sedovsek
+
+(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 translate(number, withoutSuffix, key) {
+        var result = number + " ";
+        switch (key) {
+        case 'm':
+            return withoutSuffix ? 'ena minuta' : 'eno minuto';
+        case 'mm':
+            if (number === 1) {
+                result += 'minuta';
+            } else if (number === 2) {
+                result += 'minuti';
+            } else if (number === 3 || number === 4) {
+                result += 'minute';
+            } else {
+                result += 'minut';
+            }
+            return result;
+        case 'h':
+            return withoutSuffix ? 'ena ura' : 'eno uro';
+        case 'hh':
+            if (number === 1) {
+                result += 'ura';
+            } else if (number === 2) {
+                result += 'uri';
+            } else if (number === 3 || number === 4) {
+                result += 'ure';
+            } else {
+                result += 'ur';
+            }
+            return result;
+        case 'dd':
+            if (number === 1) {
+                result += 'dan';
+            } else {
+                result += 'dni';
+            }
+            return result;
+        case 'MM':
+            if (number === 1) {
+                result += 'mesec';
+            } else if (number === 2) {
+                result += 'meseca';
+            } else if (number === 3 || number === 4) {
+                result += 'mesece';
+            } else {
+                result += 'mesecev';
+            }
+            return result;
+        case 'yy':
+            if (number === 1) {
+                result += 'leto';
+            } else if (number === 2) {
+                result += 'leti';
+            } else if (number === 3 || number === 4) {
+                result += 'leta';
+            } else {
+                result += 'let';
+            }
+            return result;
+        }
+    }
+
+    return moment.lang('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("_"),
+        weekdaysShort : "ned._pon._tor._sre._čet._pet._sob.".split("_"),
+        weekdaysMin : "ne_po_to_sr_če_pe_so".split("_"),
+        longDateFormat : {
+            LT : "H:mm",
+            L : "DD. MM. YYYY",
+            LL : "D. MMMM YYYY",
+            LLL : "D. MMMM YYYY LT",
+            LLLL : "dddd, D. MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay  : '[danes ob] LT',
+            nextDay  : '[jutri ob] LT',
+
+            nextWeek : function () {
+                switch (this.day()) {
+                case 0:
+                    return '[v] [nedeljo] [ob] LT';
+                case 3:
+                    return '[v] [sredo] [ob] LT';
+                case 6:
+                    return '[v] [soboto] [ob] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[v] dddd [ob] LT';
+                }
+            },
+            lastDay  : '[včeraj ob] LT',
+            lastWeek : function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                case 6:
+                    return '[prejšnja] dddd [ob] LT';
+                case 1:
+                case 2:
+                case 4:
+                case 5:
+                    return '[prejšnji] dddd [ob] LT';
+                }
+            },
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "čez %s",
+            past   : "%s nazaj",
+            s      : "nekaj sekund",
+            m      : translate,
+            mm     : translate,
+            h      : translate,
+            hh     : translate,
+            d      : "en dan",
+            dd     : translate,
+            M      : "en mesec",
+            MM     : translate,
+            y      : "eno leto",
+            yy     : translate
+        },
+        ordinal : '%d.',
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/sq.js b/resources/moment/lang/sq.js
new file mode 100644 (file)
index 0000000..a5e44b5
--- /dev/null
@@ -0,0 +1,57 @@
+// moment.js language configuration
+// language : Albanian (sq)
+// author : Flakërim Ismani : https://github.com/flakerimi
+// author: Menelion Elensúle: https://github.com/Oire (tests)
+
+(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.lang('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 Marte_E Mërkure_E Enjte_E Premte_E Shtunë".split("_"),
+        weekdaysShort : "Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"),
+        weekdaysMin : "D_H_Ma_Më_E_P_Sh".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 : '[Sot në] LT',
+            nextDay : '[Neser në] LT',
+            nextWeek : 'dddd [në] LT',
+            lastDay : '[Dje në] LT',
+            lastWeek : 'dddd [e kaluar në] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "në %s",
+            past : "%s me parë",
+            s : "disa sekonda",
+            m : "një minut",
+            mm : "%d minuta",
+            h : "një orë",
+            hh : "%d orë",
+            d : "një ditë",
+            dd : "%d ditë",
+            M : "një muaj",
+            MM : "%d muaj",
+            y : "një vit",
+            yy : "%d vite"
+        },
+        ordinal : '%d.',
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/sv.js b/resources/moment/lang/sv.js
new file mode 100644 (file)
index 0000000..0de8c40
--- /dev/null
@@ -0,0 +1,63 @@
+// moment.js language configuration
+// language : swedish (sv)
+// author : Jens Alm : https://github.com/ulmus
+
+(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.lang('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("_"),
+        weekdaysShort : "sön_mån_tis_ons_tor_fre_lör".split("_"),
+        weekdaysMin : "sö_må_ti_on_to_fr_lö".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "YYYY-MM-DD",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY LT",
+            LLLL : "dddd D MMMM YYYY LT"
+        },
+        calendar : {
+            sameDay: '[Idag] LT',
+            nextDay: '[Imorgon] LT',
+            lastDay: '[Igår] LT',
+            nextWeek: 'dddd LT',
+            lastWeek: '[Förra] dddd[en] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "om %s",
+            past : "för %s sedan",
+            s : "några sekunder",
+            m : "en minut",
+            mm : "%d minuter",
+            h : "en timme",
+            hh : "%d timmar",
+            d : "en dag",
+            dd : "%d dagar",
+            M : "en månad",
+            MM : "%d månader",
+            y : "ett år",
+            yy : "%d år"
+        },
+        ordinal : function (number) {
+            var b = number % 10,
+                output = (~~ (number % 100 / 10) === 1) ? 'e' :
+                (b === 1) ? 'a' :
+                (b === 2) ? 'a' :
+                (b === 3) ? 'e' : 'e';
+            return number + output;
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/ta.js b/resources/moment/lang/ta.js
new file mode 100644 (file)
index 0000000..cc742c9
--- /dev/null
@@ -0,0 +1,112 @@
+// moment.js language configuration
+// language : tamil (ta)
+// author : Arjunkumar Krishnamoorthy : https://github.com/tk120404
+
+(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.lang('ta', {
+        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];
+            });
+        },*/
+        ordinal : function (number) {
+            return number + 'வது';
+        },
+
+
+// refer http://ta.wikipedia.org/s/1er1      
+
+        meridiem : function (hour, minute, isLower) {
+            if (hour >= 6 && hour <= 10) {
+                return " காலை";
+            } else   if (hour >= 10 && hour <= 14) {
+                return " நண்பகல்";
+            } else    if (hour >= 14 && hour <= 18) {
+                return " எற்பாடு";
+            } else   if (hour >= 18 && hour <= 20) {
+                return " மாலை";
+            } else  if (hour >= 20 && hour <= 24) {
+                return " இரவு";
+            } else  if (hour >= 0 && hour <= 6) {
+                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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/th.js b/resources/moment/lang/th.js
new file mode 100644 (file)
index 0000000..70336c8
--- /dev/null
@@ -0,0 +1,58 @@
+// moment.js language configuration
+// language : thai (th)
+// author : Kridsada Thanabulpong : https://github.com/sirn
+
+(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.lang('th', {
+        months : "มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),
+        monthsShort : "มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา".split("_"),
+        weekdays : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),
+        weekdaysShort : "อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"), // yes, three characters difference
+        weekdaysMin : "อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),
+        longDateFormat : {
+            LT : "H นาฬิกา m นาที",
+            L : "YYYY/MM/DD",
+            LL : "D MMMM YYYY",
+            LLL : "D MMMM YYYY เวลา LT",
+            LLLL : "วันddddที่ D MMMM YYYY เวลา LT"
+        },
+        meridiem : function (hour, minute, isLower) {
+            if (hour < 12) {
+                return "ก่อนเที่ยง";
+            } else {
+                return "หลังเที่ยง";
+            }
+        },
+        calendar : {
+            sameDay : '[วันนี้ เวลา] LT',
+            nextDay : '[พรุ่งนี้ เวลา] LT',
+            nextWeek : 'dddd[หน้า เวลา] LT',
+            lastDay : '[เมื่อวานนี้ เวลา] LT',
+            lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "อีก %s",
+            past : "%sที่แล้ว",
+            s : "ไม่กี่วินาที",
+            m : "1 นาที",
+            mm : "%d นาที",
+            h : "1 ชั่วโมง",
+            hh : "%d ชั่วโมง",
+            d : "1 วัน",
+            dd : "%d วัน",
+            M : "1 เดือน",
+            MM : "%d เดือน",
+            y : "1 ปี",
+            yy : "%d ปี"
+        }
+    });
+}));
diff --git a/resources/moment/lang/tl-ph.js b/resources/moment/lang/tl-ph.js
new file mode 100644 (file)
index 0000000..8044483
--- /dev/null
@@ -0,0 +1,58 @@
+// moment.js language configuration
+// language : Tagalog/Filipino (tl-ph)
+// author : Dan Hagman
+
+(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.lang('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("_"),
+        weekdaysShort : "Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),
+        weekdaysMin : "Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "MM/D/YYYY",
+            LL : "MMMM D, YYYY",
+            LLL : "MMMM D, YYYY LT",
+            LLLL : "dddd, MMMM DD, YYYY LT"
+        },
+        calendar : {
+            sameDay: "[Ngayon sa] LT",
+            nextDay: '[Bukas sa] LT',
+            nextWeek: 'dddd [sa] LT',
+            lastDay: '[Kahapon sa] LT',
+            lastWeek: 'dddd [huling linggo] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "sa loob ng %s",
+            past : "%s ang nakalipas",
+            s : "ilang segundo",
+            m : "isang minuto",
+            mm : "%d minuto",
+            h : "isang oras",
+            hh : "%d oras",
+            d : "isang araw",
+            dd : "%d araw",
+            M : "isang buwan",
+            MM : "%d buwan",
+            y : "isang taon",
+            yy : "%d taon"
+        },
+        ordinal : function (number) {
+            return number;
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/tr.js b/resources/moment/lang/tr.js
new file mode 100644 (file)
index 0000000..e90f250
--- /dev/null
@@ -0,0 +1,93 @@
+// moment.js language configuration
+// language : turkish (tr)
+// authors : Erhan Gundogan : https://github.com/erhangundogan,
+//           Burak Yiğit Kaya: https://github.com/BYK
+
+(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 suffixes = {
+        1: "'inci",
+        5: "'inci",
+        8: "'inci",
+        70: "'inci",
+        80: "'inci",
+
+        2: "'nci",
+        7: "'nci",
+        20: "'nci",
+        50: "'nci",
+
+        3: "'üncü",
+        4: "'üncü",
+        100: "'üncü",
+
+        6: "'ncı",
+
+        9: "'uncu",
+        10: "'uncu",
+        30: "'uncu",
+
+        60: "'ıncı",
+        90: "'ıncı"
+    };
+
+    return moment.lang('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("_"),
+        weekdaysShort : "Paz_Pts_Sal_Çar_Per_Cum_Cts".split("_"),
+        weekdaysMin : "Pz_Pt_Sa_Ça_Pe_Cu_Ct".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 : '[bugün saat] LT',
+            nextDay : '[yarın saat] LT',
+            nextWeek : '[haftaya] dddd [saat] LT',
+            lastDay : '[dün] LT',
+            lastWeek : '[geçen hafta] dddd [saat] LT',
+            sameElse : 'L'
+        },
+        relativeTime : {
+            future : "%s sonra",
+            past : "%s önce",
+            s : "birkaç saniye",
+            m : "bir dakika",
+            mm : "%d dakika",
+            h : "bir saat",
+            hh : "%d saat",
+            d : "bir gün",
+            dd : "%d gün",
+            M : "bir ay",
+            MM : "%d ay",
+            y : "bir yıl",
+            yy : "%d yıl"
+        },
+        ordinal : function (number) {
+            if (number === 0) {  // special case for zero
+                return number + "'ıncı";
+            }
+            var a = number % 10,
+                b = number % 100 - a,
+                c = number >= 100 ? 100 : null;
+
+            return number + (suffixes[a] || suffixes[b] || suffixes[c]);
+        },
+        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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/tzm-la.js b/resources/moment/lang/tzm-la.js
new file mode 100644 (file)
index 0000000..be1d878
--- /dev/null
@@ -0,0 +1,55 @@
+// moment.js language configuration
+// language : Morocco Central Atlas Tamaziɣt in Latin (tzm-la)
+// author : Abdel Said : https://github.com/abdelsaid
+
+(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.lang('tzm-la', {
+        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("_"),
+        weekdaysShort : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),
+        weekdaysMin : "asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".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: "[asdkh g] LT",
+            nextDay: '[aska g] LT',
+            nextWeek: 'dddd [g] LT',
+            lastDay: '[assant g] LT',
+            lastWeek: 'dddd [g] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "dadkh s yan %s",
+            past : "yan %s",
+            s : "imik",
+            m : "minuḍ",
+            mm : "%d minuḍ",
+            h : "saɛa",
+            hh : "%d tassaɛin",
+            d : "ass",
+            dd : "%d ossan",
+            M : "ayowr",
+            MM : "%d iyyirn",
+            y : "asgas",
+            yy : "%d isgasn"
+        },
+        week : {
+            dow : 6, // Saturday is the first day of the week.
+            doy : 12  // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/tzm.js b/resources/moment/lang/tzm.js
new file mode 100644 (file)
index 0000000..c7c76bd
--- /dev/null
@@ -0,0 +1,55 @@
+// moment.js language configuration
+// language : Morocco Central Atlas Tamaziɣt (tzm)
+// author : Abdel Said : https://github.com/abdelsaid
+
+(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.lang('tzm', {
+        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 oⵙⵙⴰⵏ",
+            M : "ⴰⵢoⵓⵔ",
+            MM : "%d ⵉⵢⵢⵉⵔⵏ",
+            y : "ⴰⵙⴳⴰⵙ",
+            yy : "%d ⵉⵙⴳⴰⵙⵏ"
+        },
+        week : {
+            dow : 6, // Saturday is the first day of the week.
+            doy : 12  // The week that contains Jan 1st is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/uk.js b/resources/moment/lang/uk.js
new file mode 100644 (file)
index 0000000..47056cb
--- /dev/null
@@ -0,0 +1,157 @@
+// moment.js language configuration
+// language : ukrainian (uk)
+// author : zemlanin : https://github.com/zemlanin
+// 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': 'хвилина_хвилини_хвилин',
+            'hh': 'година_години_годин',
+            '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]? *MMMM?/).test(format) ?
+            'accusative' :
+            'nominative';
+
+        return months[nounCase][m.month()];
+    }
+
+    function weekdaysCaseReplace(m, format) {
+        var weekdays = {
+            'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),
+            'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),
+            'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')
+        },
+
+        nounCase = (/(\[[ВвУу]\]) ?dddd/).test(format) ?
+            'accusative' :
+            ((/\[?(?:минулої|наступної)? ?\] ?dddd/).test(format) ?
+                'genitive' :
+                'nominative');
+
+        return weekdays[nounCase][m.day()];
+    }
+
+    function processHoursFunction(str) {
+        return function () {
+            return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
+        };
+    }
+
+    return moment.lang('uk', {
+        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: processHoursFunction('[Сьогодні '),
+            nextDay: processHoursFunction('[Завтра '),
+            lastDay: processHoursFunction('[Вчора '),
+            nextWeek: processHoursFunction('[У] dddd ['),
+            lastWeek: function () {
+                switch (this.day()) {
+                case 0:
+                case 3:
+                case 5:
+                case 6:
+                    return processHoursFunction('[Минулої] dddd [').call(this);
+                case 1:
+                case 2:
+                case 4:
+                    return processHoursFunction('[Минулого] dddd [').call(this);
+                }
+            },
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "за %s",
+            past : "%s тому",
+            s : "декілька секунд",
+            m : relativeTimeWithPlural,
+            mm : relativeTimeWithPlural,
+            h : "годину",
+            hh : relativeTimeWithPlural,
+            d : "день",
+            dd : relativeTimeWithPlural,
+            M : "місяць",
+            MM : relativeTimeWithPlural,
+            y : "рік",
+            yy : relativeTimeWithPlural
+        },
+
+        // M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
+
+        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 + '-й';
+            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.
+        }
+    });
+}));
diff --git a/resources/moment/lang/uz.js b/resources/moment/lang/uz.js
new file mode 100644 (file)
index 0000000..a5b06fa
--- /dev/null
@@ -0,0 +1,55 @@
+// moment.js language configuration
+// language : uzbek
+// author : Sardor Muminov : https://github.com/muminoff
+
+(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.lang('uz', {
+        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 : "D MMMM YYYY, dddd 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 йил"
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 7  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/vn.js b/resources/moment/lang/vn.js
new file mode 100644 (file)
index 0000000..f28e7c3
--- /dev/null
@@ -0,0 +1,62 @@
+// moment.js language configuration
+// language : vietnamese (vn)
+// author : Bang Nguyen : https://github.com/bangnk
+
+(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.lang('vn', {
+        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("_"),
+        weekdaysShort : "CN_T2_T3_T4_T5_T6_T7".split("_"),
+        weekdaysMin : "CN_T2_T3_T4_T5_T6_T7".split("_"),
+        longDateFormat : {
+            LT : "HH:mm",
+            L : "DD/MM/YYYY",
+            LL : "D MMMM [năm] YYYY",
+            LLL : "D MMMM [năm] YYYY LT",
+            LLLL : "dddd, D MMMM [năm] YYYY LT",
+            l : "DD/M/YYYY",
+            ll : "D MMM YYYY",
+            lll : "D MMM YYYY LT",
+            llll : "ddd, D MMM YYYY LT"
+        },
+        calendar : {
+            sameDay: "[Hôm nay lúc] LT",
+            nextDay: '[Ngày mai lúc] LT',
+            nextWeek: 'dddd [tuần tới lúc] LT',
+            lastDay: '[Hôm qua lúc] LT',
+            lastWeek: 'dddd [tuần rồi lúc] LT',
+            sameElse: 'L'
+        },
+        relativeTime : {
+            future : "%s tới",
+            past : "%s trước",
+            s : "vài giây",
+            m : "một phút",
+            mm : "%d phút",
+            h : "một giờ",
+            hh : "%d giờ",
+            d : "một ngày",
+            dd : "%d ngày",
+            M : "một tháng",
+            MM : "%d tháng",
+            y : "một năm",
+            yy : "%d năm"
+        },
+        ordinal : function (number) {
+            return number;
+        },
+        week : {
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/zh-cn.js b/resources/moment/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..50a3ed9
--- /dev/null
@@ -0,0 +1,108 @@
+// moment.js language configuration
+// language : chinese
+// author : suupic : https://github.com/suupic
+// author : Zeno Zeng : https://github.com/zenozeng
+
+(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.lang('zh-cn', {
+        months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
+        monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
+        weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
+        weekdaysShort : "周日_周一_周二_周三_周四_周五_周六".split("_"),
+        weekdaysMin : "日_一_二_三_四_五_六".split("_"),
+        longDateFormat : {
+            LT : "Ah点mm",
+            L : "YYYY-MM-DD",
+            LL : "YYYY年MMMD日",
+            LLL : "YYYY年MMMD日LT",
+            LLLL : "YYYY年MMMD日ddddLT",
+            l : "YYYY-MM-DD",
+            ll : "YYYY年MMMD日",
+            lll : "YYYY年MMMD日LT",
+            llll : "YYYY年MMMD日ddddLT"
+        },
+        meridiem : function (hour, minute, isLower) {
+            var hm = hour * 100 + minute;
+            if (hm < 600) {
+                return "凌晨";
+            } else if (hm < 900) {
+                return "早上";
+            } else if (hm < 1130) {
+                return "上午";
+            } else if (hm < 1230) {
+                return "中午";
+            } else if (hm < 1800) {
+                return "下午";
+            } else {
+                return "晚上";
+            }
+        },
+        calendar : {
+            sameDay : function () {
+                return this.minutes() === 0 ? "[今天]Ah[点整]" : "[今天]LT";
+            },
+            nextDay : function () {
+                return this.minutes() === 0 ? "[明天]Ah[点整]" : "[明天]LT";
+            },
+            lastDay : function () {
+                return this.minutes() === 0 ? "[昨天]Ah[点整]" : "[昨天]LT";
+            },
+            nextWeek : function () {
+                var startOfWeek, prefix;
+                startOfWeek = moment().startOf('week');
+                prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';
+                return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm";
+            },
+            lastWeek : function () {
+                var startOfWeek, prefix;
+                startOfWeek = moment().startOf('week');
+                prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';
+                return this.minutes() === 0 ? prefix + "dddAh点整" : prefix + "dddAh点mm";
+            },
+            sameElse : 'LL'
+        },
+        ordinal : function (number, period) {
+            switch (period) {
+            case "d":
+            case "D":
+            case "DDD":
+                return number + "日";
+            case "M":
+                return number + "月";
+            case "w":
+            case "W":
+                return number + "周";
+            default:
+                return number;
+            }
+        },
+        relativeTime : {
+            future : "%s内",
+            past : "%s前",
+            s : "几秒",
+            m : "1分钟",
+            mm : "%d分钟",
+            h : "1小时",
+            hh : "%d小时",
+            d : "1天",
+            dd : "%d天",
+            M : "1个月",
+            MM : "%d个月",
+            y : "1年",
+            yy : "%d年"
+        },
+        week : {
+            // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
+            dow : 1, // Monday is the first day of the week.
+            doy : 4  // The week that contains Jan 4th is the first week of the year.
+        }
+    });
+}));
diff --git a/resources/moment/lang/zh-tw.js b/resources/moment/lang/zh-tw.js
new file mode 100644 (file)
index 0000000..bbb0737
--- /dev/null
@@ -0,0 +1,84 @@
+// moment.js language configuration
+// language : traditional chinese (zh-tw)
+// author : Ben : https://github.com/ben-lin
+
+(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.lang('zh-tw', {
+        months : "一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),
+        monthsShort : "1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),
+        weekdays : "星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),
+        weekdaysShort : "週日_週一_週二_週三_週四_週五_週六".split("_"),
+        weekdaysMin : "日_一_二_三_四_五_六".split("_"),
+        longDateFormat : {
+            LT : "Ah點mm",
+            L : "YYYY年MMMD日",
+            LL : "YYYY年MMMD日",
+            LLL : "YYYY年MMMD日LT",
+            LLLL : "YYYY年MMMD日ddddLT",
+            l : "YYYY年MMMD日",
+            ll : "YYYY年MMMD日",
+            lll : "YYYY年MMMD日LT",
+            llll : "YYYY年MMMD日ddddLT"
+        },
+        meridiem : function (hour, minute, isLower) {
+            var hm = hour * 100 + minute;
+            if (hm < 900) {
+                return "早上";
+            } else if (hm < 1130) {
+                return "上午";
+            } else if (hm < 1230) {
+                return "中午";
+            } else if (hm < 1800) {
+                return "下午";
+            } else {
+                return "晚上";
+            }
+        },
+        calendar : {
+            sameDay : '[今天]LT',
+            nextDay : '[明天]LT',
+            nextWeek : '[下]ddddLT',
+            lastDay : '[昨天]LT',
+            lastWeek : '[上]ddddLT',
+            sameElse : 'L'
+        },
+        ordinal : function (number, period) {
+            switch (period) {
+            case "d" :
+            case "D" :
+            case "DDD" :
+                return number + "日";
+            case "M" :
+                return number + "月";
+            case "w" :
+            case "W" :
+                return number + "週";
+            default :
+                return number;
+            }
+        },
+        relativeTime : {
+            future : "%s內",
+            past : "%s前",
+            s : "幾秒",
+            m : "一分鐘",
+            mm : "%d分鐘",
+            h : "一小時",
+            hh : "%d小時",
+            d : "一天",
+            dd : "%d天",
+            M : "一個月",
+            MM : "%d個月",
+            y : "一年",
+            yy : "%d年"
+        }
+    });
+}));
diff --git a/resources/moment/moment.js b/resources/moment/moment.js
new file mode 100644 (file)
index 0000000..b79da7f
--- /dev/null
@@ -0,0 +1,2400 @@
+//! moment.js
+//! version : 2.5.1
+//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
+//! license : MIT
+//! momentjs.com
+
+(function (undefined) {
+
+    /************************************
+        Constants
+    ************************************/
+
+    var moment,
+        VERSION = "2.5.1",
+        global = this,
+        round = Math.round,
+        i,
+
+        YEAR = 0,
+        MONTH = 1,
+        DATE = 2,
+        HOUR = 3,
+        MINUTE = 4,
+        SECOND = 5,
+        MILLISECOND = 6,
+
+        // internal storage for language config files
+        languages = {},
+
+        // moment internal properties
+        momentProperties = {
+            _isAMomentObject: null,
+            _i : null,
+            _f : null,
+            _l : null,
+            _strict : null,
+            _isUTC : null,
+            _offset : null,  // optional. Combine with _isUTC
+            _pf : null,
+            _lang : null  // optional
+        },
+
+        // check for nodeJS
+        hasModule = (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined'),
+
+        // ASP.NET json date format regex
+        aspNetJsonRegex = /^\/?Date\((\-?\d+)/i,
+        aspNetTimeSpanJsonRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,
+
+        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
+        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
+        isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,
+
+        // format tokens
+        formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|X|zz?|ZZ?|.)/g,
+        localFormattingTokens = /(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,
+
+        // parsing token regexes
+        parseTokenOneOrTwoDigits = /\d\d?/, // 0 - 99
+        parseTokenOneToThreeDigits = /\d{1,3}/, // 0 - 999
+        parseTokenOneToFourDigits = /\d{1,4}/, // 0 - 9999
+        parseTokenOneToSixDigits = /[+\-]?\d{1,6}/, // -999,999 - 999,999
+        parseTokenDigits = /\d+/, // nonzero number of digits
+        parseTokenWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.
+        parseTokenTimezone = /Z|[\+\-]\d\d:?\d\d/gi, // +00:00 -00:00 +0000 -0000 or Z
+        parseTokenT = /T/i, // T (ISO separator)
+        parseTokenTimestampMs = /[\+\-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123
+
+        //strict parsing regexes
+        parseTokenOneDigit = /\d/, // 0 - 9
+        parseTokenTwoDigits = /\d\d/, // 00 - 99
+        parseTokenThreeDigits = /\d{3}/, // 000 - 999
+        parseTokenFourDigits = /\d{4}/, // 0000 - 9999
+        parseTokenSixDigits = /[+-]?\d{6}/, // -999,999 - 999,999
+        parseTokenSignedNumber = /[+-]?\d+/, // -inf - inf
+
+        // iso 8601 regex
+        // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)
+        isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,
+
+        isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',
+
+        isoDates = [
+            ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/],
+            ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/],
+            ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/],
+            ['GGGG-[W]WW', /\d{4}-W\d{2}/],
+            ['YYYY-DDD', /\d{4}-\d{3}/]
+        ],
+
+        // iso time formats and regexes
+        isoTimes = [
+            ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d{1,3}/],
+            ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/],
+            ['HH:mm', /(T| )\d\d:\d\d/],
+            ['HH', /(T| )\d\d/]
+        ],
+
+        // timezone chunker "+10:00" > ["10", "00"] or "-1530" > ["-15", "30"]
+        parseTimezoneChunker = /([\+\-]|\d\d)/gi,
+
+        // getter and setter names
+        proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),
+        unitMillisecondFactors = {
+            'Milliseconds' : 1,
+            'Seconds' : 1e3,
+            'Minutes' : 6e4,
+            'Hours' : 36e5,
+            'Days' : 864e5,
+            'Months' : 2592e6,
+            'Years' : 31536e6
+        },
+
+        unitAliases = {
+            ms : 'millisecond',
+            s : 'second',
+            m : 'minute',
+            h : 'hour',
+            d : 'day',
+            D : 'date',
+            w : 'week',
+            W : 'isoWeek',
+            M : 'month',
+            y : 'year',
+            DDD : 'dayOfYear',
+            e : 'weekday',
+            E : 'isoWeekday',
+            gg: 'weekYear',
+            GG: 'isoWeekYear'
+        },
+
+        camelFunctions = {
+            dayofyear : 'dayOfYear',
+            isoweekday : 'isoWeekday',
+            isoweek : 'isoWeek',
+            weekyear : 'weekYear',
+            isoweekyear : 'isoWeekYear'
+        },
+
+        // format function strings
+        formatFunctions = {},
+
+        // tokens to ordinalize and pad
+        ordinalizeTokens = 'DDD w W M D d'.split(' '),
+        paddedTokens = 'M D H h m s w W'.split(' '),
+
+        formatTokenFunctions = {
+            M    : function () {
+                return this.month() + 1;
+            },
+            MMM  : function (format) {
+                return this.lang().monthsShort(this, format);
+            },
+            MMMM : function (format) {
+                return this.lang().months(this, format);
+            },
+            D    : function () {
+                return this.date();
+            },
+            DDD  : function () {
+                return this.dayOfYear();
+            },
+            d    : function () {
+                return this.day();
+            },
+            dd   : function (format) {
+                return this.lang().weekdaysMin(this, format);
+            },
+            ddd  : function (format) {
+                return this.lang().weekdaysShort(this, format);
+            },
+            dddd : function (format) {
+                return this.lang().weekdays(this, format);
+            },
+            w    : function () {
+                return this.week();
+            },
+            W    : function () {
+                return this.isoWeek();
+            },
+            YY   : function () {
+                return leftZeroFill(this.year() % 100, 2);
+            },
+            YYYY : function () {
+                return leftZeroFill(this.year(), 4);
+            },
+            YYYYY : function () {
+                return leftZeroFill(this.year(), 5);
+            },
+            YYYYYY : function () {
+                var y = this.year(), sign = y >= 0 ? '+' : '-';
+                return sign + leftZeroFill(Math.abs(y), 6);
+            },
+            gg   : function () {
+                return leftZeroFill(this.weekYear() % 100, 2);
+            },
+            gggg : function () {
+                return leftZeroFill(this.weekYear(), 4);
+            },
+            ggggg : function () {
+                return leftZeroFill(this.weekYear(), 5);
+            },
+            GG   : function () {
+                return leftZeroFill(this.isoWeekYear() % 100, 2);
+            },
+            GGGG : function () {
+                return leftZeroFill(this.isoWeekYear(), 4);
+            },
+            GGGGG : function () {
+                return leftZeroFill(this.isoWeekYear(), 5);
+            },
+            e : function () {
+                return this.weekday();
+            },
+            E : function () {
+                return this.isoWeekday();
+            },
+            a    : function () {
+                return this.lang().meridiem(this.hours(), this.minutes(), true);
+            },
+            A    : function () {
+                return this.lang().meridiem(this.hours(), this.minutes(), false);
+            },
+            H    : function () {
+                return this.hours();
+            },
+            h    : function () {
+                return this.hours() % 12 || 12;
+            },
+            m    : function () {
+                return this.minutes();
+            },
+            s    : function () {
+                return this.seconds();
+            },
+            S    : function () {
+                return toInt(this.milliseconds() / 100);
+            },
+            SS   : function () {
+                return leftZeroFill(toInt(this.milliseconds() / 10), 2);
+            },
+            SSS  : function () {
+                return leftZeroFill(this.milliseconds(), 3);
+            },
+            SSSS : function () {
+                return leftZeroFill(this.milliseconds(), 3);
+            },
+            Z    : function () {
+                var a = -this.zone(),
+                    b = "+";
+                if (a < 0) {
+                    a = -a;
+                    b = "-";
+                }
+                return b + leftZeroFill(toInt(a / 60), 2) + ":" + leftZeroFill(toInt(a) % 60, 2);
+            },
+            ZZ   : function () {
+                var a = -this.zone(),
+                    b = "+";
+                if (a < 0) {
+                    a = -a;
+                    b = "-";
+                }
+                return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);
+            },
+            z : function () {
+                return this.zoneAbbr();
+            },
+            zz : function () {
+                return this.zoneName();
+            },
+            X    : function () {
+                return this.unix();
+            },
+            Q : function () {
+                return this.quarter();
+            }
+        },
+
+        lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'];
+
+    function defaultParsingFlags() {
+        // We need to deep clone this object, and es5 standard is not very
+        // helpful.
+        return {
+            empty : false,
+            unusedTokens : [],
+            unusedInput : [],
+            overflow : -2,
+            charsLeftOver : 0,
+            nullInput : false,
+            invalidMonth : null,
+            invalidFormat : false,
+            userInvalidated : false,
+            iso: false
+        };
+    }
+
+    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);
+        };
+    }
+
+    while (ordinalizeTokens.length) {
+        i = ordinalizeTokens.pop();
+        formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);
+    }
+    while (paddedTokens.length) {
+        i = paddedTokens.pop();
+        formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);
+    }
+    formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);
+
+
+    /************************************
+        Constructors
+    ************************************/
+
+    function Language() {
+
+    }
+
+    // Moment prototype object
+    function Moment(config) {
+        checkOverflow(config);
+        extend(this, config);
+    }
+
+    // Duration Constructor
+    function Duration(duration) {
+        var normalizedInput = normalizeObjectUnits(duration),
+            years = normalizedInput.year || 0,
+            months = normalizedInput.month || 0,
+            weeks = normalizedInput.week || 0,
+            days = normalizedInput.day || 0,
+            hours = normalizedInput.hour || 0,
+            minutes = normalizedInput.minute || 0,
+            seconds = normalizedInput.second || 0,
+            milliseconds = normalizedInput.millisecond || 0;
+
+        // representation for dateAddRemove
+        this._milliseconds = +milliseconds +
+            seconds * 1e3 + // 1000
+            minutes * 6e4 + // 1000 * 60
+            hours * 36e5; // 1000 * 60 * 60
+        // Because of dateAddRemove treats 24 hours as different from a
+        // day when working around DST, we need to store them separately
+        this._days = +days +
+            weeks * 7;
+        // It is impossible translate months into days without knowing
+        // which months you are are talking about, so we have to store
+        // it separately.
+        this._months = +months +
+            years * 12;
+
+        this._data = {};
+
+        this._bubble();
+    }
+
+    /************************************
+        Helpers
+    ************************************/
+
+
+    function extend(a, b) {
+        for (var i in b) {
+            if (b.hasOwnProperty(i)) {
+                a[i] = b[i];
+            }
+        }
+
+        if (b.hasOwnProperty("toString")) {
+            a.toString = b.toString;
+        }
+
+        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];
+            }
+        }
+
+        return result;
+    }
+
+    function absRound(number) {
+        if (number < 0) {
+            return Math.ceil(number);
+        } else {
+            return Math.floor(number);
+        }
+    }
+
+    // left zero fill a number
+    // see http://jsperf.com/left-zero-filling for performance comparison
+    function leftZeroFill(number, targetLength, forceSign) {
+        var output = '' + Math.abs(number),
+            sign = number >= 0;
+
+        while (output.length < targetLength) {
+            output = '0' + output;
+        }
+        return (sign ? (forceSign ? '+' : '') : '-') + output;
+    }
+
+    // helper function for _.addTime and _.subtractTime
+    function addOrSubtractDurationFromMoment(mom, duration, isAdding, ignoreUpdateOffset) {
+        var milliseconds = duration._milliseconds,
+            days = duration._days,
+            months = duration._months,
+            minutes,
+            hours;
+
+        if (milliseconds) {
+            mom._d.setTime(+mom._d + milliseconds * isAdding);
+        }
+        // store the minutes and hours so we can restore them
+        if (days || months) {
+            minutes = mom.minute();
+            hours = mom.hour();
+        }
+        if (days) {
+            mom.date(mom.date() + days * isAdding);
+        }
+        if (months) {
+            mom.month(mom.month() + months * isAdding);
+        }
+        if (milliseconds && !ignoreUpdateOffset) {
+            moment.updateOffset(mom);
+        }
+        // restore the minutes and hours after possibly changing dst
+        if (days || months) {
+            mom.minute(minutes);
+            mom.hour(hours);
+        }
+    }
+
+    // check if is an array
+    function isArray(input) {
+        return Object.prototype.toString.call(input) === '[object Array]';
+    }
+
+    function isDate(input) {
+        return  Object.prototype.toString.call(input) === '[object Date]' ||
+                input instanceof Date;
+    }
+
+    // compare two arrays, return the number of differences
+    function compareArrays(array1, array2, dontConvert) {
+        var len = Math.min(array1.length, array2.length),
+            lengthDiff = Math.abs(array1.length - array2.length),
+            diffs = 0,
+            i;
+        for (i = 0; i < len; i++) {
+            if ((dontConvert && array1[i] !== array2[i]) ||
+                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {
+                diffs++;
+            }
+        }
+        return diffs + lengthDiff;
+    }
+
+    function normalizeUnits(units) {
+        if (units) {
+            var lowered = units.toLowerCase().replace(/(.)s$/, '$1');
+            units = unitAliases[units] || camelFunctions[lowered] || lowered;
+        }
+        return units;
+    }
+
+    function normalizeObjectUnits(inputObject) {
+        var normalizedInput = {},
+            normalizedProp,
+            prop;
+
+        for (prop in inputObject) {
+            if (inputObject.hasOwnProperty(prop)) {
+                normalizedProp = normalizeUnits(prop);
+                if (normalizedProp) {
+                    normalizedInput[normalizedProp] = inputObject[prop];
+                }
+            }
+        }
+
+        return normalizedInput;
+    }
+
+    function makeList(field) {
+        var count, setter;
+
+        if (field.indexOf('week') === 0) {
+            count = 7;
+            setter = 'day';
+        }
+        else if (field.indexOf('month') === 0) {
+            count = 12;
+            setter = 'month';
+        }
+        else {
+            return;
+        }
+
+        moment[field] = function (format, index) {
+            var i, getter,
+                method = moment.fn._lang[field],
+                results = [];
+
+            if (typeof format === 'number') {
+                index = format;
+                format = undefined;
+            }
+
+            getter = function (i) {
+                var m = moment().utc().set(setter, i);
+                return method.call(moment.fn._lang, m, format || '');
+            };
+
+            if (index != null) {
+                return getter(index);
+            }
+            else {
+                for (i = 0; i < count; i++) {
+                    results.push(getter(i));
+                }
+                return results;
+            }
+        };
+    }
+
+    function toInt(argumentForCoercion) {
+        var coercedNumber = +argumentForCoercion,
+            value = 0;
+
+        if (coercedNumber !== 0 && isFinite(coercedNumber)) {
+            if (coercedNumber >= 0) {
+                value = Math.floor(coercedNumber);
+            } else {
+                value = Math.ceil(coercedNumber);
+            }
+        }
+
+        return value;
+    }
+
+    function daysInMonth(year, month) {
+        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
+    }
+
+    function daysInYear(year) {
+        return isLeapYear(year) ? 366 : 365;
+    }
+
+    function isLeapYear(year) {
+        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
+    }
+
+    function checkOverflow(m) {
+        var overflow;
+        if (m._a && m._pf.overflow === -2) {
+            overflow =
+                m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :
+                m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :
+                m._a[HOUR] < 0 || m._a[HOUR] > 23 ? HOUR :
+                m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :
+                m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :
+                m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :
+                -1;
+
+            if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {
+                overflow = DATE;
+            }
+
+            m._pf.overflow = overflow;
+        }
+    }
+
+    function isValid(m) {
+        if (m._isValid == null) {
+            m._isValid = !isNaN(m._d.getTime()) &&
+                m._pf.overflow < 0 &&
+                !m._pf.empty &&
+                !m._pf.invalidMonth &&
+                !m._pf.nullInput &&
+                !m._pf.invalidFormat &&
+                !m._pf.userInvalidated;
+
+            if (m._strict) {
+                m._isValid = m._isValid &&
+                    m._pf.charsLeftOver === 0 &&
+                    m._pf.unusedTokens.length === 0;
+            }
+        }
+        return m._isValid;
+    }
+
+    function normalizeLanguage(key) {
+        return key ? key.toLowerCase().replace('_', '-') : key;
+    }
+
+    // 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) :
+            moment(input).local();
+    }
+
+    /************************************
+        Languages
+    ************************************/
+
+
+    extend(Language.prototype, {
+
+        set : function (config) {
+            var prop, i;
+            for (i in config) {
+                prop = config[i];
+                if (typeof prop === 'function') {
+                    this[i] = prop;
+                } else {
+                    this['_' + i] = prop;
+                }
+            }
+        },
+
+        _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 : function (m) {
+            return this._monthsShort[m.month()];
+        },
+
+        monthsParse : function (monthName) {
+            var i, mom, regex;
+
+            if (!this._monthsParse) {
+                this._monthsParse = [];
+            }
+
+            for (i = 0; i < 12; i++) {
+                // make the regex if we don't have it already
+                if (!this._monthsParse[i]) {
+                    mom = moment.utc([2000, i]);
+                    regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
+                    this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
+                }
+                // test the regex
+                if (this._monthsParse[i].test(monthName)) {
+                    return i;
+                }
+            }
+        },
+
+        _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 : function (m) {
+            return this._weekdaysShort[m.day()];
+        },
+
+        _weekdaysMin : "Su_Mo_Tu_We_Th_Fr_Sa".split("_"),
+        weekdaysMin : function (m) {
+            return this._weekdaysMin[m.day()];
+        },
+
+        weekdaysParse : function (weekdayName) {
+            var i, mom, regex;
+
+            if (!this._weekdaysParse) {
+                this._weekdaysParse = [];
+            }
+
+            for (i = 0; i < 7; i++) {
+                // make the regex if we don't have it already
+                if (!this._weekdaysParse[i]) {
+                    mom = moment([2000, 1]).day(i);
+                    regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
+                    this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
+                }
+                // test the regex
+                if (this._weekdaysParse[i].test(weekdayName)) {
+                    return i;
+                }
+            }
+        },
+
+        _longDateFormat : {
+            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];
+            if (!output && this._longDateFormat[key.toUpperCase()]) {
+                output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {
+                    return val.slice(1);
+                });
+                this._longDateFormat[key] = output;
+            }
+            return output;
+        },
+
+        isPM : function (input) {
+            // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
+            // Using charAt should be more compatible.
+            return ((input + '').toLowerCase().charAt(0) === 'p');
+        },
+
+        _meridiemParse : /[ap]\.?m?\.?/i,
+        meridiem : function (hours, minutes, isLower) {
+            if (hours > 11) {
+                return isLower ? 'pm' : 'PM';
+            } else {
+                return isLower ? 'am' : 'AM';
+            }
+        },
+
+        _calendar : {
+            sameDay : '[Today at] LT',
+            nextDay : '[Tomorrow at] LT',
+            nextWeek : 'dddd [at] LT',
+            lastDay : '[Yesterday at] LT',
+            lastWeek : '[Last] dddd [at] LT',
+            sameElse : 'L'
+        },
+        calendar : function (key, mom) {
+            var output = this._calendar[key];
+            return typeof output === 'function' ? output.apply(mom) : output;
+        },
+
+        _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"
+        },
+        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);
+        },
+        _ordinal : "%d",
+
+        preparse : function (string) {
+            return string;
+        },
+
+        postformat : function (string) {
+            return string;
+        },
+
+        week : function (mom) {
+            return weekOfYear(mom, this._week.dow, this._week.doy).week;
+        },
+
+        _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.
+        },
+
+        _invalidDate: 'Invalid date',
+        invalidDate: function () {
+            return this._invalidDate;
+        }
+    });
+
+    // 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, "");
+    }
+
+    function makeFormatFunction(format) {
+        var array = format.match(formattingTokens), i, length;
+
+        for (i = 0, length = array.length; i < length; i++) {
+            if (formatTokenFunctions[array[i]]) {
+                array[i] = formatTokenFunctions[array[i]];
+            } else {
+                array[i] = removeFormattingTokens(array[i]);
+            }
+        }
+
+        return function (mom) {
+            var output = "";
+            for (i = 0; i < length; i++) {
+                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];
+            }
+            return output;
+        };
+    }
+
+    // format date using native date object
+    function formatMoment(m, format) {
+
+        if (!m.isValid()) {
+            return m.lang().invalidDate();
+        }
+
+        format = expandFormat(format, m.lang());
+
+        if (!formatFunctions[format]) {
+            formatFunctions[format] = makeFormatFunction(format);
+        }
+
+        return formatFunctions[format](m);
+    }
+
+    function expandFormat(format, lang) {
+        var i = 5;
+
+        function replaceLongDateFormatTokens(input) {
+            return lang.longDateFormat(input) || input;
+        }
+
+        localFormattingTokens.lastIndex = 0;
+        while (i >= 0 && localFormattingTokens.test(format)) {
+            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);
+            localFormattingTokens.lastIndex = 0;
+            i -= 1;
+        }
+
+        return format;
+    }
+
+
+    /************************************
+        Parsing
+    ************************************/
+
+
+    // get the regex to find the next token
+    function getParseRegexForToken(token, config) {
+        var a, strict = config._strict;
+        switch (token) {
+        case 'DDDD':
+            return parseTokenThreeDigits;
+        case 'YYYY':
+        case 'GGGG':
+        case 'gggg':
+            return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;
+        case 'Y':
+        case 'G':
+        case 'g':
+            return parseTokenSignedNumber;
+        case 'YYYYYY':
+        case 'YYYYY':
+        case 'GGGGG':
+        case 'ggggg':
+            return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;
+        case 'S':
+            if (strict) { return parseTokenOneDigit; }
+            /* falls through */
+        case 'SS':
+            if (strict) { return parseTokenTwoDigits; }
+            /* falls through */
+        case 'SSS':
+            if (strict) { return parseTokenThreeDigits; }
+            /* falls through */
+        case 'DDD':
+            return parseTokenOneToThreeDigits;
+        case 'MMM':
+        case 'MMMM':
+        case 'dd':
+        case 'ddd':
+        case 'dddd':
+            return parseTokenWord;
+        case 'a':
+        case 'A':
+            return getLangDefinition(config._l)._meridiemParse;
+        case 'X':
+            return parseTokenTimestampMs;
+        case 'Z':
+        case 'ZZ':
+            return parseTokenTimezone;
+        case 'T':
+            return parseTokenT;
+        case 'SSSS':
+            return parseTokenDigits;
+        case 'MM':
+        case 'DD':
+        case 'YY':
+        case 'GG':
+        case 'gg':
+        case 'HH':
+        case 'hh':
+        case 'mm':
+        case 'ss':
+        case 'ww':
+        case 'WW':
+            return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;
+        case 'M':
+        case 'D':
+        case 'd':
+        case 'H':
+        case 'h':
+        case 'm':
+        case 's':
+        case 'w':
+        case 'W':
+        case 'e':
+        case 'E':
+            return parseTokenOneOrTwoDigits;
+        default :
+            a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\', '')), "i"));
+            return a;
+        }
+    }
+
+    function timezoneMinutesFromString(string) {
+        string = string || "";
+        var possibleTzMatches = (string.match(parseTokenTimezone) || []),
+            tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],
+            parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],
+            minutes = +(parts[1] * 60) + toInt(parts[2]);
+
+        return parts[0] === '+' ? -minutes : minutes;
+    }
+
+    // function to convert string input to date
+    function addTimeToArrayFromToken(token, input, config) {
+        var a, datePartArray = config._a;
+
+        switch (token) {
+        // MONTH
+        case 'M' : // fall through to MM
+        case 'MM' :
+            if (input != null) {
+                datePartArray[MONTH] = toInt(input) - 1;
+            }
+            break;
+        case 'MMM' : // fall through to MMMM
+        case 'MMMM' :
+            a = getLangDefinition(config._l).monthsParse(input);
+            // if we didn't find a month name, mark the date as invalid.
+            if (a != null) {
+                datePartArray[MONTH] = a;
+            } else {
+                config._pf.invalidMonth = input;
+            }
+            break;
+        // DAY OF MONTH
+        case 'D' : // fall through to DD
+        case 'DD' :
+            if (input != null) {
+                datePartArray[DATE] = toInt(input);
+            }
+            break;
+        // DAY OF YEAR
+        case 'DDD' : // fall through to DDDD
+        case 'DDDD' :
+            if (input != null) {
+                config._dayOfYear = toInt(input);
+            }
+
+            break;
+        // YEAR
+        case 'YY' :
+            datePartArray[YEAR] = toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
+            break;
+        case 'YYYY' :
+        case 'YYYYY' :
+        case 'YYYYYY' :
+            datePartArray[YEAR] = toInt(input);
+            break;
+        // AM / PM
+        case 'a' : // fall through to A
+        case 'A' :
+            config._isPm = getLangDefinition(config._l).isPM(input);
+            break;
+        // 24 HOUR
+        case 'H' : // fall through to hh
+        case 'HH' : // fall through to hh
+        case 'h' : // fall through to hh
+        case 'hh' :
+            datePartArray[HOUR] = toInt(input);
+            break;
+        // MINUTE
+        case 'm' : // fall through to mm
+        case 'mm' :
+            datePartArray[MINUTE] = toInt(input);
+            break;
+        // SECOND
+        case 's' : // fall through to ss
+        case 'ss' :
+            datePartArray[SECOND] = toInt(input);
+            break;
+        // MILLISECOND
+        case 'S' :
+        case 'SS' :
+        case 'SSS' :
+        case 'SSSS' :
+            datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);
+            break;
+        // UNIX TIMESTAMP WITH MS
+        case 'X':
+            config._d = new Date(parseFloat(input) * 1000);
+            break;
+        // TIMEZONE
+        case 'Z' : // fall through to ZZ
+        case 'ZZ' :
+            config._useUTC = true;
+            config._tzm = timezoneMinutesFromString(input);
+            break;
+        case 'w':
+        case 'ww':
+        case 'W':
+        case 'WW':
+        case 'd':
+        case 'dd':
+        case 'ddd':
+        case 'dddd':
+        case 'e':
+        case 'E':
+            token = token.substr(0, 1);
+            /* falls through */
+        case 'gg':
+        case 'gggg':
+        case 'GG':
+        case 'GGGG':
+        case 'GGGGG':
+            token = token.substr(0, 2);
+            if (input) {
+                config._w = config._w || {};
+                config._w[token] = input;
+            }
+            break;
+        }
+    }
+
+    // convert an array to a date.
+    // the array should mirror the parameters below
+    // note: all values past the year are optional and will default to the lowest possible value.
+    // [year, month, day , hour, minute, second, millisecond]
+    function dateFromConfig(config) {
+        var i, date, input = [], currentDate,
+            yearToUse, fixYear, w, temp, lang, weekday, week;
+
+        if (config._d) {
+            return;
+        }
+
+        currentDate = currentDateArray(config);
+
+        //compute day of the year from weeks and weekdays
+        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
+            fixYear = function (val) {
+                var int_val = parseInt(val, 10);
+                return val ?
+                  (val.length < 3 ? (int_val > 68 ? 1900 + int_val : 2000 + int_val) : int_val) :
+                  (config._a[YEAR] == null ? moment().weekYear() : config._a[YEAR]);
+            };
+
+            w = config._w;
+            if (w.GG != null || w.W != null || w.E != null) {
+                temp = dayOfYearFromWeeks(fixYear(w.GG), w.W || 1, w.E, 4, 1);
+            }
+            else {
+                lang = getLangDefinition(config._l);
+                weekday = w.d != null ?  parseWeekday(w.d, lang) :
+                  (w.e != null ?  parseInt(w.e, 10) + lang._week.dow : 0);
+
+                week = parseInt(w.w, 10) || 1;
+
+                //if we're parsing 'd', then the low day numbers may be next week
+                if (w.d != null && weekday < lang._week.dow) {
+                    week++;
+                }
+
+                temp = dayOfYearFromWeeks(fixYear(w.gg), week, weekday, lang._week.doy, lang._week.dow);
+            }
+
+            config._a[YEAR] = temp.year;
+            config._dayOfYear = temp.dayOfYear;
+        }
+
+        //if the day of the year is set, figure out what it is
+        if (config._dayOfYear) {
+            yearToUse = config._a[YEAR] == null ? currentDate[YEAR] : config._a[YEAR];
+
+            if (config._dayOfYear > daysInYear(yearToUse)) {
+                config._pf._overflowDayOfYear = true;
+            }
+
+            date = makeUTCDate(yearToUse, 0, config._dayOfYear);
+            config._a[MONTH] = date.getUTCMonth();
+            config._a[DATE] = date.getUTCDate();
+        }
+
+        // Default to current date.
+        // * if no year, month, day of month are given, default to today
+        // * if day of month is given, default month and year
+        // * if month is given, default only year
+        // * if year is given, don't default anything
+        for (i = 0; i < 3 && config._a[i] == null; ++i) {
+            config._a[i] = input[i] = currentDate[i];
+        }
+
+        // Zero out whatever was not defaulted, including time
+        for (; i < 7; i++) {
+            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
+        }
+
+        // add the offsets to the time to be parsed so that we can have a clean array for checking isValid
+        input[HOUR] += toInt((config._tzm || 0) / 60);
+        input[MINUTE] += toInt((config._tzm || 0) % 60);
+
+        config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);
+    }
+
+    function dateFromObject(config) {
+        var normalizedInput;
+
+        if (config._d) {
+            return;
+        }
+
+        normalizedInput = normalizeObjectUnits(config._i);
+        config._a = [
+            normalizedInput.year,
+            normalizedInput.month,
+            normalizedInput.day,
+            normalizedInput.hour,
+            normalizedInput.minute,
+            normalizedInput.second,
+            normalizedInput.millisecond
+        ];
+
+        dateFromConfig(config);
+    }
+
+    function currentDateArray(config) {
+        var now = new Date();
+        if (config._useUTC) {
+            return [
+                now.getUTCFullYear(),
+                now.getUTCMonth(),
+                now.getUTCDate()
+            ];
+        } else {
+            return [now.getFullYear(), now.getMonth(), now.getDate()];
+        }
+    }
+
+    // date from string and format string
+    function makeDateFromStringAndFormat(config) {
+
+        config._a = [];
+        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,
+            i, parsedInput, tokens, token, skipped,
+            stringLength = string.length,
+            totalParsedInputLength = 0;
+
+        tokens = expandFormat(config._f, lang).match(formattingTokens) || [];
+
+        for (i = 0; i < tokens.length; i++) {
+            token = tokens[i];
+            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
+            if (parsedInput) {
+                skipped = string.substr(0, string.indexOf(parsedInput));
+                if (skipped.length > 0) {
+                    config._pf.unusedInput.push(skipped);
+                }
+                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
+                totalParsedInputLength += parsedInput.length;
+            }
+            // don't parse if it's not a known token
+            if (formatTokenFunctions[token]) {
+                if (parsedInput) {
+                    config._pf.empty = false;
+                }
+                else {
+                    config._pf.unusedTokens.push(token);
+                }
+                addTimeToArrayFromToken(token, parsedInput, config);
+            }
+            else if (config._strict && !parsedInput) {
+                config._pf.unusedTokens.push(token);
+            }
+        }
+
+        // add remaining unparsed input length to the string
+        config._pf.charsLeftOver = stringLength - totalParsedInputLength;
+        if (string.length > 0) {
+            config._pf.unusedInput.push(string);
+        }
+
+        // handle am pm
+        if (config._isPm && config._a[HOUR] < 12) {
+            config._a[HOUR] += 12;
+        }
+        // if is 12 am, change hours to 0
+        if (config._isPm === false && config._a[HOUR] === 12) {
+            config._a[HOUR] = 0;
+        }
+
+        dateFromConfig(config);
+        checkOverflow(config);
+    }
+
+    function unescapeFormat(s) {
+        return s.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) {
+            return p1 || p2 || p3 || p4;
+        });
+    }
+
+    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript
+    function regexpEscape(s) {
+        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+    }
+
+    // date from string and array of format strings
+    function makeDateFromStringAndArray(config) {
+        var tempConfig,
+            bestMoment,
+
+            scoreToBeat,
+            i,
+            currentScore;
+
+        if (config._f.length === 0) {
+            config._pf.invalidFormat = true;
+            config._d = new Date(NaN);
+            return;
+        }
+
+        for (i = 0; i < config._f.length; i++) {
+            currentScore = 0;
+            tempConfig = extend({}, config);
+            tempConfig._pf = defaultParsingFlags();
+            tempConfig._f = config._f[i];
+            makeDateFromStringAndFormat(tempConfig);
+
+            if (!isValid(tempConfig)) {
+                continue;
+            }
+
+            // if there is any input that was not parsed add a penalty for that format
+            currentScore += tempConfig._pf.charsLeftOver;
+
+            //or tokens
+            currentScore += tempConfig._pf.unusedTokens.length * 10;
+
+            tempConfig._pf.score = currentScore;
+
+            if (scoreToBeat == null || currentScore < scoreToBeat) {
+                scoreToBeat = currentScore;
+                bestMoment = tempConfig;
+            }
+        }
+
+        extend(config, bestMoment || tempConfig);
+    }
+
+    // date from iso format
+    function makeDateFromString(config) {
+        var i, l,
+            string = config._i,
+            match = isoRegex.exec(string);
+
+        if (match) {
+            config._pf.iso = true;
+            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] || " ");
+                    break;
+                }
+            }
+            for (i = 0, l = isoTimes.length; i < l; i++) {
+                if (isoTimes[i][1].exec(string)) {
+                    config._f += isoTimes[i][0];
+                    break;
+                }
+            }
+            if (string.match(parseTokenTimezone)) {
+                config._f += "Z";
+            }
+            makeDateFromStringAndFormat(config);
+        }
+        else {
+            config._d = new Date(string);
+        }
+    }
+
+    function makeDateFromInput(config) {
+        var input = config._i,
+            matched = aspNetJsonRegex.exec(input);
+
+        if (input === undefined) {
+            config._d = new Date();
+        } else if (matched) {
+            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 {
+            config._d = new Date(input);
+        }
+    }
+
+    function makeDate(y, m, d, h, M, s, ms) {
+        //can't just apply() to create a date:
+        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
+        var date = new Date(y, m, d, h, M, s, ms);
+
+        //the date constructor doesn't accept years < 1970
+        if (y < 1970) {
+            date.setFullYear(y);
+        }
+        return date;
+    }
+
+    function makeUTCDate(y) {
+        var date = new Date(Date.UTC.apply(null, arguments));
+        if (y < 1970) {
+            date.setUTCFullYear(y);
+        }
+        return date;
+    }
+
+    function parseWeekday(input, language) {
+        if (typeof input === 'string') {
+            if (!isNaN(input)) {
+                input = parseInt(input, 10);
+            }
+            else {
+                input = language.weekdaysParse(input);
+                if (typeof input !== 'number') {
+                    return null;
+                }
+            }
+        }
+        return input;
+    }
+
+    /************************************
+        Relative Time
+    ************************************/
+
+
+    // 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 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 < 45 && ['s', seconds] ||
+                minutes === 1 && ['m'] ||
+                minutes < 45 && ['mm', minutes] ||
+                hours === 1 && ['h'] ||
+                hours < 22 && ['hh', hours] ||
+                days === 1 && ['d'] ||
+                days <= 25 && ['dd', days] ||
+                days <= 45 && ['M'] ||
+                days < 345 && ['MM', round(days / 30)] ||
+                years === 1 && ['y'] || ['yy', years];
+        args[2] = withoutSuffix;
+        args[3] = milliseconds > 0;
+        args[4] = lang;
+        return substituteTimeAgo.apply({}, args);
+    }
+
+
+    /************************************
+        Week of Year
+    ************************************/
+
+
+    // firstDayOfWeek       0 = sun, 6 = sat
+    //                      the day of the week that starts the week
+    //                      (usually sunday or monday)
+    // firstDayOfWeekOfYear 0 = sun, 6 = sat
+    //                      the first week is the week that contains the first
+    //                      of this day of the week
+    //                      (eg. ISO weeks use thursday (4))
+    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {
+        var end = firstDayOfWeekOfYear - firstDayOfWeek,
+            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),
+            adjustedMoment;
+
+
+        if (daysToDayOfWeek > end) {
+            daysToDayOfWeek -= 7;
+        }
+
+        if (daysToDayOfWeek < end - 7) {
+            daysToDayOfWeek += 7;
+        }
+
+        adjustedMoment = moment(mom).add('d', daysToDayOfWeek);
+        return {
+            week: Math.ceil(adjustedMoment.dayOfYear() / 7),
+            year: adjustedMoment.year()
+        };
+    }
+
+    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
+    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {
+        var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;
+
+        weekday = weekday != null ? weekday : firstDayOfWeek;
+        daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);
+        dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;
+
+        return {
+            year: dayOfYear > 0 ? year : year - 1,
+            dayOfYear: dayOfYear > 0 ?  dayOfYear : daysInYear(year - 1) + dayOfYear
+        };
+    }
+
+    /************************************
+        Top Level Functions
+    ************************************/
+
+    function makeMoment(config) {
+        var input = config._i,
+            format = config._f;
+
+        if (input === null) {
+            return moment.invalid({nullInput: true});
+        }
+
+        if (typeof input === 'string') {
+            config._i = input = getLangDefinition().preparse(input);
+        }
+
+        if (moment.isMoment(input)) {
+            config = cloneMoment(input);
+
+            config._d = new Date(+input._d);
+        } else if (format) {
+            if (isArray(format)) {
+                makeDateFromStringAndArray(config);
+            } else {
+                makeDateFromStringAndFormat(config);
+            }
+        } else {
+            makeDateFromInput(config);
+        }
+
+        return new Moment(config);
+    }
+
+    moment = function (input, format, lang, strict) {
+        var c;
+
+        if (typeof(lang) === "boolean") {
+            strict = lang;
+            lang = undefined;
+        }
+        // object construction must be done this way.
+        // https://github.com/moment/moment/issues/1423
+        c = {};
+        c._isAMomentObject = true;
+        c._i = input;
+        c._f = format;
+        c._l = lang;
+        c._strict = strict;
+        c._isUTC = false;
+        c._pf = defaultParsingFlags();
+
+        return makeMoment(c);
+    };
+
+    // creating with utc
+    moment.utc = function (input, format, lang, strict) {
+        var c;
+
+        if (typeof(lang) === "boolean") {
+            strict = lang;
+            lang = undefined;
+        }
+        // object construction must be done this way.
+        // https://github.com/moment/moment/issues/1423
+        c = {};
+        c._isAMomentObject = true;
+        c._useUTC = true;
+        c._isUTC = true;
+        c._l = lang;
+        c._i = input;
+        c._f = format;
+        c._strict = strict;
+        c._pf = defaultParsingFlags();
+
+        return makeMoment(c).utc();
+    };
+
+    // creating with unix timestamp (in seconds)
+    moment.unix = function (input) {
+        return moment(input * 1000);
+    };
+
+    // duration
+    moment.duration = function (input, key) {
+        var duration = input,
+            // matching against regexp is expensive, do it on demand
+            match = null,
+            sign,
+            ret,
+            parseIso;
+
+        if (moment.isDuration(input)) {
+            duration = {
+                ms: input._milliseconds,
+                d: input._days,
+                M: input._months
+            };
+        } else if (typeof input === 'number') {
+            duration = {};
+            if (key) {
+                duration[key] = input;
+            } else {
+                duration.milliseconds = input;
+            }
+        } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {
+            sign = (match[1] === "-") ? -1 : 1;
+            duration = {
+                y: 0,
+                d: toInt(match[DATE]) * sign,
+                h: toInt(match[HOUR]) * sign,
+                m: toInt(match[MINUTE]) * sign,
+                s: toInt(match[SECOND]) * sign,
+                ms: toInt(match[MILLISECOND]) * sign
+            };
+        } else if (!!(match = isoDurationRegex.exec(input))) {
+            sign = (match[1] === "-") ? -1 : 1;
+            parseIso = function (inp) {
+                // We'd normally use ~~inp for this, but unfortunately it also
+                // converts floats to ints.
+                // inp may be undefined, so careful calling replace on it.
+                var res = inp && parseFloat(inp.replace(',', '.'));
+                // apply sign while we're at it
+                return (isNaN(res) ? 0 : res) * sign;
+            };
+            duration = {
+                y: parseIso(match[2]),
+                M: parseIso(match[3]),
+                d: parseIso(match[4]),
+                h: parseIso(match[5]),
+                m: parseIso(match[6]),
+                s: parseIso(match[7]),
+                w: parseIso(match[8])
+            };
+        }
+
+        ret = new Duration(duration);
+
+        if (moment.isDuration(input) && input.hasOwnProperty('_lang')) {
+            ret._lang = input._lang;
+        }
+
+        return ret;
+    };
+
+    // version number
+    moment.version = VERSION;
+
+    // default format
+    moment.defaultFormat = isoFormat;
+
+    // This function will be called whenever a moment is mutated.
+    // It is intended to keep the offset in sync with the timezone.
+    moment.updateOffset = function () {};
+
+    // This function will load languages and then set the global language.  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;
+    };
+
+    // returns language data
+    moment.langData = function (key) {
+        if (key && key._lang && key._lang._abbr) {
+            key = key._lang._abbr;
+        }
+        return getLangDefinition(key);
+    };
+
+    // compare moment object
+    moment.isMoment = function (obj) {
+        return obj instanceof Moment ||
+            (obj != null &&  obj.hasOwnProperty('_isAMomentObject'));
+    };
+
+    // for typechecking Duration objects
+    moment.isDuration = function (obj) {
+        return obj instanceof Duration;
+    };
+
+    for (i = lists.length - 1; i >= 0; --i) {
+        makeList(lists[i]);
+    }
+
+    moment.normalizeUnits = function (units) {
+        return normalizeUnits(units);
+    };
+
+    moment.invalid = function (flags) {
+        var m = moment.utc(NaN);
+        if (flags != null) {
+            extend(m._pf, flags);
+        }
+        else {
+            m._pf.userInvalidated = true;
+        }
+
+        return m;
+    };
+
+    moment.parseZone = function (input) {
+        return moment(input).parseZone();
+    };
+
+    /************************************
+        Moment Prototype
+    ************************************/
+
+
+    extend(moment.fn = Moment.prototype, {
+
+        clone : function () {
+            return moment(this);
+        },
+
+        valueOf : function () {
+            return +this._d + ((this._offset || 0) * 60000);
+        },
+
+        unix : function () {
+            return Math.floor(+this / 1000);
+        },
+
+        toString : function () {
+            return this.clone().lang('en').format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ");
+        },
+
+        toDate : function () {
+            return this._offset ? new Date(+this) : this._d;
+        },
+
+        toISOString : function () {
+            var m = moment(this).utc();
+            if (0 < m.year() && m.year() <= 9999) {
+                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
+            } else {
+                return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
+            }
+        },
+
+        toArray : function () {
+            var m = this;
+            return [
+                m.year(),
+                m.month(),
+                m.date(),
+                m.hours(),
+                m.minutes(),
+                m.seconds(),
+                m.milliseconds()
+            ];
+        },
+
+        isValid : function () {
+            return isValid(this);
+        },
+
+        isDSTShifted : function () {
+
+            if (this._a) {
+                return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;
+            }
+
+            return false;
+        },
+
+        parsingFlags : function () {
+            return extend({}, this._pf);
+        },
+
+        invalidAt: function () {
+            return this._pf.overflow;
+        },
+
+        utc : function () {
+            return this.zone(0);
+        },
+
+        local : function () {
+            this.zone(0);
+            this._isUTC = false;
+            return this;
+        },
+
+        format : function (inputString) {
+            var output = formatMoment(this, inputString || moment.defaultFormat);
+            return this.lang().postformat(output);
+        },
+
+        add : function (input, val) {
+            var dur;
+            // switch args to support add('s', 1) and add(1, 's')
+            if (typeof input === 'string') {
+                dur = moment.duration(+val, input);
+            } else {
+                dur = moment.duration(input, val);
+            }
+            addOrSubtractDurationFromMoment(this, dur, 1);
+            return this;
+        },
+
+        subtract : function (input, val) {
+            var dur;
+            // switch args to support subtract('s', 1) and subtract(1, 's')
+            if (typeof input === 'string') {
+                dur = moment.duration(+val, input);
+            } else {
+                dur = moment.duration(input, val);
+            }
+            addOrSubtractDurationFromMoment(this, dur, -1);
+            return this;
+        },
+
+        diff : function (input, units, asFloat) {
+            var that = makeAs(input, this),
+                zoneDiff = (this.zone() - that.zone()) * 6e4,
+                diff, output;
+
+            units = normalizeUnits(units);
+
+            if (units === 'year' || units === 'month') {
+                // average number of days in the months in the given dates
+                diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
+                // difference in months
+                output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
+                // adjust by taking difference in days, average number of days
+                // and dst in the given months.
+                output += ((this - moment(this).startOf('month')) -
+                        (that - moment(that).startOf('month'))) / diff;
+                // same as above but with zones, to negate all dst
+                output -= ((this.zone() - moment(this).startOf('month').zone()) -
+                        (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
+                if (units === 'year') {
+                    output = output / 12;
+                }
+            } else {
+                diff = (this - that);
+                output = units === 'second' ? diff / 1e3 : // 1000
+                    units === 'minute' ? diff / 6e4 : // 1000 * 60
+                    units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
+                    units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
+                    units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
+                    diff;
+            }
+            return asFloat ? output : absRound(output);
+        },
+
+        from : function (time, withoutSuffix) {
+            return moment.duration(this.diff(time)).lang(this.lang()._abbr).humanize(!withoutSuffix);
+        },
+
+        fromNow : function (withoutSuffix) {
+            return this.from(moment(), withoutSuffix);
+        },
+
+        calendar : function () {
+            // We want to compare the start of today, vs this.
+            // Getting start-of-today depends on whether we're zone'd or not.
+            var sod = makeAs(moment(), this).startOf('day'),
+                diff = this.diff(sod, 'days', true),
+                format = diff < -6 ? 'sameElse' :
+                    diff < -1 ? 'lastWeek' :
+                    diff < 0 ? 'lastDay' :
+                    diff < 1 ? 'sameDay' :
+                    diff < 2 ? 'nextDay' :
+                    diff < 7 ? 'nextWeek' : 'sameElse';
+            return this.format(this.lang().calendar(format, this));
+        },
+
+        isLeapYear : function () {
+            return isLeapYear(this.year());
+        },
+
+        isDST : function () {
+            return (this.zone() < this.clone().month(0).zone() ||
+                this.zone() < this.clone().month(5).zone());
+        },
+
+        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 });
+            } else {
+                return day;
+            }
+        },
+
+        month : function (input) {
+            var utc = this._isUTC ? 'UTC' : '',
+                dayOfMonth;
+
+            if (input != null) {
+                if (typeof input === 'string') {
+                    input = this.lang().monthsParse(input);
+                    if (typeof input !== 'number') {
+                        return this;
+                    }
+                }
+
+                dayOfMonth = this.date();
+                this.date(1);
+                this._d['set' + utc + 'Month'](input);
+                this.date(Math.min(dayOfMonth, this.daysInMonth()));
+
+                moment.updateOffset(this);
+                return this;
+            } else {
+                return this._d['get' + utc + 'Month']();
+            }
+        },
+
+        startOf: function (units) {
+            units = normalizeUnits(units);
+            // the following switch intentionally omits break keywords
+            // to utilize falling through the cases.
+            switch (units) {
+            case 'year':
+                this.month(0);
+                /* falls through */
+            case 'month':
+                this.date(1);
+                /* falls through */
+            case 'week':
+            case 'isoWeek':
+            case 'day':
+                this.hours(0);
+                /* falls through */
+            case 'hour':
+                this.minutes(0);
+                /* falls through */
+            case 'minute':
+                this.seconds(0);
+                /* falls through */
+            case 'second':
+                this.milliseconds(0);
+                /* falls through */
+            }
+
+            // weeks are a special case
+            if (units === 'week') {
+                this.weekday(0);
+            } else if (units === 'isoWeek') {
+                this.isoWeekday(1);
+            }
+
+            return this;
+        },
+
+        endOf: function (units) {
+            units = normalizeUnits(units);
+            return this.startOf(units).add((units === 'isoWeek' ? 'week' : units), 1).subtract('ms', 1);
+        },
+
+        isAfter: function (input, units) {
+            units = typeof units !== 'undefined' ? units : 'millisecond';
+            return +this.clone().startOf(units) > +moment(input).startOf(units);
+        },
+
+        isBefore: function (input, units) {
+            units = typeof units !== 'undefined' ? units : 'millisecond';
+            return +this.clone().startOf(units) < +moment(input).startOf(units);
+        },
+
+        isSame: function (input, units) {
+            units = units || 'ms';
+            return +this.clone().startOf(units) === +makeAs(input, this).startOf(units);
+        },
+
+        min: function (other) {
+            other = moment.apply(null, arguments);
+            return other < this ? this : other;
+        },
+
+        max: function (other) {
+            other = moment.apply(null, arguments);
+            return other > this ? this : other;
+        },
+
+        zone : function (input) {
+            var offset = this._offset || 0;
+            if (input != null) {
+                if (typeof input === "string") {
+                    input = timezoneMinutesFromString(input);
+                }
+                if (Math.abs(input) < 16) {
+                    input = input * 60;
+                }
+                this._offset = input;
+                this._isUTC = true;
+                if (offset !== input) {
+                    addOrSubtractDurationFromMoment(this, moment.duration(offset - input, 'm'), 1, true);
+                }
+            } else {
+                return this._isUTC ? offset : this._d.getTimezoneOffset();
+            }
+            return this;
+        },
+
+        zoneAbbr : function () {
+            return this._isUTC ? "UTC" : "";
+        },
+
+        zoneName : function () {
+            return this._isUTC ? "Coordinated Universal Time" : "";
+        },
+
+        parseZone : function () {
+            if (this._tzm) {
+                this.zone(this._tzm);
+            } else if (typeof this._i === 'string') {
+                this.zone(this._i);
+            }
+            return this;
+        },
+
+        hasAlignedHourOffset : function (input) {
+            if (!input) {
+                input = 0;
+            }
+            else {
+                input = moment(input).zone();
+            }
+
+            return (this.zone() - input) % 60 === 0;
+        },
+
+        daysInMonth : function () {
+            return daysInMonth(this.year(), this.month());
+        },
+
+        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));
+        },
+
+        quarter : function () {
+            return Math.ceil((this.month() + 1.0) / 3.0);
+        },
+
+        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));
+        },
+
+        isoWeekYear : function (input) {
+            var year = weekOfYear(this, 1, 4).year;
+            return input == null ? year : this.add("y", (input - year));
+        },
+
+        week : function (input) {
+            var week = this.lang().week(this);
+            return input == null ? week : this.add("d", (input - week) * 7);
+        },
+
+        isoWeek : function (input) {
+            var week = weekOfYear(this, 1, 4).week;
+            return input == null ? week : this.add("d", (input - week) * 7);
+        },
+
+        weekday : function (input) {
+            var weekday = (this.day() + 7 - this.lang()._week.dow) % 7;
+            return input == null ? weekday : this.add("d", input - weekday);
+        },
+
+        isoWeekday : function (input) {
+            // behaves the same as moment#day except
+            // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
+            // as a setter, sunday should belong to the previous week.
+            return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);
+        },
+
+        get : function (units) {
+            units = normalizeUnits(units);
+            return this[units]();
+        },
+
+        set : function (units, value) {
+            units = normalizeUnits(units);
+            if (typeof this[units] === 'function') {
+                this[units](value);
+            }
+            return this;
+        },
+
+        // If passed a language key, it will set the language for this
+        // instance.  Otherwise, it will return the language configuration
+        // variables for this instance.
+        lang : function (key) {
+            if (key === undefined) {
+                return this._lang;
+            } else {
+                this._lang = getLangDefinition(key);
+                return this;
+            }
+        }
+    });
+
+    // helper for adding shortcuts
+    function makeGetterAndSetter(name, key) {
+        moment.fn[name] = moment.fn[name + 's'] = function (input) {
+            var utc = this._isUTC ? 'UTC' : '';
+            if (input != null) {
+                this._d['set' + utc + key](input);
+                moment.updateOffset(this);
+                return this;
+            } else {
+                return this._d['get' + utc + key]();
+            }
+        };
+    }
+
+    // loop through and add shortcuts (Month, Date, Hours, Minutes, Seconds, Milliseconds)
+    for (i = 0; i < proxyGettersAndSetters.length; i ++) {
+        makeGetterAndSetter(proxyGettersAndSetters[i].toLowerCase().replace(/s$/, ''), proxyGettersAndSetters[i]);
+    }
+
+    // add shortcut for year (uses different syntax than the getter/setter 'year' == 'FullYear')
+    makeGetterAndSetter('year', 'FullYear');
+
+    // add plural methods
+    moment.fn.days = moment.fn.day;
+    moment.fn.months = moment.fn.month;
+    moment.fn.weeks = moment.fn.week;
+    moment.fn.isoWeeks = moment.fn.isoWeek;
+
+    // add aliased format methods
+    moment.fn.toJSON = moment.fn.toISOString;
+
+    /************************************
+        Duration Prototype
+    ************************************/
+
+
+    extend(moment.duration.fn = Duration.prototype, {
+
+        _bubble : function () {
+            var milliseconds = this._milliseconds,
+                days = this._days,
+                months = this._months,
+                data = this._data,
+                seconds, minutes, hours, years;
+
+            // The following code bubbles up values, see the tests for
+            // examples of what that means.
+            data.milliseconds = milliseconds % 1000;
+
+            seconds = absRound(milliseconds / 1000);
+            data.seconds = seconds % 60;
+
+            minutes = absRound(seconds / 60);
+            data.minutes = minutes % 60;
+
+            hours = absRound(minutes / 60);
+            data.hours = hours % 24;
+
+            days += absRound(hours / 24);
+            data.days = days % 30;
+
+            months += absRound(days / 30);
+            data.months = months % 12;
+
+            years = absRound(months / 12);
+            data.years = years;
+        },
+
+        weeks : function () {
+            return absRound(this.days() / 7);
+        },
+
+        valueOf : function () {
+            return this._milliseconds +
+              this._days * 864e5 +
+              (this._months % 12) * 2592e6 +
+              toInt(this._months / 12) * 31536e6;
+        },
+
+        humanize : function (withSuffix) {
+            var difference = +this,
+                output = relativeTime(difference, !withSuffix, this.lang());
+
+            if (withSuffix) {
+                output = this.lang().pastFuture(difference, output);
+            }
+
+            return this.lang().postformat(output);
+        },
+
+        add : function (input, val) {
+            // supports only 2.0-style add(1, 's') or add(moment)
+            var dur = moment.duration(input, val);
+
+            this._milliseconds += dur._milliseconds;
+            this._days += dur._days;
+            this._months += dur._months;
+
+            this._bubble();
+
+            return this;
+        },
+
+        subtract : function (input, val) {
+            var dur = moment.duration(input, val);
+
+            this._milliseconds -= dur._milliseconds;
+            this._days -= dur._days;
+            this._months -= dur._months;
+
+            this._bubble();
+
+            return this;
+        },
+
+        get : function (units) {
+            units = normalizeUnits(units);
+            return this[units.toLowerCase() + 's']();
+        },
+
+        as : function (units) {
+            units = normalizeUnits(units);
+            return this['as' + units.charAt(0).toUpperCase() + units.slice(1) + 's']();
+        },
+
+        lang : moment.fn.lang,
+
+        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()),
+                days = Math.abs(this.days()),
+                hours = Math.abs(this.hours()),
+                minutes = Math.abs(this.minutes()),
+                seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);
+
+            if (!this.asSeconds()) {
+                // this is the same as C#'s (Noda) and python (isodate)...
+                // but not other JS (goog.date)
+                return 'P0D';
+            }
+
+            return (this.asSeconds() < 0 ? '-' : '') +
+                'P' +
+                (years ? years + 'Y' : '') +
+                (months ? months + 'M' : '') +
+                (days ? days + 'D' : '') +
+                ((hours || minutes || seconds) ? 'T' : '') +
+                (hours ? hours + 'H' : '') +
+                (minutes ? minutes + 'M' : '') +
+                (seconds ? seconds + 'S' : '');
+        }
+    });
+
+    function makeDurationGetter(name) {
+        moment.duration.fn[name] = function () {
+            return this._data[name];
+        };
+    }
+
+    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.asMonths = function () {
+        return (+this - this.years() * 31536e6) / 2592e6 + this.years() * 12;
+    };
+
+
+    /************************************
+        Default Lang
+    ************************************/
+
+
+    // Set default language, other languages will inherit from English.
+    moment.lang('en', {
+        ordinal : function (number) {
+            var b = number % 10,
+                output = (toInt(number % 100 / 10) === 1) ? 'th' :
+                (b === 1) ? 'st' :
+                (b === 2) ? 'nd' :
+                (b === 3) ? 'rd' : 'th';
+            return number + output;
+        }
+    });
+
+    /* EMBED_LANGUAGES */
+
+    /************************************
+        Exposing Moment
+    ************************************/
+
+    function makeGlobal(deprecate) {
+        var warned = false, local_moment = moment;
+        /*global ender:false */
+        if (typeof ender !== 'undefined') {
+            return;
+        }
+        // here, `this` means `window` in the browser, or `global` on the server
+        // add `moment` as a global object via a string identifier,
+        // for Closure Compiler "advanced" mode
+        if (deprecate) {
+            global.moment = function () {
+                if (!warned && console && console.warn) {
+                    warned = true;
+                    console.warn(
+                            "Accessing Moment through the global scope is " +
+                            "deprecated, and will be removed in an upcoming " +
+                            "release.");
+                }
+                return local_moment.apply(null, arguments);
+            };
+            extend(global.moment, local_moment);
+        } else {
+            global['moment'] = moment;
+        }
+    }
+
+    // CommonJS module is defined
+    if (hasModule) {
+        module.exports = moment;
+        makeGlobal(true);
+    } else if (typeof define === "function" && define.amd) {
+        define("moment", function (require, exports, module) {
+            if (module.config && module.config() && module.config().noGlobal !== true) {
+                // If user provided noGlobal, he is aware of global
+                makeGlobal(module.config().noGlobal === undefined);
+            }
+
+            return moment;
+        });
+    } else {
+        makeGlobal();
+    }
+}).call(this);
diff --git a/resources/oojs-ui/i18n/km.json b/resources/oojs-ui/i18n/km.json
new file mode 100644 (file)
index 0000000..2013ee3
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "@metadata": {
+        "authors": [
+            "Sovichet"
+        ]
+    },
+    "ooui-dialog-action-close": "បិទ",
+    "ooui-outline-control-move-down": "រុញ​ទៅ​ក្រោម",
+    "ooui-outline-control-move-up": "រុញ​ទៅ​លើ",
+    "ooui-toolbar-more": "បន្ថែម"
+}
\ No newline at end of file
index a58f65d..63ecf98 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre (a290673bbd)
+ * OOjs UI v0.1.0-pre (424b40373e)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Wed Feb 12 2014 13:52:08 GMT-0800 (PST)
+ * Date: Fri Feb 14 2014 17:57:32 GMT-0800 (PST)
  */
 ( function () {
 
@@ -176,9 +176,10 @@ OO.ui.Element = function OoUiElement( config ) {
        // Properties
        this.$ = config.$ || OO.ui.Element.getJQuery( document );
        this.$element = this.$( this.$.context.createElement( this.getTagName() ) );
+       this.elementGroup = null;
 
        // Initialization
-       if ( Array.isArray( config.classes ) ) {
+       if ( $.isArray( config.classes ) ) {
                this.$element.addClass( config.classes.join( ' ' ) );
        }
        if ( config.$content ) {
@@ -559,6 +560,26 @@ OO.ui.Element.prototype.getClosestScrollableElementContainer = function () {
        return OO.ui.Element.getClosestScrollableContainer( this.$element[0] );
 };
 
+/**
+ * Get group element is in.
+ *
+ * @returns {OO.ui.GroupElement|null} Group element, null if none
+ */
+OO.ui.Element.prototype.getElementGroup = function () {
+       return this.elementGroup;
+};
+
+/**
+ * Set group element is in.
+ *
+ * @param {OO.ui.GroupElement|null} group Group element, null if none
+ * @chainable
+ */
+OO.ui.Element.prototype.setElementGroup = function ( group ) {
+       this.elementGroup = group;
+       return this;
+};
+
 /**
  * Scroll element into view
  *
@@ -1607,7 +1628,7 @@ OO.ui.Dialog.prototype.close = function ( data ) {
  * @class
  * @abstract
  * @extends OO.ui.Element
- * @mixin OO.EventEmitter
+ * @mixins OO.EventEmitter
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -1637,7 +1658,7 @@ OO.mixinClass( OO.ui.Layout, OO.EventEmitter );
  * @class
  * @abstract
  * @extends OO.ui.Element
- * @mixin OO.EventEmitter
+ * @mixins OO.EventEmitter
  *
  * @constructor
  * @param {Object} [config] Configuration options
@@ -1654,11 +1675,12 @@ OO.ui.Widget = function OoUiWidget( config ) {
        OO.EventEmitter.call( this );
 
        // Properties
-       this.disabled = config.disabled;
+       this.disabled = null;
+       this.wasDisabled = null;
 
        // Initialization
        this.$element.addClass( 'oo-ui-widget' );
-       this.setDisabled( this.disabled );
+       this.setDisabled( !!config.disabled );
 };
 
 /* Inheritance */
@@ -1667,6 +1689,13 @@ OO.inheritClass( OO.ui.Widget, OO.ui.Element );
 
 OO.mixinClass( OO.ui.Widget, OO.EventEmitter );
 
+/* Events */
+
+/**
+ * @event disable
+ * @param {boolean} disabled Widget is disabled
+ */
+
 /* Methods */
 
 /**
@@ -1679,22 +1708,36 @@ OO.ui.Widget.prototype.isDisabled = function () {
        return this.disabled;
 };
 
+/**
+ * Update the disabled state, in case of changes in parent widget.
+ *
+ * @method
+ * @chainable
+ */
+OO.ui.Widget.prototype.updateDisabled = function () {
+       this.setDisabled( this.disabled );
+       return this;
+};
+
 /**
  * Set the disabled state of the widget.
  *
  * This should probably change the widgets's appearance and prevent it from being used.
  *
  * @method
- * @param {boolean} disabled Disable button
+ * @param {boolean} disabled Disable widget
  * @chainable
  */
 OO.ui.Widget.prototype.setDisabled = function ( disabled ) {
+       var isDisabled;
+
        this.disabled = !!disabled;
-       if ( this.disabled ) {
-               this.$element.addClass( 'oo-ui-widget-disabled' );
-       } else {
-               this.$element.removeClass( 'oo-ui-widget-disabled' );
+       isDisabled = this.isDisabled();
+       if ( isDisabled !== this.wasDisabled ) {
+               this.$element.toggleClass( 'oo-ui-widget-disabled', isDisabled );
+               this.emit( 'disable', isDisabled );
        }
+       this.wasDisabled = isDisabled;
        return this;
 };
 /**
@@ -1781,8 +1824,12 @@ OO.ui.ButtonedElement.prototype.setActive = function ( value ) {
  *
  * @constructor
  * @param {jQuery} $clippable Nodes to clip, assigned to #$clippable
+ * @param {Object} [config] Configuration options
  */
-OO.ui.ClippableElement = function OoUiClippableElement( $clippable ) {
+OO.ui.ClippableElement = function OoUiClippableElement( $clippable, config ) {
+       // Configuration initialization
+       config = config || {};
+
        // Properties
        this.$clippable = $clippable;
        this.clipping = false;
@@ -1969,7 +2016,7 @@ OO.ui.FlaggableElement.prototype.setFlags = function ( flags ) {
        var i, len, flag,
                classPrefix = 'oo-ui-flaggableElement-';
 
-       if ( Array.isArray( flags ) ) {
+       if ( $.isArray( flags ) ) {
                for ( i = 0, len = flags.length; i < len; i++ ) {
                        flag = flags[i];
                        // Set
@@ -1978,7 +2025,7 @@ OO.ui.FlaggableElement.prototype.setFlags = function ( flags ) {
                }
        } else if ( OO.isPlainObject( flags ) ) {
                for ( flag in flags ) {
-                       if ( flags[flags] ) {
+                       if ( flags[flag] ) {
                                // Set
                                this.flags[flag] = true;
                                this.$element.addClass( classPrefix + flag );
@@ -2042,7 +2089,7 @@ OO.ui.GroupElement.prototype.addItems = function ( items, index ) {
                item = items[i];
 
                // Check if item exists then remove it first, effectively "moving" it
-               currentIndex = this.items.indexOf( item );
+               currentIndex = $.inArray( item, this.items );
                if ( currentIndex >= 0 ) {
                        this.removeItems( [ item ] );
                        // Adjust index to compensate for removal
@@ -2058,6 +2105,7 @@ OO.ui.GroupElement.prototype.addItems = function ( items, index ) {
                        }
                        item.connect( this, events );
                }
+               item.setElementGroup( this );
                $items = $items.add( item.$element );
        }
 
@@ -2092,11 +2140,12 @@ OO.ui.GroupElement.prototype.removeItems = function ( items ) {
        // Remove specific items
        for ( i = 0, len = items.length; i < len; i++ ) {
                item = items[i];
-               index = this.items.indexOf( item );
+               index = $.inArray( item, this.items );
                if ( index !== -1 ) {
                        if ( this.aggregate ) {
                                item.disconnect( this );
                        }
+                       item.setElementGroup( null );
                        this.items.splice( index, 1 );
                        item.$element.detach();
                        this.$items = this.$items.not( item.$element );
@@ -2118,10 +2167,12 @@ OO.ui.GroupElement.prototype.clearItems = function () {
        var i, len, item;
 
        // Remove all items
-       if ( this.aggregate ) {
-               for ( i = 0, len = this.items.length; i < len; i++ ) {
+       for ( i = 0, len = this.items.length; i < len; i++ ) {
+               item = this.items[i];
+               if ( this.aggregate ) {
                        item.disconnect( this );
                }
+               item.setElementGroup( null );
        }
        this.items = [];
        this.$items.detach();
@@ -2372,6 +2423,9 @@ OO.ui.LabeledElement.static.label = null;
 /**
  * Set the label.
  *
+ * An empty string will result in the label being hidden. A string containing only whitespace will
+ * be converted to a single &nbsp;
+ *
  * @method
  * @param {jQuery|string|Function|null} label Label nodes; text; a function that retuns nodes or
  *  text; or null for no label
@@ -2381,8 +2435,13 @@ OO.ui.LabeledElement.prototype.setLabel = function ( label ) {
        var empty = false;
 
        this.label = label = OO.ui.resolveMsg( label ) || null;
-       if ( typeof label === 'string' && label.trim() ) {
-               this.$label.text( label );
+       if ( typeof label === 'string' && label.length ) {
+               if ( label.match( /^\s*$/ ) ) {
+                       // Convert whitespace only string to a single non-breaking space
+                       this.$label.html( '&nbsp;' );
+               } else {
+                       this.$label.text( label );
+               }
        } else if ( label instanceof jQuery ) {
                this.$label.empty().append( label );
        } else {
@@ -2800,20 +2859,20 @@ OO.ui.Tool.prototype.destroy = function () {
  *
  * @constructor
  * @param {OO.Factory} toolFactory Factory for creating tools
- * @param {Object} [options] Configuration options
+ * @param {Object} [config] Configuration options
  * @cfg {boolean} [actions] Add an actions section opposite to the tools
  * @cfg {boolean} [shadow] Add a shadow below the toolbar
  */
-OO.ui.Toolbar = function OoUiToolbar( toolFactory, options ) {
+OO.ui.Toolbar = function OoUiToolbar( toolFactory, config ) {
        // Configuration initialization
-       options = options || {};
+       config = config || {};
 
        // Parent constructor
-       OO.ui.Element.call( this, options );
+       OO.ui.Element.call( this, config );
 
        // Mixin constructors
        OO.EventEmitter.call( this );
-       OO.ui.GroupElement.call( this, this.$( '<div>' ) );
+       OO.ui.GroupElement.call( this, this.$( '<div>' ), config );
 
        // Properties
        this.toolFactory = toolFactory;
@@ -2831,12 +2890,12 @@ OO.ui.Toolbar = function OoUiToolbar( toolFactory, options ) {
        // Initialization
        this.$group.addClass( 'oo-ui-toolbar-tools' );
        this.$bar.addClass( 'oo-ui-toolbar-bar' ).append( this.$group );
-       if ( options.actions ) {
+       if ( config.actions ) {
                this.$actions.addClass( 'oo-ui-toolbar-actions' );
                this.$bar.append( this.$actions );
        }
        this.$bar.append( '<div style="clear:both"></div>' );
-       if ( options.shadow ) {
+       if ( config.shadow ) {
                this.$bar.append( '<div class="oo-ui-toolbar-shadow"></div>' );
        }
        this.$element.addClass( 'oo-ui-toolbar' ).append( this.$bar );
@@ -3068,7 +3127,7 @@ OO.ui.ToolFactory.prototype.extract = function ( collection, used ) {
                                }
                        }
                }
-       } else if ( Array.isArray( collection ) ) {
+       } else if ( $.isArray( collection ) ) {
                for ( i = 0, len = collection.length; i < len; i++ ) {
                        item = collection[i];
                        // Allow plain strings as shorthand for named tools
@@ -3135,7 +3194,7 @@ OO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) {
        OO.ui.Widget.call( this, config );
 
        // Mixin constructors
-       OO.ui.GroupElement.call( this, this.$( '<div>' ) );
+       OO.ui.GroupElement.call( this, this.$( '<div>' ), config );
 
        // Properties
        this.toolbar = toolbar;
@@ -3396,13 +3455,18 @@ OO.ui.ToolGroup.prototype.destroy = function () {
 /**
  * Layout made of a fieldset and optional legend.
  *
+ * Just add OO.ui.FieldLayout items.
+ *
  * @class
  * @extends OO.ui.Layout
  * @mixins OO.ui.LabeledElement
+ * @mixins OO.ui.IconedElement
+ * @mixins OO.ui.GroupElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
  * @cfg {string} [icon] Symbolic icon name
+ * @cfg {OO.ui.FieldLayout[]} [items] Items to add
  */
 OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
        // Config initialization
@@ -3412,18 +3476,16 @@ OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
        OO.ui.Layout.call( this, config );
 
        // Mixin constructors
+       OO.ui.IconedElement.call( this, this.$( '<div>' ), config );
        OO.ui.LabeledElement.call( this, this.$( '<legend>' ), config );
+       OO.ui.GroupElement.call( this, this.$( '<div>' ), config );
 
        // Initialization
-       if ( config.icon ) {
-               this.$element.addClass( 'oo-ui-fieldsetLayout-decorated' );
-               this.$label.addClass( 'oo-ui-icon-' + config.icon );
-       }
-       this.$element.addClass( 'oo-ui-fieldsetLayout' );
-       if ( config.icon || config.label ) {
-               this.$element
-                       .addClass( 'oo-ui-fieldsetLayout-labeled' )
-                       .append( this.$label );
+       this.$element
+               .addClass( 'oo-ui-fieldsetLayout' )
+               .append( this.$icon, this.$label, this.$group );
+       if ( $.isArray( config.items ) ) {
+               this.addItems( config.items );
        }
 };
 
@@ -3431,11 +3493,119 @@ OO.ui.FieldsetLayout = function OoUiFieldsetLayout( config ) {
 
 OO.inheritClass( OO.ui.FieldsetLayout, OO.ui.Layout );
 
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.IconedElement );
 OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.LabeledElement );
+OO.mixinClass( OO.ui.FieldsetLayout, OO.ui.GroupElement );
 
 /* Static Properties */
 
 OO.ui.FieldsetLayout.static.tagName = 'fieldset';
+/**
+ * Layout made of a field and optional label.
+ *
+ * @class
+ * @extends OO.ui.Layout
+ * @mixins OO.ui.LabeledElement
+ *
+ * Available label alignment modes include:
+ *  - 'left': Label is before the field and aligned away from it, best for when the user will be
+ *    scanning for a specific label in a form with many fields
+ *  - 'right': Label is before the field and aligned toward it, best for forms the user is very
+ *    familiar with and will tab through field checking quickly to verify which field they are in
+ *  - 'top': Label is before the field and above it, best for when the use will need to fill out all
+ *    fields from top to bottom in a form with few fields
+ *  - 'inline': Label is after the field and aligned toward it, best for small boolean fields like
+ *    checkboxes or radio buttons
+ *
+ * @constructor
+ * @param {OO.ui.Widget} field Field widget
+ * @param {Object} [config] Configuration options
+ * @cfg {string} [align='left'] Alignment mode, either 'left', 'right', 'top' or 'inline'
+ */
+OO.ui.FieldLayout = function OoUiFieldLayout( field, config ) {
+       // Config initialization
+       config = $.extend( { 'align': 'left' }, config );
+
+       // Parent constructor
+       OO.ui.Layout.call( this, config );
+
+       // Mixin constructors
+       OO.ui.LabeledElement.call( this, this.$( '<label>' ), config );
+
+       // Properties
+       this.$field = this.$( '<div>' );
+       this.field = field;
+       this.align = null;
+
+       // Events
+       if ( this.field instanceof OO.ui.InputWidget ) {
+               this.$label.on( 'click', OO.ui.bind( this.onLabelClick, this ) );
+       }
+
+       // Initialization
+       this.$element.addClass( 'oo-ui-fieldLayout' );
+       this.$field
+               .addClass( 'oo-ui-fieldLayout-field' )
+               .append( this.field.$element );
+       this.setAlignment( config.align );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.FieldLayout, OO.ui.Layout );
+
+OO.mixinClass( OO.ui.FieldLayout, OO.ui.LabeledElement );
+
+/* Methods */
+
+/**
+ * Handles label mouse click events.
+ *
+ * @method
+ * @param {jQuery.Event} e Mouse click event
+ */
+OO.ui.FieldLayout.prototype.onLabelClick = function () {
+       this.field.simulateLabelClick();
+       return false;
+};
+
+/**
+ * Get the field.
+ *
+ * @returns {OO.ui.Widget} Field widget
+ */
+OO.ui.FieldLayout.prototype.getField = function () {
+       return this.field;
+};
+
+/**
+ * Set the field alignment mode.
+ *
+ * @param {string} value Alignment mode, either 'left', 'right', 'top' or 'inline'
+ * @chainable
+ */
+OO.ui.FieldLayout.prototype.setAlignment = function ( value ) {
+       if ( value !== this.align ) {
+               // Default to 'left'
+               if ( [ 'left', 'right', 'top', 'inline' ].indexOf( value ) === -1 ) {
+                       value = 'left';
+               }
+               // Reorder elements
+               if ( value === 'inline' ) {
+                       this.$element.append( this.$field, this.$label );
+               } else {
+                       this.$element.append( this.$label, this.$field );
+               }
+               // Set classes
+               if ( this.align ) {
+                       this.$element.removeClass( 'oo-ui-fieldLayout-align-' + this.align );
+               }
+               this.align = value;
+               this.$element.addClass( 'oo-ui-fieldLayout-align-' + this.align );
+       }
+
+       return this;
+};
 /**
  * Layout made of proportionally sized columns and rows.
  *
@@ -3821,7 +3991,7 @@ OO.ui.BookletLayout.prototype.getPageName = function () {
  * @chainable
  */
 OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
-       var i, len, name, page,
+       var i, len, name, page, item,
                items = [],
                remove = [];
 
@@ -3834,7 +4004,9 @@ OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) {
                }
                this.pages[page.getName()] = page;
                if ( this.outlined ) {
-                       items.push( new OO.ui.BookletOutlineItemWidget( name, page, { '$': this.$ } ) );
+                       item = new OO.ui.OutlineItemWidget( name, page, { '$': this.$ } );
+                       page.setOutlineItem( item );
+                       items.push( item );
                }
        }
        if ( remove.length ) {
@@ -3868,6 +4040,7 @@ OO.ui.BookletLayout.prototype.removePages = function ( pages ) {
                delete this.pages[name];
                if ( this.outlined ) {
                        items.push( this.outlineWidget.getItemFromData( name ) );
+                       page.setOutlineItem( null );
                }
        }
        if ( this.outlined && items.length ) {
@@ -3888,12 +4061,16 @@ OO.ui.BookletLayout.prototype.removePages = function ( pages ) {
  * @chainable
  */
 OO.ui.BookletLayout.prototype.clearPages = function () {
-       var pages = this.stackLayout.getItems();
+       var i, len,
+               pages = this.stackLayout.getItems();
 
        this.pages = {};
        this.currentPageName = null;
        if ( this.outlined ) {
                this.outlineWidget.clearItems();
+               for ( i = 0, len = pages.length; i < len; i++ ) {
+                       pages[i].setOutlineItem( null );
+               }
        }
        this.stackLayout.clearItems();
 
@@ -3985,12 +4162,7 @@ OO.inheritClass( OO.ui.PanelLayout, OO.ui.Layout );
  * @constructor
  * @param {string} name Unique symbolic name of page
  * @param {Object} [config] Configuration options
- * @param {string} [icon=''] Symbolic name of icon to display in outline
- * @param {string} [indicator=''] Symbolic name of indicator to display in outline
- * @param {string} [indicatorTitle=''] Description of indicator meaning to display in outline
- * @param {string} [label=''] Label to display in outline
- * @param {number} [level=0] Indentation level of item in outline
- * @param {boolean} [movable=false] Page should be movable using outline controls
+ * @param {string} [outlineItem] Outline item widget
  */
 OO.ui.PageLayout = function OoUiPageLayout( name, config ) {
        // Configuration initialization
@@ -4001,12 +4173,7 @@ OO.ui.PageLayout = function OoUiPageLayout( name, config ) {
 
        // Properties
        this.name = name;
-       this.icon = config.icon || '';
-       this.indicator = config.indicator || '';
-       this.indicatorTitle = OO.ui.resolveMsg( config.indicatorTitle ) || '';
-       this.label = OO.ui.resolveMsg( config.label ) || '';
-       this.level = config.level || 0;
-       this.movable = !!config.movable;
+       this.outlineItem = config.outlineItem || null;
 
        // Initialization
        this.$element.addClass( 'oo-ui-pageLayout' );
@@ -4028,57 +4195,23 @@ OO.ui.PageLayout.prototype.getName = function () {
 };
 
 /**
- * Get page icon.
- *
- * @returns {string} Symbolic name of icon
- */
-OO.ui.PageLayout.prototype.getIcon = function () {
-       return this.icon;
-};
-
-/**
- * Get page indicator.
- *
- * @returns {string} Symbolic name of indicator
- */
-OO.ui.PageLayout.prototype.getIndicator = function () {
-       return this.indicator;
-};
-
-/**
- * Get page indicator label.
+ * Get outline item.
  *
- * @returns {string} Description of indicator meaning
+ * @returns {OO.ui.OutlineItemWidget|null} Outline item widget
  */
-OO.ui.PageLayout.prototype.getIndicatorTitle = function () {
-       return this.indicatorTitle;
-};
-
-/**
- * Get page label.
- *
- * @returns {string} Label text
- */
-OO.ui.PageLayout.prototype.getLabel = function () {
-       return this.label;
+OO.ui.PageLayout.prototype.getOutlineItem = function () {
+       return this.outlineItem;
 };
 
 /**
- * Get outline item indentation level.
+ * Get outline item.
  *
- * @returns {number} Indentation level
- */
-OO.ui.PageLayout.prototype.getLevel = function () {
-       return this.level;
-};
-
-/**
- * Check if page is movable using outline controls.
- *
- * @returns {boolean} Page is movable
+ * @param {OO.ui.OutlineItemWidget|null} outlineItem Outline item widget, null to clear
+ * @chainable
  */
-OO.ui.PageLayout.prototype.isMovable = function () {
-       return this.movable;
+OO.ui.PageLayout.prototype.setOutlineItem = function ( outlineItem ) {
+       this.outlineItem = outlineItem;
+       return this;
 };
 /**
  * Layout containing a series of mutually exclusive pages.
@@ -4091,6 +4224,7 @@ OO.ui.PageLayout.prototype.isMovable = function () {
  * @param {Object} [config] Configuration options
  * @cfg {boolean} [continuous=false] Show all pages, one after another
  * @cfg {string} [icon=''] Symbolic icon name
+ * @cfg {OO.ui.Layout[]} [items] Layouts to add
  */
 OO.ui.StackLayout = function OoUiStackLayout( config ) {
        // Config initialization
@@ -4111,6 +4245,9 @@ OO.ui.StackLayout = function OoUiStackLayout( config ) {
        if ( this.continuous ) {
                this.$element.addClass( 'oo-ui-stackLayout-continuous' );
        }
+       if ( $.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
 };
 
 /* Inheritance */
@@ -4159,7 +4296,7 @@ OO.ui.StackLayout.prototype.addItems = function ( items, index ) {
  */
 OO.ui.StackLayout.prototype.removeItems = function ( items ) {
        OO.ui.GroupElement.prototype.removeItems.call( this, items );
-       if ( items.indexOf( this.currentItem ) !== -1 ) {
+       if ( $.inArray( this.currentItem, items  ) !== -1 ) {
                this.currentItem = null;
                if ( !this.currentItem && this.items.length ) {
                        this.setItem( this.items[0] );
@@ -4197,7 +4334,7 @@ OO.ui.StackLayout.prototype.setItem = function ( item ) {
        if ( !this.continuous ) {
                this.$items.css( 'display', '' );
        }
-       if ( this.items.indexOf( item ) !== -1 ) {
+       if ( $.inArray( item, this.items ) !== -1 ) {
                if ( !this.continuous ) {
                        item.$element.css( 'display', 'block' );
                }
@@ -4265,7 +4402,7 @@ OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
        OO.ui.IndicatedElement.call( this, this.$( '<span>' ), config );
        OO.ui.LabeledElement.call( this, this.$( '<span>' ), config );
        OO.ui.TitledElement.call( this, this.$element, config );
-       OO.ui.ClippableElement.call( this, this.$group );
+       OO.ui.ClippableElement.call( this, this.$group, config );
 
        // Properties
        this.active = false;
@@ -4516,15 +4653,107 @@ OO.ui.PopupTool.prototype.onSelect = function () {
 OO.ui.PopupTool.prototype.onUpdateState = function () {
        this.setActive( false );
 };
+/**
+ * Group widget.
+ *
+ * Use together with OO.ui.ItemWidget to make disabled state inheritable.
+ *
+ * @class
+ * @abstract
+ * @extends OO.ui.GroupElement
+ *
+ * @constructor
+ * @param {jQuery} $group Container node, assigned to #$group
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.GroupWidget = function OoUiGroupWidget( $element, config ) {
+       // Parent constructor
+       OO.ui.GroupElement.call( this, $element, config );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.GroupWidget, OO.ui.GroupElement );
+
+/* Methods */
+
+/**
+ * Set the disabled state of the widget.
+ *
+ * This will also update the disabled state of child widgets.
+ *
+ * @method
+ * @param {boolean} disabled Disable widget
+ * @chainable
+ */
+OO.ui.GroupWidget.prototype.setDisabled = function ( disabled ) {
+       var i, len;
+
+       // Parent method
+       OO.ui.Widget.prototype.setDisabled.call( this, disabled );
+
+       // During construction, #setDisabled is called before the OO.ui.GroupElement constructor
+       if ( this.items ) {
+               for ( i = 0, len = this.items.length; i < len; i++ ) {
+                       this.items[i].updateDisabled();
+               }
+       }
+
+       return this;
+};
+/**
+ * Item widget.
+ *
+ * Use together with OO.ui.GroupWidget to make disabled state inheritable.
+ *
+ * @class
+ * @abstract
+ *
+ * @constructor
+ */
+OO.ui.ItemWidget = function OoUiItemWidget() {
+       //
+};
+
+/* Methods */
+
+/**
+ * Check if widget is disabled.
+ *
+ * Checks parent if present, making disabled state inheritable.
+ *
+ * @returns {boolean} Widget is disabled
+ */
+OO.ui.ItemWidget.prototype.isDisabled = function () {
+       return this.disabled ||
+               ( this.elementGroup instanceof OO.ui.Widget && this.elementGroup.isDisabled() );
+};
+
+/**
+ * Set group element is in.
+ *
+ * @param {OO.ui.GroupElement|null} group Group element, null if none
+ * @chainable
+ */
+OO.ui.ItemWidget.prototype.setElementGroup = function ( group ) {
+       // Parent method
+       OO.ui.Element.prototype.setElementGroup.call( this, group );
+
+       // Initialize item disabled states
+       this.updateDisabled();
+
+       return this;
+};
 /**
  * Container for multiple related buttons.
  *
  * @class
  * @extends OO.ui.Widget
- * @mixin OO.ui.GroupElement
+ * @mixins OO.ui.GroupElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.ButtonWidget} [items] Buttons to add
  */
 OO.ui.ButtonGroupWidget = function OoUiButtonGroupWidget( config ) {
        // Parent constructor
@@ -4535,6 +4764,9 @@ OO.ui.ButtonGroupWidget = function OoUiButtonGroupWidget( config ) {
 
        // Initialization
        this.$element.addClass( 'oo-ui-buttonGroupWidget' );
+       if ( $.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
 };
 
 /* Inheritance */
@@ -4791,6 +5023,21 @@ OO.ui.InputWidget.prototype.sanitizeValue = function ( value ) {
        }
 };
 
+/**
+ * Simulate the behavior of clicking on a label bound to this input.
+ *
+ * @method
+ */
+OO.ui.InputWidget.prototype.simulateLabelClick = function () {
+       if ( !this.isDisabled() ) {
+               if ( this.$input.is( ':checkbox,:radio' ) ) {
+                       this.$input.click();
+               } else if ( this.$input.is( ':input' ) ) {
+                       this.$input.focus();
+               }
+       }
+};
+
 /**
  * Check if the widget is read-only.
  *
@@ -4825,7 +5072,8 @@ OO.ui.InputWidget.prototype.setDisabled = function ( state ) {
                this.$input.prop( 'disabled', this.disabled );
        }
        return this;
-};/**
+};
+/**
  * Creates an OO.ui.CheckboxInputWidget object.
  *
  * @class
@@ -4892,41 +5140,7 @@ OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
        }
 };
 /**
- * Creates an OO.ui.CheckboxWidget object.
- *
- * @class
- * @extends OO.ui.CheckboxInputWidget
- * @mixins OO.ui.LabeledElement
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {string} [label=''] Label
- */
-OO.ui.CheckboxWidget = function OoUiCheckboxWidget( config ) {
-       // Configuration initialization
-       config = config || {};
-
-       // Parent constructor
-       OO.ui.CheckboxInputWidget.call( this, config );
-
-       // Mixin constructors
-       OO.ui.LabeledElement.call( this, this.$( '<span>' ) , config );
-
-       // Initialization
-       this.$element
-               .addClass( 'oo-ui-checkboxWidget' )
-               .append( this.$( '<label>' ).append( this.$input, this.$label ) );
-};
-
-/* Inheritance */
-
-OO.inheritClass( OO.ui.CheckboxWidget, OO.ui.CheckboxInputWidget );
-
-OO.mixinClass( OO.ui.CheckboxWidget, OO.ui.LabeledElement );
-/**
- * Creates an OO.ui.InputLabelWidget object.
- *
- * CSS classes will be added to the button for each flag, each prefixed with 'oo-ui-InputLabelWidget-'
+ * Creates an OO.ui.LabelWidget object.
  *
  * @class
  * @extends OO.ui.Widget
@@ -4934,11 +5148,10 @@ OO.mixinClass( OO.ui.CheckboxWidget, OO.ui.LabeledElement );
  *
  * @constructor
  * @param {Object} [config] Configuration options
- * @cfg {OO.ui.InputWidget|null} [input] Related input widget
  */
-OO.ui.InputLabelWidget = function OoUiInputLabelWidget( config ) {
+OO.ui.LabelWidget = function OoUiLabelWidget( config ) {
        // Config intialization
-       config = $.extend( { 'input': null }, config );
+       config = config || {};
 
        // Parent constructor
        OO.ui.Widget.call( this, config );
@@ -4950,34 +5163,34 @@ OO.ui.InputLabelWidget = function OoUiInputLabelWidget( config ) {
        this.input = config.input;
 
        // Events
-       this.$element.on( 'click', OO.ui.bind( this.onClick, this ) );
+       if ( this.input instanceof OO.ui.InputWidget ) {
+               this.$element.on( 'click', OO.ui.bind( this.onClick, this ) );
+       }
 
        // Initialization
-       this.$element.addClass( 'oo-ui-inputLabelWidget' );
+       this.$element.addClass( 'oo-ui-labelWidget' );
 };
 
 /* Inheritance */
 
-OO.inheritClass( OO.ui.InputLabelWidget, OO.ui.Widget );
+OO.inheritClass( OO.ui.LabelWidget, OO.ui.Widget );
 
-OO.mixinClass( OO.ui.InputLabelWidget, OO.ui.LabeledElement );
+OO.mixinClass( OO.ui.LabelWidget, OO.ui.LabeledElement );
 
 /* Static Properties */
 
-OO.ui.InputLabelWidget.static.tagName = 'label';
+OO.ui.LabelWidget.static.tagName = 'label';
 
 /* Methods */
 
 /**
- * Handles mouse click events.
+ * Handles label mouse click events.
  *
  * @method
  * @param {jQuery.Event} e Mouse click event
  */
-OO.ui.InputLabelWidget.prototype.onClick = function () {
-       if ( !this.disabled && this.input ) {
-               this.input.$input.focus();
-       }
+OO.ui.LabelWidget.prototype.onClick = function () {
+       this.input.simulateLabelClick();
        return false;
 };
 /**
@@ -5224,6 +5437,7 @@ OO.ui.LookupInputWidget.prototype.getLookupMenuItemsFromData = function () {
  * @mixins OO.ui.IconedElement
  * @mixins OO.ui.LabeledElement
  * @mixins OO.ui.IndicatedElement
+ * @mixins OO.ui.FlaggableElement
  *
  * @constructor
  * @param {Mixed} data Option data
@@ -5240,9 +5454,11 @@ OO.ui.OptionWidget = function OoUiOptionWidget( data, config ) {
        OO.ui.Widget.call( this, config );
 
        // Mixin constructors
+       OO.ui.ItemWidget.call( this );
        OO.ui.IconedElement.call( this, this.$( '<span>' ), config );
        OO.ui.LabeledElement.call( this, this.$( '<span>' ), config );
        OO.ui.IndicatedElement.call( this, this.$( '<span>' ), config );
+       OO.ui.FlaggableElement.call( this, config );
 
        // Properties
        this.data = data;
@@ -5268,9 +5484,11 @@ OO.ui.OptionWidget = function OoUiOptionWidget( data, config ) {
 
 OO.inheritClass( OO.ui.OptionWidget, OO.ui.Widget );
 
+OO.mixinClass( OO.ui.OptionWidget, OO.ui.ItemWidget );
 OO.mixinClass( OO.ui.OptionWidget, OO.ui.IconedElement );
 OO.mixinClass( OO.ui.OptionWidget, OO.ui.LabeledElement );
 OO.mixinClass( OO.ui.OptionWidget, OO.ui.IndicatedElement );
+OO.mixinClass( OO.ui.OptionWidget, OO.ui.FlaggableElement );
 
 /* Static Properties */
 
@@ -5400,10 +5618,11 @@ OO.ui.OptionWidget.prototype.getData = function () {
  * @class
  * @abstract
  * @extends OO.ui.Widget
- * @mixin OO.ui.GroupElement
+ * @mixins OO.ui.GroupElement
  *
  * @constructor
  * @param {Object} [config] Configuration options
+ * @cfg {OO.ui.OptionWidget[]} [items] Options to add
  */
 OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
        // Config intialization
@@ -5413,7 +5632,7 @@ OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
        OO.ui.Widget.call( this, config );
 
        // Mixin constructors
-       OO.ui.GroupElement.call( this, this.$element, config );
+       OO.ui.GroupWidget.call( this, this.$element, config );
 
        // Properties
        this.pressed = false;
@@ -5431,14 +5650,20 @@ OO.ui.SelectWidget = function OoUiSelectWidget( config ) {
 
        // Initialization
        this.$element.addClass( 'oo-ui-selectWidget' );
+       if ( $.isArray( config.items ) ) {
+               this.addItems( config.items );
+       }
 };
 
 /* Inheritance */
 
 OO.inheritClass( OO.ui.SelectWidget, OO.ui.Widget );
 
+// Need to mixin base class as well
 OO.mixinClass( OO.ui.SelectWidget, OO.ui.GroupElement );
 
+OO.mixinClass( OO.ui.SelectWidget, OO.ui.GroupWidget );
+
 /* Events */
 
 /**
@@ -5706,7 +5931,7 @@ OO.ui.SelectWidget.prototype.getRelativeSelectableItem = function ( item, direct
        var inc = direction > 0 ? 1 : -1,
                len = this.items.length,
                index = item instanceof OO.ui.OptionWidget ?
-                       this.items.indexOf( item ) : ( inc > 0 ? -1 : 0 ),
+                       $.inArray( item, this.items ) : ( inc > 0 ? -1 : 0 ),
                stopAt = Math.max( Math.min( index, len - 1 ), 0 ),
                i = inc > 0 ?
                        // Default to 0 instead of -1, if nothing is selected let's start at the beginning
@@ -5879,7 +6104,7 @@ OO.ui.MenuWidget = function OoUiMenuWidget( config ) {
        OO.ui.SelectWidget.call( this, config );
 
        // Mixin constructors
-       OO.ui.ClippableElement.call( this, this.$group );
+       OO.ui.ClippableElement.call( this, this.$group, config );
 
        // Properties
        this.newItems = [];
@@ -6323,7 +6548,7 @@ OO.ui.OutlineItemWidget.static.levels = 3;
 /**
  * Check if item is movable.
  *
- * Moveablilty is used by outline controls.
+ * Movablilty is used by outline controls.
  *
  * @returns {boolean} Item is movable
  */
@@ -6340,6 +6565,19 @@ OO.ui.OutlineItemWidget.prototype.getLevel = function () {
        return this.level;
 };
 
+/**
+ * Set movability.
+ *
+ * Movablilty is used by outline controls.
+ *
+ * @param {boolean} movable Item is movable
+ * @chainable
+ */
+OO.ui.OutlineItemWidget.prototype.setMovable = function ( movable ) {
+       this.movable = !!movable;
+       return this;
+};
+
 /**
  * Set indentation level.
  *
@@ -6363,37 +6601,6 @@ OO.ui.OutlineItemWidget.prototype.setLevel = function ( level ) {
 
        return this;
 };
-/**
- * Creates an OO.ui.BookletOutlineItemWidget object.
- *
- * @class
- * @extends OO.ui.OutlineItemWidget
- *
- * @constructor
- * @param {Mixed} data Item data
- * @param {Object} [config] Configuration options
- */
-OO.ui.BookletOutlineItemWidget = function OoUiBookletOutlineItemWidget( data, page, config ) {
-       // Configuration intialization
-       config = $.extend( {
-               'label': page.getLabel() || data,
-               'level': page.getLevel(),
-               'icon': page.getIcon(),
-               'indicator': page.getIndicator(),
-               'indicatorTitle': page.getIndicatorTitle(),
-               'movable': page.isMovable()
-       }, config );
-
-       // Parent constructor
-       OO.ui.OutlineItemWidget.call( this, data, config );
-
-       // Initialization
-       this.$element.addClass( 'oo-ui-bookletOutlineItemWidget' );
-};
-
-/* Inheritance */
-
-OO.inheritClass( OO.ui.BookletOutlineItemWidget, OO.ui.OutlineItemWidget );
 /**
  * Create an OO.ui.ButtonSelect object.
  *
index 185bcf0..917707e 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs UI v0.1.0-pre-svg (a290673bbd)
+ * OOjs UI v0.1.0-pre-svg (424b40373e)
  * https://www.mediawiki.org/wiki/OOjs_UI
  *
  * Copyright 2011–2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Wed Feb 12 2014 13:52:08 GMT-0800 (PST)
+ * Date: Fri Feb 14 2014 17:57:32 GMT-0800 (PST)
  */
 /*csslint vendor-prefix:false */
 
@@ -236,6 +236,9 @@ a.oo-ui-buttonedElement-button {
 .oo-ui-buttonedElement .oo-ui-buttonedElement-button > .oo-ui-indicatedElement-indicator {
        margin-right: -0.75em;
 }
+.oo-ui-buttonedElement.oo-ui-widget-disabled .oo-ui-buttonedElement-button {
+       cursor: default;
+}
 
 .oo-ui-buttonedElement-frameless {
        display: inline-block;
@@ -281,7 +284,6 @@ a.oo-ui-buttonedElement-button {
        border-radius: 0.3em;
        vertical-align: top;
        text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5);
-       box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
        text-align: center;
 
        /* Animation */
@@ -498,6 +500,7 @@ a.oo-ui-buttonedElement-button {
 /* OO.ui.FieldsetLayout */
 
 .oo-ui-fieldsetLayout {
+       position: relative;
        border: none;
        margin: 0;
        padding: 0;
@@ -514,14 +517,80 @@ a.oo-ui-buttonedElement-button {
 .oo-ui-fieldsetLayout > legend.oo-ui-labeledElement-label {
        font-size: 1.5em;
        margin-bottom: 0.5em;
+       padding-left: 0;
 }
 
-.oo-ui-fieldsetLayout-decorated > legend.oo-ui-labeledElement-label {
+.oo-ui-fieldsetLayout.oo-ui-iconedElement > legend.oo-ui-labeledElement-label {
        padding-left: 1.75em;
-       background-position: left center;
+}
+
+.oo-ui-fieldsetLayout.oo-ui-iconedElement > .oo-ui-iconedElement-icon {
+       display: block;
+       position: absolute;
+       left: 0;
+       top: 0.5em;
+       width: 2em;
+       height: 2em;
+       background-position: center center;
        background-repeat: no-repeat;
 }
 
+/* OO.ui.FieldLayout */
+
+.oo-ui-fieldLayout {
+       margin-bottom: 1em;
+}
+
+.oo-ui-fieldLayout:last-child {
+       margin-bottom: 0;
+}
+
+.oo-ui-fieldLayout:before,
+.oo-ui-fieldLayout:after {
+    content: " ";
+    display: table;
+}
+
+.oo-ui-fieldLayout:after {
+    clear: both;
+}
+
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-labeledElement-label,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labeledElement-label {
+       display: block;
+       float: left;
+       width: 35%;
+       padding-top: 0.5em;
+       margin-right: 5%;
+}
+
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-left > .oo-ui-fieldLayout-field,
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-fieldLayout-field {
+       display: block;
+       float: left;
+       width: 60%;
+}
+
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-right > .oo-ui-labeledElement-label {
+       text-align: right;
+}
+
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-labeledElement-label {
+       display: inline-block;
+       vertical-align: middle;
+       padding: 0.75em 0.5em 0.5em 0.5em;
+}
+
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-inline > .oo-ui-fieldLayout-field {
+       display: inline-block;
+       vertical-align: middle;
+       padding: 0.5em 0;
+}
+
+.oo-ui-fieldLayout.oo-ui-fieldLayout-align-top > .oo-ui-labeledElement-label {
+       padding: 0.5em 0;
+}
+
 /* OO.ui.BookletLayout */
 
 .oo-ui-bookletLayout-stackLayout .oo-ui-panelLayout {
@@ -994,15 +1063,14 @@ a.oo-ui-buttonedElement-button {
 
 .oo-ui-buttonGroupWidget {
        display: inline-block;
+       white-space: nowrap;
        border-radius: 0.3em;
-       box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
 }
 
 .oo-ui-buttonGroupWidget .oo-ui-buttonedElement-framed .oo-ui-buttonedElement-button {
        border-radius: 0;
        margin-bottom: -1px;
        margin-left: -1px;
-       box-shadow: none;
 }
 
 .oo-ui-buttonGroupWidget .oo-ui-buttonedElement-framed:first-child .oo-ui-buttonedElement-button {
@@ -1112,6 +1180,22 @@ a.oo-ui-buttonedElement-button {
        left: 4em;
 }
 
+.oo-ui-outlineItemWidget.oo-ui-flaggableElement-important {
+       font-weight: bold;
+}
+
+.oo-ui-outlineItemWidget.oo-ui-flaggableElement-placeholder {
+       font-style: italic;
+}
+
+.oo-ui-outlineItemWidget.oo-ui-flaggableElement-empty .oo-ui-iconedElement-icon,
+.oo-ui-outlineItemWidget.oo-ui-flaggableElement-empty .oo-ui-indicatedElement-indicator {
+       opacity: 0.5;
+}
+.oo-ui-outlineItemWidget.oo-ui-flaggableElement-empty .oo-ui-labeledElement-label {
+       color: #698AA0;
+}
+
 /* OO.ui.OutlineControlsWidget */
 
 .oo-ui-outlineControlsWidget {
@@ -1150,9 +1234,9 @@ a.oo-ui-buttonedElement-button {
        cursor: default;
 }
 
-/* OO.ui.InputLabelWidget */
+/* OO.ui.LabelWidget */
 
-.oo-ui-inputLabelWidget {
+.oo-ui-labelWidget {
        padding: 0.5em 0;
 }
 
@@ -1175,7 +1259,7 @@ a.oo-ui-buttonedElement-button {
        display: inline-block;
        font-size: 1em;
        font-family: sans-serif;
-       background-color: #f7f7f7;
+       background-color: #fff;
        border: solid 1px #ccc;
        box-shadow: 0 0 0 white, inset 0 0.1em 0.2em #ddd;
        padding: 0.5em;
@@ -1187,10 +1271,10 @@ a.oo-ui-buttonedElement-button {
        resize: none;
 
        /* Animation */
-       -webkit-transition: border-color 200ms, box-shadow 200ms, background-color 200ms;
-       -moz-transition: border-color 200ms, box-shadow 200ms, background-color 200ms;
-       -o-transition: border-color 200ms, box-shadow 200ms, background-color 200ms;
-       transition: border-color 200ms, box-shadow 200ms, background-color 200ms;
+       -webkit-transition: border-color 200ms, box-shadow 200ms;
+       -moz-transition: border-color 200ms, box-shadow 200ms;
+       -o-transition: border-color 200ms, box-shadow 200ms;
+       transition: border-color 200ms, box-shadow 200ms;
 }
 
 .oo-ui-textInputWidget-pending input,
@@ -1203,7 +1287,6 @@ a.oo-ui-buttonedElement-button {
        outline: none;
        border-color: #a7dcff;
        box-shadow: 0 0 0.3em #a7dcff, 0 0 0 white;
-       background-color: #fff;
 }
 
 .oo-ui-textInputWidget input[readonly],
@@ -1217,6 +1300,7 @@ a.oo-ui-buttonedElement-button {
 .oo-ui-widget-disabled.oo-ui-textInputWidget textarea,
 .oo-ui-widget-disabled.oo-ui-textInputWidget textarea:focus {
        color: #ccc;
+       border-color: #ddd;
        text-shadow: 0 1px 1px #fff;
 }
 
@@ -1235,21 +1319,6 @@ a.oo-ui-buttonedElement-button {
        background-repeat: no-repeat;
 }
 
-/* OO.ui.CheckboxWidget */
-.oo-ui-checkboxWidget .oo-ui-labeledElement-label {
-       display: inline-block;
-       vertical-align: middle;
-       padding-left: 0.5em;
-}
-
-.oo-ui-checkboxWidget input {
-       vertical-align: middle;
-}
-
-.oo-ui-checkboxWidget.oo-ui-widget-disabled .oo-ui-labeledElement-label {
-       opacity: 0.5;
-}
-
 /* OO.ui.MenuWidget */
 
 .oo-ui-menuWidget {
@@ -1303,14 +1372,13 @@ a.oo-ui-buttonedElement-button {
 
 .oo-ui-buttonSelectWidget {
        display: inline-block;
+       white-space: nowrap;
        border-radius: 0.3em;
-       box-shadow: 0 0.1em 0.25em rgba(0, 0, 0, 0.1);
 }
 
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget .oo-ui-buttonedElement-button {
        border-radius: 0;
        margin-left: -1px;
-       box-shadow: none;
 }
 
 .oo-ui-buttonSelectWidget .oo-ui-buttonOptionWidget:first-child .oo-ui-buttonedElement-button {
@@ -1479,6 +1547,7 @@ a.oo-ui-buttonedElement-button {
 
 .oo-ui-toggleSwitchWidget.oo-ui-widget-disabled {
        opacity: 0.5;
+       cursor: default;
 }
 
 .oo-ui-toggleSwitchWidget-grip {
@@ -1540,7 +1609,6 @@ a.oo-ui-buttonedElement-button {
        left: 0;
        border-radius: 1em;
        box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
-       cursor: pointer;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -moz-user-select: none;
@@ -1614,139 +1682,6 @@ a.oo-ui-buttonedElement-button {
 }
 /* Icons */
 
-.oo-ui-icon-add-item {
-       /* @embed */
-       background-image: url(images/icons/add-item.png);
-}
-
-.oo-ui-icon-advanced {
-       /* @embed */
-       background-image: url(images/icons/advanced.png);
-}
-
-.oo-ui-icon-alert {
-       /* @embed */
-       background-image: url(images/icons/alert.png);
-}
-
-.oo-ui-icon-check {
-       /* @embed */
-       background-image: url(images/icons/check.png);
-}
-
-.oo-ui-icon-clear {
-       /* @embed */
-       background-image: url(images/icons/clear.png);
-}
-
-.oo-ui-icon-close {
-       /* @embed */
-       background-image: url(images/icons/close.png);
-}
-
-.oo-ui-icon-code {
-       /* @embed */
-       background-image: url(images/icons/code.png);
-}
-
-.oo-ui-icon-collapse {
-       /* @embed */
-       background-image: url(images/icons/collapse.png);
-}
-
-.oo-ui-icon-comment {
-       /* @embed */
-       background-image: url(images/icons/comment.png);
-}
-
-.oo-ui-icon-expand {
-       /* @embed */
-       background-image: url(images/icons/expand.png);
-}
-
-.oo-ui-icon-help {
-       /* @embed */
-       background-image: url(images/icons/help.png);
-}
-
-.oo-ui-icon-link {
-       /* @embed */
-       background-image: url(images/icons/link.png);
-}
-
-.oo-ui-icon-menu {
-       /* @embed */
-       background-image: url(images/icons/menu.png);
-}
-
-.oo-ui-icon-next {
-       /* @embed */
-       background-image: url(images/icons/move-ltr.png);
-}
-
-.oo-ui-icon-picture {
-       /* @embed */
-       background-image: url(images/icons/picture.png);
-}
-
-.oo-ui-icon-previous {
-       /* @embed */
-       background-image: url(images/icons/move-rtl.png);
-}
-
-.oo-ui-icon-redo {
-       /* @embed */
-       background-image: url(images/icons/arched-arrow-ltr.png);
-}
-
-.oo-ui-icon-remove {
-       /* @embed */
-       background-image: url(images/icons/remove.png);
-}
-
-.oo-ui-icon-search {
-       /* @embed */
-       background-image: url(images/icons/search.png);
-}
-
-.oo-ui-icon-settings {
-       /* @embed */
-       background-image: url(images/icons/settings.png);
-}
-
-.oo-ui-icon-tag {
-       /* @embed */
-       background-image: url(images/icons/tag.png);
-}
-
-.oo-ui-icon-undo {
-       /* @embed */
-       background-image: url(images/icons/arched-arrow-rtl.png);
-}
-
-.oo-ui-icon-window {
-       /* @embed */
-       background-image: url(images/icons/window.png);
-}
-
-/* Indicators */
-
-.oo-ui-indicator-down {
-       /* @embed */
-       background-image: url(images/indicators/down.png);
-}
-
-.oo-ui-indicator-required {
-       /* @embed */
-       background-image: url(images/indicators/required.png);
-}
-
-.oo-ui-indicator-up {
-       /* @embed */
-       background-image: url(images/indicators/up.png);
-}
-/* Icons */
-
 .oo-ui-icon-add-item {
        /* @embed */
        background-image: url(images/icons/add-item.svg);
index 706f589..70cb221 100644 (file)
@@ -1,12 +1,12 @@
 /*!
- * OOjs v1.0.6
+ * OOjs v1.0.7-pre (9c04f3e917)
  * https://www.mediawiki.org/wiki/OOjs
  *
- * Copyright 2011-2013 OOjs Team and other contributors.
+ * Copyright 2011-2014 OOjs Team and other contributors.
  * Released under the MIT license
  * http://oojs.mit-license.org
  *
- * Date: Tue Dec 10 2013 22:43:42 GMT+0100 (CET)
+ * Date: Fri Feb 14 2014 17:51:43 GMT-0800 (PST)
  */
 ( function ( global ) {
 
@@ -23,7 +23,6 @@ var
 
 /* Class Methods */
 
-
 /**
  * Assert whether a value is a plain object or not.
  *
@@ -64,23 +63,27 @@ oo.isPlainObject = function ( obj ) {
  *  multiple constructors consider storing an instance of the other constructor in a
  *  property instead, or perhaps use a mixin (see oo.mixinClass).
  *
- *     function Foo() {}
- *     Foo.prototype.jump = function () {};
+ *     function Thing() {}
+ *     Thing.prototype.exists = function () {};
  *
- *     function FooBar() {}
- *     oo.inheritClass( FooBar, Foo );
- *     FooBar.prop.feet = 2;
- *     FooBar.prototype.walk = function () {};
+ *     function Person() {
+ *         this.constructor.super.apply( this, arguments );
+ *     }
+ *     oo.inheritClass( Person, Thing );
+ *     Person.static.defaultEyeCount = 2;
+ *     Person.prototype.walk = function () {};
  *
- *     function FooBarQuux() {}
- *     OO.inheritClass( FooBarQuux, FooBar );
- *     FooBarQuux.prototype.jump = function () {};
+ *     function Jumper() {
+ *         this.constructor.super.apply( this, arguments );
+ *     }
+ *     OO.inheritClass( Jumper, Person );
+ *     Jumper.prototype.jump = function () {};
  *
- *     FooBarQuux.prop.feet === 2;
- *     var fb = new FooBar();
- *     fb.jump();
- *     fb.walk();
- *     fb instanceof Foo && fb instanceof FooBar && fb instanceof FooBarQuux;
+ *     Jumper.static.defaultEyeCount === 2;
+ *     var x = new Jumper();
+ *     x.jump();
+ *     x.walk();
+ *     x instanceof Thing && x instanceof Person && x instanceof Jumper;
  *
  * @method
  * @param {Function} targetFn
@@ -94,6 +97,7 @@ oo.inheritClass = function ( targetFn, originFn ) {
 
        var targetConstructor = targetFn.prototype.constructor;
 
+       targetFn.super = originFn;
        targetFn.prototype = Object.create( originFn.prototype, {
                // Restore constructor property of targetFn
                constructor: {
@@ -502,9 +506,9 @@ oo.EventEmitter.prototype.on = function ( event, callback, args, context ) {
        }
        // Add binding
        bindings.push( {
-               'callback': callback,
-               'args': args,
-               'context': context
+               callback: callback,
+               args: args,
+               context: context
        } );
        return this;
 };
index dc5c001..a7c62b3 100644 (file)
@@ -283,7 +283,7 @@ class CologneBlueTemplate extends BaseTemplate {
                        <?php } ?>
                </div>
        </div>
-       <div id="article" role="main">
+       <div id="article" class="mw-body" role="main">
                <?php if ( $this->getSkin()->getSiteNotice() ) { ?>
                <div id="siteNotice"><?php echo $this->getSkin()->getSiteNotice() ?></div>
                <?php } ?>
index b44b914..899a272 100644 (file)
@@ -428,7 +428,7 @@ class VectorTemplate extends BaseTemplate {
 <div id="p-search" role="search">
        <h3<?php $this->html( 'userlangattributes' ) ?>><label for="searchInput"><?php $this->msg( 'search' ) ?></label></h3>
        <form action="<?php $this->text( 'wgScript' ) ?>" id="searchform">
-               <?php if ( $wgVectorUseSimpleSearch && $this->getSkin()->getUser()->getOption( 'vector-simplesearch' ) ) { ?>
+               <?php if ( $wgVectorUseSimpleSearch ) { ?>
                        <div id="simpleSearch">
                <?php } else { ?>
                        <div>
index 6e4a7b3..b76a825 100644 (file)
@@ -1,3 +1,5 @@
+@import "mediawiki.mixins.rotation"
+
 /* Watch/Unwatch Icon Styling */
 #ca-unwatch.icon a,
 #ca-watch.icon a {
index a7a6c6b..fd05df8 100644 (file)
        d="m 786.52454,689.44812 0,6.09375 4,0 0,-5.28125 -0.84375,0 0,-0.8125 -3.15625,0 z"
        id="rect7896"
        style="fill:url(#radialGradient7968);fill-opacity:1;stroke:none" />
-    <g
-       id="text7952"
-       style="font-size:1px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans">
-      <path
-         d="m 786.54126,689.4494 0.0986,0 0,0.646 0.35498,0 0,0.083 -0.45361,0 0,-0.72901"
-         id="path2999" />
-      <path
-         d="m 787.28833,689.69452 c -0.0482,0 -0.0863,0.0189 -0.11426,0.0566 -0.028,0.0374 -0.042,0.0889 -0.042,0.1543 0,0.0654 0.0138,0.11702 0.0415,0.15478 0.028,0.0374 0.0662,0.0562 0.11475,0.0562 0.0479,0 0.0858,-0.0189 0.11377,-0.0566 0.028,-0.0378 0.042,-0.0892 0.042,-0.15429 0,-0.0648 -0.014,-0.11605 -0.042,-0.15381 -0.028,-0.0381 -0.0659,-0.0571 -0.11377,-0.0571 m 0,-0.0762 c 0.0781,0 0.13949,0.0254 0.18408,0.0762 0.0446,0.0508 0.0669,0.12109 0.0669,0.21094 0,0.0895 -0.0223,0.15983 -0.0669,0.21093 -0.0446,0.0508 -0.10596,0.0762 -0.18408,0.0762 -0.0784,0 -0.13997,-0.0254 -0.18457,-0.0762 -0.0443,-0.0511 -0.0664,-0.12142 -0.0664,-0.21093 0,-0.0898 0.0221,-0.16016 0.0664,-0.21094 0.0446,-0.0508 0.10612,-0.0762 0.18457,-0.0762"
-         id="path3001" />
-      <path
-         d="m 788.00464,689.71552 c -0.0101,-0.006 -0.0212,-0.0101 -0.0332,-0.0127 -0.0117,-0.003 -0.0247,-0.004 -0.0391,-0.004 -0.0508,0 -0.0898,0.0166 -0.11718,0.0498 -0.027,0.0329 -0.0405,0.0802 -0.0405,0.14209 l 0,0.28809 -0.0903,0 0,-0.54688 0.0903,0 0,0.085 c 0.0189,-0.0332 0.0435,-0.0578 0.0737,-0.0737 0.0303,-0.0163 0.0671,-0.0244 0.11035,-0.0244 0.006,0 0.013,4.9e-4 0.0205,10e-4 0.007,6.5e-4 0.0158,0.002 0.0249,0.003 l 4.9e-4,0.0923"
-         id="path3003" />
-      <path
-         d="m 788.54614,689.88251 0,0.0439 -0.41308,0 c 0.004,0.0618 0.0225,0.10905 0.0557,0.1416 0.0335,0.0322 0.0801,0.0483 0.13965,0.0483 0.0345,0 0.0679,-0.004 0.1001,-0.0127 0.0326,-0.008 0.0648,-0.0212 0.0967,-0.0381 l 0,0.085 c -0.0322,0.0137 -0.0653,0.0241 -0.0991,0.0312 -0.0339,0.007 -0.0682,0.0108 -0.10303,0.0108 -0.0872,0 -0.15641,-0.0254 -0.20752,-0.0762 -0.0508,-0.0508 -0.0762,-0.11946 -0.0762,-0.20605 0,-0.0895 0.0241,-0.16048 0.0723,-0.21289 0.0485,-0.0527 0.11377,-0.0791 0.1958,-0.0791 0.0736,0 0.13168,0.0238 0.17432,0.0713 0.043,0.0472 0.0645,0.11149 0.0645,0.19287 m -0.0898,-0.0264 c -6.5e-4,-0.0491 -0.0145,-0.0884 -0.0415,-0.11768 -0.0267,-0.0293 -0.0622,-0.0439 -0.10644,-0.0439 -0.0501,0 -0.0903,0.0142 -0.12061,0.0425 -0.0299,0.0283 -0.0472,0.0682 -0.0517,0.11963 l 0.32031,-4.9e-4"
-         id="path3005" />
-      <path
-         d="m 789.11938,689.73651 c 0.0225,-0.0404 0.0493,-0.0701 0.0806,-0.0893 0.0312,-0.0192 0.068,-0.0288 0.11035,-0.0288 0.057,0 0.10091,0.02 0.13184,0.0601 0.0309,0.0397 0.0464,0.0964 0.0464,0.16992 l 0,0.33008 -0.0903,0 0,-0.32715 c 0,-0.0524 -0.009,-0.0913 -0.0278,-0.1167 -0.0186,-0.0254 -0.0469,-0.0381 -0.085,-0.0381 -0.0466,0 -0.0833,0.0155 -0.11035,0.0464 -0.027,0.0309 -0.0405,0.0731 -0.0405,0.12646 l 0,0.30909 -0.0903,0 0,-0.32715 c 0,-0.0527 -0.009,-0.0916 -0.0278,-0.1167 -0.0186,-0.0254 -0.0472,-0.0381 -0.0859,-0.0381 -0.0459,0 -0.0824,0.0156 -0.10938,0.0469 -0.027,0.0309 -0.0405,0.0729 -0.0405,0.12597 l 0,0.30909 -0.0903,0 0,-0.54688 0.0903,0 0,0.085 c 0.0205,-0.0335 0.0451,-0.0583 0.0737,-0.0742 0.0286,-0.016 0.0627,-0.0239 0.10205,-0.0239 0.0397,0 0.0734,0.0101 0.10107,0.0303 0.028,0.0202 0.0487,0.0495 0.062,0.0879"
-         id="path3007" />
-      <path
-         d="m 786.53735,690.88153 0.0899,0 0,0.54688 -0.0899,0 0,-0.54688 m 0,-0.21289 0.0899,0 0,0.11377 -0.0899,0 0,-0.11377"
-         id="path3009" />
-      <path
-         d="m 786.90161,691.34637 0,0.29004 -0.0903,0 0,-0.75488 0.0903,0 0,0.083 c 0.0189,-0.0326 0.0426,-0.0566 0.0713,-0.0723 0.029,-0.016 0.0635,-0.0239 0.10352,-0.0239 0.0664,0 0.12028,0.0264 0.16162,0.0791 0.0417,0.0527 0.0625,0.12207 0.0625,0.20801 0,0.0859 -0.0208,0.15527 -0.0625,0.208 -0.0413,0.0527 -0.0952,0.0791 -0.16162,0.0791 -0.04,0 -0.0745,-0.008 -0.10352,-0.0234 -0.0286,-0.0159 -0.0524,-0.0402 -0.0713,-0.0728 m 0.30567,-0.19091 c -10e-6,-0.0661 -0.0137,-0.11784 -0.041,-0.15528 -0.027,-0.0378 -0.0643,-0.0566 -0.11182,-0.0566 -0.0475,0 -0.085,0.0189 -0.1123,0.0566 -0.027,0.0374 -0.0405,0.0892 -0.0405,0.15528 0,0.0661 0.0135,0.118 0.0405,0.15576 0.0273,0.0374 0.0648,0.0562 0.1123,0.0562 0.0475,0 0.0848,-0.0187 0.11182,-0.0562 0.0273,-0.0378 0.041,-0.0897 0.041,-0.15576"
-         id="path3011" />
-      <path
-         d="m 787.7981,690.89764 0,0.085 c -0.0254,-0.013 -0.0518,-0.0228 -0.0791,-0.0293 -0.0273,-0.007 -0.0557,-0.01 -0.085,-0.01 -0.0446,0 -0.0781,0.007 -0.10058,0.0205 -0.0221,0.0137 -0.0332,0.0342 -0.0332,0.0615 0,0.0208 0.008,0.0373 0.0239,0.0493 0.0159,0.0117 0.048,0.023 0.0962,0.0337 l 0.0308,0.007 c 0.0638,0.0137 0.10905,0.033 0.13575,0.0581 0.027,0.0247 0.0405,0.0594 0.0405,0.10401 0,0.0508 -0.0202,0.091 -0.0605,0.1206 -0.04,0.0296 -0.0952,0.0444 -0.16553,0.0444 -0.0293,0 -0.0599,-0.003 -0.0918,-0.009 -0.0316,-0.006 -0.0649,-0.014 -0.1001,-0.0254 l 0,-0.0928 c 0.0332,0.0173 0.0659,0.0303 0.0982,0.0391 0.0322,0.008 0.0641,0.0127 0.0957,0.0127 0.0423,0 0.0749,-0.007 0.0977,-0.0215 0.0228,-0.0147 0.0342,-0.0352 0.0342,-0.0615 0,-0.0244 -0.008,-0.0431 -0.0249,-0.0562 -0.0163,-0.013 -0.0522,-0.0255 -0.10792,-0.0376 l -0.0312,-0.007 c -0.0557,-0.0117 -0.0959,-0.0296 -0.1206,-0.0537 -0.0247,-0.0244 -0.0371,-0.0578 -0.0371,-0.1001 0,-0.0514 0.0182,-0.0912 0.0547,-0.11914 0.0365,-0.028 0.0882,-0.042 0.15527,-0.042 0.0332,0 0.0644,0.002 0.0937,0.007 0.0293,0.005 0.0563,0.0122 0.0811,0.022"
-         id="path3013" />
-      <path
-         d="m 787.96167,691.21259 0,-0.33106 0.0898,0 0,0.32764 c 0,0.0518 0.0101,0.0907 0.0303,0.1167 0.0202,0.0257 0.0505,0.0386 0.0908,0.0386 0.0485,0 0.0868,-0.0155 0.11474,-0.0464 0.0283,-0.0309 0.0425,-0.0731 0.0425,-0.12646 l 0,-0.31006 0.0898,0 0,0.54688 -0.0898,0 0,-0.084 c -0.0218,0.0332 -0.0472,0.0579 -0.0762,0.0742 -0.0286,0.0159 -0.062,0.0239 -0.1001,0.0239 -0.0628,0 -0.11051,-0.0195 -0.14306,-0.0586 -0.0326,-0.0391 -0.0488,-0.0962 -0.0488,-0.17138 m 0.22607,-0.34424 0,0"
-         id="path3015" />
-      <path
-         d="m 789.03149,690.98651 c 0.0225,-0.0404 0.0493,-0.0701 0.0806,-0.0893 0.0312,-0.0192 0.068,-0.0288 0.11035,-0.0288 0.057,0 0.10091,0.02 0.13184,0.0601 0.0309,0.0397 0.0464,0.0964 0.0464,0.16992 l 0,0.33008 -0.0903,0 0,-0.32715 c 0,-0.0524 -0.009,-0.0913 -0.0278,-0.1167 -0.0186,-0.0254 -0.0469,-0.0381 -0.085,-0.0381 -0.0465,0 -0.0833,0.0155 -0.11035,0.0464 -0.027,0.0309 -0.0405,0.0731 -0.0405,0.12646 l 0,0.30909 -0.0903,0 0,-0.32715 c 0,-0.0527 -0.009,-0.0916 -0.0278,-0.1167 -0.0186,-0.0254 -0.0472,-0.0381 -0.0859,-0.0381 -0.0459,0 -0.0824,0.0156 -0.10938,0.0469 -0.027,0.0309 -0.0405,0.0729 -0.0405,0.12597 l 0,0.30909 -0.0903,0 0,-0.54688 0.0903,0 0,0.085 c 0.0205,-0.0335 0.0451,-0.0583 0.0737,-0.0742 0.0286,-0.016 0.0627,-0.0239 0.10205,-0.0239 0.0397,0 0.0734,0.0101 0.10107,0.0303 0.028,0.0202 0.0487,0.0495 0.062,0.0879"
-         id="path3017" />
-      <path
-         d="m 786.89722,692.21454 0,-0.2959 0.0898,0 0,0.75977 -0.0898,0 0,-0.082 c -0.0189,0.0326 -0.0428,0.0568 -0.0718,0.0728 -0.0286,0.0156 -0.0631,0.0234 -0.10352,0.0234 -0.0661,0 -0.11995,-0.0264 -0.16162,-0.0791 -0.0413,-0.0527 -0.062,-0.12207 -0.062,-0.208 0,-0.0859 0.0207,-0.15528 0.062,-0.20801 0.0417,-0.0527 0.0955,-0.0791 0.16162,-0.0791 0.0404,0 0.0749,0.008 0.10352,0.0239 0.029,0.0156 0.0529,0.0397 0.0718,0.0723 m -0.30616,0.19092 c 0,0.0661 0.0135,0.118 0.0405,0.15576 0.0274,0.0374 0.0648,0.0562 0.11231,0.0562 0.0475,0 0.085,-0.0187 0.1123,-0.0562 0.0273,-0.0378 0.041,-0.0897 0.041,-0.15576 0,-0.0661 -0.0137,-0.11784 -0.041,-0.15528 -0.0273,-0.0378 -0.0648,-0.0566 -0.1123,-0.0566 -0.0475,0 -0.085,0.0189 -0.11231,0.0566 -0.027,0.0374 -0.0405,0.0892 -0.0405,0.15528"
-         id="path3019" />
-      <path
-         d="m 787.38403,692.19452 c -0.0482,0 -0.0863,0.0189 -0.11425,0.0566 -0.028,0.0374 -0.042,0.0889 -0.042,0.1543 0,0.0654 0.0138,0.11702 0.0415,0.15478 0.028,0.0374 0.0662,0.0562 0.11474,0.0562 0.0478,0 0.0858,-0.0189 0.11377,-0.0566 0.028,-0.0378 0.042,-0.0892 0.042,-0.15429 0,-0.0648 -0.014,-0.11605 -0.042,-0.15381 -0.028,-0.0381 -0.0659,-0.0571 -0.11377,-0.0571 m 0,-0.0762 c 0.0781,0 0.13949,0.0254 0.18409,0.0762 0.0446,0.0508 0.0669,0.12109 0.0669,0.21094 0,0.0895 -0.0223,0.15983 -0.0669,0.21093 -0.0446,0.0508 -0.10596,0.0762 -0.18409,0.0762 -0.0785,0 -0.13997,-0.0254 -0.18457,-0.0762 -0.0443,-0.0511 -0.0664,-0.12142 -0.0664,-0.21093 0,-0.0898 0.0221,-0.16016 0.0664,-0.21094 0.0446,-0.0508 0.10612,-0.0762 0.18457,-0.0762"
-         id="path3021" />
-      <path
-         d="m 787.78345,691.91864 0.0898,0 0,0.75977 -0.0898,0 0,-0.75977"
-         id="path3023" />
-      <path
-         d="m 788.27271,692.19452 c -0.0482,0 -0.0863,0.0189 -0.11426,0.0566 -0.028,0.0374 -0.042,0.0889 -0.042,0.1543 -10e-6,0.0654 0.0138,0.11702 0.0415,0.15478 0.028,0.0374 0.0662,0.0562 0.11475,0.0562 0.0479,0 0.0858,-0.0189 0.11376,-0.0566 0.028,-0.0378 0.042,-0.0892 0.042,-0.15429 0,-0.0648 -0.014,-0.11605 -0.042,-0.15381 -0.028,-0.0381 -0.0659,-0.0571 -0.11376,-0.0571 m 0,-0.0762 c 0.0781,0 0.13948,0.0254 0.18408,0.0762 0.0446,0.0508 0.0669,0.12109 0.0669,0.21094 0,0.0895 -0.0223,0.15983 -0.0669,0.21093 -0.0446,0.0508 -0.10596,0.0762 -0.18408,0.0762 -0.0785,0 -0.13998,-0.0254 -0.18458,-0.0762 -0.0443,-0.0511 -0.0664,-0.12142 -0.0664,-0.21093 0,-0.0898 0.0221,-0.16016 0.0664,-0.21094 0.0446,-0.0508 0.10612,-0.0762 0.18458,-0.0762"
-         id="path3025" />
-      <path
-         d="m 788.98901,692.21552 c -0.0101,-0.006 -0.0212,-0.0101 -0.0332,-0.0127 -0.0117,-0.003 -0.0247,-0.004 -0.0391,-0.004 -0.0508,0 -0.0898,0.0166 -0.11719,0.0498 -0.027,0.0329 -0.0405,0.0802 -0.0405,0.14209 l 0,0.28809 -0.0903,0 0,-0.54688 0.0903,0 0,0.085 c 0.0189,-0.0332 0.0435,-0.0578 0.0737,-0.0737 0.0303,-0.0163 0.0671,-0.0244 0.11036,-0.0244 0.006,0 0.013,4.9e-4 0.0205,10e-4 0.007,6.5e-4 0.0158,0.002 0.0249,0.003 l 4.8e-4,0.0923"
-         id="path3027" />
-      <path
-         d="m 786.88599,693.39764 0,0.085 c -0.0254,-0.013 -0.0518,-0.0228 -0.0791,-0.0293 -0.0273,-0.007 -0.0557,-0.01 -0.085,-0.01 -0.0446,0 -0.0781,0.007 -0.10058,0.0205 -0.0221,0.0137 -0.0332,0.0342 -0.0332,0.0615 0,0.0208 0.008,0.0373 0.0239,0.0493 0.0159,0.0117 0.048,0.023 0.0962,0.0337 l 0.0308,0.007 c 0.0638,0.0137 0.10905,0.033 0.13575,0.0581 0.027,0.0247 0.0405,0.0594 0.0405,0.10401 0,0.0508 -0.0202,0.091 -0.0605,0.1206 -0.04,0.0296 -0.0952,0.0444 -0.16553,0.0444 -0.0293,0 -0.0599,-0.003 -0.0918,-0.009 -0.0316,-0.006 -0.0649,-0.014 -0.1001,-0.0254 l 0,-0.0928 c 0.0332,0.0173 0.0659,0.0303 0.0982,0.0391 0.0322,0.008 0.0641,0.0127 0.0957,0.0127 0.0423,0 0.0749,-0.007 0.0977,-0.0215 0.0228,-0.0147 0.0342,-0.0352 0.0342,-0.0615 0,-0.0244 -0.008,-0.0431 -0.0249,-0.0562 -0.0163,-0.013 -0.0522,-0.0255 -0.10791,-0.0376 l -0.0312,-0.007 c -0.0557,-0.0117 -0.0959,-0.0296 -0.12061,-0.0537 -0.0247,-0.0244 -0.0371,-0.0578 -0.0371,-0.1001 0,-0.0514 0.0182,-0.0912 0.0547,-0.11914 0.0365,-0.028 0.0882,-0.042 0.15527,-0.042 0.0332,0 0.0644,0.002 0.0937,0.007 0.0293,0.005 0.0563,0.0122 0.0811,0.022"
-         id="path3029" />
-      <path
-         d="m 787.05884,693.38153 0.0898,0 0,0.54688 -0.0898,0 0,-0.54688 m 0,-0.21289 0.0898,0 0,0.11377 -0.0898,0 0,-0.11377"
-         id="path3031" />
-      <path
-         d="m 787.42505,693.22626 0,0.15527 0.18506,0 0,0.0698 -0.18506,0 0,0.29688 c 0,0.0446 0.006,0.0732 0.0181,0.0859 0.0124,0.0127 0.0373,0.019 0.0747,0.019 l 0.0923,0 0,0.0752 -0.0923,0 c -0.0693,0 -0.11719,-0.0129 -0.14355,-0.0386 -0.0264,-0.026 -0.0396,-0.0732 -0.0396,-0.1416 l 0,-0.29688 -0.0659,0 0,-0.0698 0.0659,0 0,-0.15527 0.0903,0"
-         id="path3033" />
-      <path
-         d="m 788.29565,693.6535 c -0.0726,0 -0.12288,0.008 -0.15087,0.0249 -0.028,0.0166 -0.042,0.0449 -0.042,0.085 0,0.0319 0.0104,0.0573 0.0312,0.0762 0.0212,0.0185 0.0498,0.0278 0.0859,0.0278 0.0498,0 0.0897,-0.0176 0.11963,-0.0527 0.0303,-0.0355 0.0454,-0.0825 0.0454,-0.14112 l 0,-0.02 -0.0894,0 m 0.1792,-0.0371 0,0.31202 -0.0898,0 0,-0.083 c -0.0205,0.0332 -0.0461,0.0578 -0.0767,0.0737 -0.0306,0.0156 -0.068,0.0234 -0.11231,0.0234 -0.056,0 -0.10058,-0.0156 -0.13378,-0.0469 -0.0329,-0.0316 -0.0493,-0.0737 -0.0493,-0.12646 0,-0.0615 0.0205,-0.10791 0.0615,-0.13916 0.0413,-0.0312 0.10287,-0.0469 0.18457,-0.0469 l 0.12598,0 0,-0.009 c 0,-0.0413 -0.0137,-0.0732 -0.041,-0.0957 -0.027,-0.0228 -0.0651,-0.0342 -0.11425,-0.0342 -0.0312,0 -0.0617,0.004 -0.0913,0.0112 -0.0296,0.007 -0.0581,0.0187 -0.0854,0.0337 l 0,-0.083 c 0.0329,-0.0127 0.0648,-0.0221 0.0957,-0.0283 0.0309,-0.007 0.061,-0.01 0.0903,-0.01 0.0791,0 0.13819,0.0205 0.17725,0.0615 0.0391,0.041 0.0586,0.10319 0.0586,0.18652"
-         id="path3035" />
-      <path
-         d="m 789.08618,693.48651 c 0.0225,-0.0404 0.0493,-0.0701 0.0806,-0.0893 0.0312,-0.0192 0.068,-0.0288 0.11035,-0.0288 0.057,0 0.10091,0.02 0.13184,0.0601 0.0309,0.0397 0.0464,0.0964 0.0464,0.16992 l 0,0.33008 -0.0903,0 0,-0.32715 c 0,-0.0524 -0.009,-0.0913 -0.0278,-0.1167 -0.0186,-0.0254 -0.0469,-0.0381 -0.085,-0.0381 -0.0466,0 -0.0833,0.0155 -0.11035,0.0464 -0.027,0.0309 -0.0405,0.0731 -0.0405,0.12646 l 0,0.30909 -0.0903,0 0,-0.32715 c 0,-0.0527 -0.009,-0.0916 -0.0278,-0.1167 -0.0186,-0.0254 -0.0472,-0.0381 -0.0859,-0.0381 -0.0459,0 -0.0824,0.0156 -0.10938,0.0469 -0.027,0.0309 -0.0405,0.0729 -0.0405,0.12597 l 0,0.30909 -0.0903,0 0,-0.54688 0.0903,0 0,0.085 c 0.0205,-0.0335 0.0451,-0.0583 0.0737,-0.0742 0.0286,-0.016 0.0627,-0.0239 0.10206,-0.0239 0.0397,0 0.0734,0.0101 0.10107,0.0303 0.028,0.0202 0.0487,0.0495 0.062,0.0879"
-         id="path3037" />
-      <path
-         d="m 790.10278,693.63251 0,0.0439 -0.41308,0 c 0.004,0.0618 0.0225,0.10905 0.0557,0.1416 0.0335,0.0322 0.0801,0.0483 0.13965,0.0483 0.0345,0 0.0679,-0.004 0.1001,-0.0127 0.0326,-0.008 0.0648,-0.0212 0.0967,-0.0381 l 0,0.085 c -0.0322,0.0137 -0.0653,0.0241 -0.0991,0.0312 -0.0339,0.007 -0.0682,0.0108 -0.10303,0.0108 -0.0872,0 -0.15641,-0.0254 -0.20752,-0.0762 -0.0508,-0.0508 -0.0762,-0.11946 -0.0762,-0.20605 0,-0.0895 0.0241,-0.16048 0.0723,-0.21289 0.0485,-0.0527 0.11377,-0.0791 0.1958,-0.0791 0.0736,0 0.13168,0.0238 0.17432,0.0713 0.043,0.0472 0.0645,0.11149 0.0645,0.19287 m -0.0898,-0.0264 c -6.5e-4,-0.0491 -0.0145,-0.0884 -0.0415,-0.11768 -0.0267,-0.0293 -0.0622,-0.0439 -0.10645,-0.0439 -0.0501,0 -0.0903,0.0142 -0.12061,0.0425 -0.0299,0.0283 -0.0472,0.0682 -0.0517,0.11963 l 0.32031,-4.9e-4"
-         id="path3039" />
-      <path
-         d="m 790.33911,693.22626 0,0.15527 0.18506,0 0,0.0698 -0.18506,0 0,0.29688 c 0,0.0446 0.006,0.0732 0.0181,0.0859 0.0124,0.0127 0.0373,0.019 0.0747,0.019 l 0.0923,0 0,0.0752 -0.0923,0 c -0.0693,0 -0.11718,-0.0129 -0.14355,-0.0386 -0.0264,-0.026 -0.0395,-0.0732 -0.0395,-0.1416 l 0,-0.29688 -0.0659,0 0,-0.0698 0.0659,0 0,-0.15527 0.0903,0"
-         id="path3041" />
-    </g>
+    <path
+       d="m 790.33911,693.22626 c -0.0498,0.19786 0.33032,0.17787 0.003,0.27815 -0.16998,0.24799 0.39939,0.51157 -0.0311,0.38026 -0.0547,-0.17272 -0.19121,-0.57992 0.0276,-0.65857 m -0.23638,0.40635 c -0.1524,0.0463 -0.6328,0.0553 -0.24172,0.21827 0.48594,0.05 -0.34395,0.2177 -0.26091,-0.17076 -0.08,-0.37141 0.5251,-0.43406 0.50275,-0.0476 m -0.0898,-0.0264 c 0.0121,-0.34938 -0.523,0.0801 -0.0661,1.6e-4 0.022,-3e-5 0.0441,-7e-5 0.0661,-1e-4 M 789.086,693.4864 c 0.29829,-0.46808 0.54605,0.50739 0.27992,0.36129 0.16156,-0.25017 -0.25661,-0.58879 -0.25488,-0.19318 0.0618,0.20786 -0.16306,0.36284 -0.0814,0.0576 0.0107,-0.40895 -0.3951,-0.2098 -0.28228,0.0968 -0.10398,0.30793 -0.19195,-0.59656 0.0363,-0.38389 0.11037,-0.0424 0.2633,-0.11931 0.3025,0.062 m -0.79072,0.16676 c -0.35692,-0.0559 0.0391,0.45637 0.0912,0.0607 0.0111,-0.0474 -0.0478,-0.0975 -0.0913,-0.0606 m 0.1792,-0.0371 c 0.0389,0.27609 4.8e-4,0.31202 -0.23096,0.30993 -0.40958,0.0339 -0.12848,-0.45975 0.12931,-0.3933 -0.0182,-0.14721 -0.50917,-0.032 -0.16875,-0.16893 0.13714,-0.0119 0.30604,0.0969 0.27048,0.25186 m -1.04972,-0.38964 c -0.0498,0.19787 0.33033,0.17786 0.003,0.27815 -0.16997,0.24801 0.39941,0.51157 -0.0312,0.38026 -0.0548,-0.17265 -0.1912,-0.5799 0.0275,-0.65857 m -0.36616,0.15537 c 0.24316,0.0804 0.005,0.86043 -0.008,0.29992 0.004,-0.10008 0.0106,-0.19944 0.008,-0.29992 z m 0,-0.21289 c 0.22907,-0.0248 -0.0564,0.25715 0,0 z m -0.17285,0.229 c -0.0882,0.10339 -0.47525,0.0905 -0.12796,0.20033 0.32998,0.11579 -0.0901,0.56917 -0.25377,0.26243 0.35714,0.0875 0.26894,-0.20613 0.0291,-0.26075 -0.0991,-0.20406 0.219,-0.31306 0.35275,-0.20238 m 2.10283,-1.18179 c -0.31133,-0.19291 -0.2311,0.78642 -0.32232,0.2231 -0.003,-0.21834 -0.0409,-0.33207 0.20367,-0.28984 0.0532,-0.0761 0.16542,-0.007 0.1188,0.0663 m -0.71625,-0.0206 c -0.45977,0.0927 0.20216,0.73875 0.1549,0.16183 -0.008,-0.0784 -0.0689,-0.16424 -0.1549,-0.16175 m 0,-0.0762 c 0.53548,0.0229 0.0809,0.95772 -0.22515,0.4264 -0.0799,-0.16794 0.006,-0.44314 0.22515,-0.4264 z m -0.48925,-0.19976 c 0.18272,0.15398 0.0847,0.54861 0.0579,0.75376 -0.12668,-0.16038 -0.0274,-0.52657 -0.0579,-0.75376 z m -0.39942,0.27588 c -0.45976,0.0927 0.20217,0.73874 0.15491,0.16183 -0.008,-0.0784 -0.0689,-0.16425 -0.15491,-0.16175 m 0,-0.0762 c 0.53548,0.0229 0.0809,0.95772 -0.22514,0.4264 -0.0799,-0.16793 0.006,-0.44314 0.22514,-0.4264 z m -0.4868,0.0961 c -0.0625,-0.16476 0.0794,-0.45885 0.09,-0.12059 -0.0239,0.26428 0.11747,0.64725 -0.22523,0.59616 -0.43366,0.0367 -0.28113,-0.79293 0.1054,-0.51731 l 0.0299,0.0419 m -0.30616,0.19092 c 0.047,0.51755 0.63135,-0.23866 0.10766,-0.19898 -0.0793,0.0264 -0.13034,0.11753 -0.10766,0.19898 z m 2.44043,-1.41901 c 0.29826,-0.46803 0.54607,0.50725 0.27992,0.36136 0.16147,-0.25014 -0.25659,-0.58875 -0.25486,-0.19318 0.0619,0.20787 -0.16304,0.36286 -0.0814,0.0576 0.0107,-0.40895 -0.3951,-0.2098 -0.28228,0.0968 -0.10398,0.30793 -0.19195,-0.59655 0.0362,-0.3839 0.11037,-0.0424 0.26328,-0.11929 0.30249,0.062 m -1.07,0.22585 c -0.0292,-0.18312 0.0291,-0.522 0.10111,-0.12385 -0.10501,0.40792 0.38701,0.2743 0.27403,-0.0627 0.0564,-0.3908 0.20452,0.56128 -0.0268,0.36504 -0.17034,0.0747 -0.37234,0.0484 -0.34922,-0.17885 m -0.16355,-0.31494 c -0.0882,0.10339 -0.47525,0.0905 -0.12796,0.20033 0.32998,0.11579 -0.0901,0.56917 -0.25377,0.26243 0.35714,0.0875 0.26894,-0.20613 0.0291,-0.26075 -0.0991,-0.20406 0.219,-0.31306 0.35275,-0.20238 m -0.89668,0.44906 c 0.0709,0.22245 -0.11848,0.41831 -0.0905,0.067 -0.0102,-0.29611 -0.0793,-0.68343 0.34185,-0.49802 0.37303,0.11125 0.0193,0.78296 -0.25134,0.43095 m 0.30567,-0.19091 c -0.0477,-0.51709 -0.63035,0.23885 -0.1077,0.199 0.0793,-0.0265 0.1303,-0.11753 0.1077,-0.199 z m -0.66993,-0.2739 c 0.24336,0.0802 0.006,0.86052 -0.008,0.29994 0.004,-0.10009 0.0107,-0.19945 0.008,-0.29994 z m 0,-0.21289 c 0.22926,-0.0249 -0.0564,0.25727 0,0 z m 2.58203,-0.93213 c 0.29827,-0.46803 0.54607,0.50727 0.27992,0.36136 0.16146,-0.25013 -0.25657,-0.58874 -0.25484,-0.19316 0.0618,0.20786 -0.16306,0.36284 -0.0814,0.0576 0.0107,-0.40895 -0.3951,-0.2098 -0.28228,0.0968 -0.10398,0.30793 -0.19195,-0.59655 0.0363,-0.38389 0.11037,-0.0424 0.26329,-0.11932 0.30249,0.062 m -0.57342,0.14577 c -0.15244,0.0463 -0.6328,0.0553 -0.24172,0.21831 0.48594,0.0499 -0.34396,0.21764 -0.26091,-0.1708 -0.08,-0.37142 0.52507,-0.43399 0.50275,-0.0476 m -0.0898,-0.0264 c 0.0121,-0.34938 -0.52298,0.0801 -0.066,1.6e-4 0.022,-3e-5 0.0441,-7e-5 0.0661,-10e-5 m -0.4519,-0.14058 c -0.31132,-0.1929 -0.23109,0.78642 -0.32231,0.2231 -0.003,-0.21839 -0.0409,-0.33204 0.20369,-0.28978 0.0533,-0.0761 0.16541,-0.007 0.11871,0.0664 m -0.71627,-0.0206 c -0.45977,0.0927 0.20216,0.73875 0.1549,0.16183 -0.008,-0.0784 -0.0689,-0.16424 -0.1549,-0.16175 m 0,-0.0762 c 0.53548,0.0229 0.0809,0.95772 -0.22514,0.4264 -0.0799,-0.16794 0.006,-0.44314 0.22514,-0.4264 z m -0.74706,-0.169 c 0.25031,0.19128 -0.10354,0.79515 0.43395,0.67146 -0.24652,0.23651 -0.54896,-0.0523 -0.43399,-0.36033 0,-0.10371 0,-0.20743 0,-0.31114"
+       id="path3041"
+       style="fill:#000000;fill-opacity:1;stroke:none" />
     <path
        d="m 789.74329,687.77624 0,2.35938 2.34375,0"
        id="path7894"
index 3fbdfe7..e5514a7 100644 (file)
   <g
      transform="translate(-877.85712,-687.36218)"
      id="layer1">
-    <g
-       id="text5536"
-       style="font-size:41.13991928px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans">
-      <path
-         d="m 879.87841,689.39933 0.19335,0 0,0.60364 0.33948,0 0,0.14614 -0.53283,0 0,-0.74978"
-         id="path3051"
-         style="font-size:1.02849805px;font-weight:bold;-inkscape-font-specification:Sans Bold" />
-      <path
-         d="m 880.52524,689.58665 0.17978,0 0,0.56246 -0.17978,0 0,-0.56246 m 0,-0.21896 0.17978,0 0,0.14664 -0.17978,0 0,-0.14664"
-         id="path3053"
-         style="font-size:1.02849805px;font-weight:bold;-inkscape-font-specification:Sans Bold" />
-      <path
-         d="m 881.05857,690.06775 0,0.29529 -0.17979,0 0,-0.77639 0.17979,0 0,0.0824 c 0.0248,-0.0328 0.0522,-0.0569 0.0824,-0.0723 0.0301,-0.0157 0.0648,-0.0236 0.10396,-0.0236 0.0693,0 0.12621,0.0276 0.17074,0.0829 0.0445,0.0549 0.0668,0.12572 0.0668,0.21243 0,0.0867 -0.0223,0.15769 -0.0668,0.21293 -0.0445,0.0549 -0.10144,0.0824 -0.17074,0.0824 -0.0392,0 -0.0738,-0.008 -0.10396,-0.0231 -0.0301,-0.0157 -0.0576,-0.04 -0.0824,-0.0728 m 0.11952,-0.36409 c -0.0385,0 -0.0681,0.0142 -0.0889,0.0427 -0.0204,0.0281 -0.0306,0.0688 -0.0306,0.12203 0,0.0532 0.0102,0.0941 0.0306,0.12254 0.0208,0.0281 0.0504,0.0422 0.0889,0.0422 0.0385,0 0.0678,-0.0141 0.0879,-0.0422 0.0204,-0.0281 0.0306,-0.069 0.0306,-0.12254 0,-0.0536 -0.0102,-0.0944 -0.0306,-0.12253 -0.0201,-0.0281 -0.0494,-0.0422 -0.0879,-0.0422"
-         id="path3055"
-         style="font-size:1.02849805px;font-weight:bold;-inkscape-font-specification:Sans Bold" />
-      <path
-         d="m 882.05543,689.60423 0,0.13659 c -0.0385,-0.0161 -0.0757,-0.0281 -0.11149,-0.0362 -0.0358,-0.008 -0.0696,-0.0121 -0.10144,-0.0121 -0.0341,0 -0.0596,0.004 -0.0763,0.0131 -0.0164,0.008 -0.0246,0.0214 -0.0246,0.0392 0,0.0144 0.006,0.0255 0.0186,0.0332 0.0127,0.008 0.0353,0.0134 0.0678,0.0171 l 0.0316,0.005 c 0.0921,0.0117 0.15401,0.031 0.18582,0.0578 0.0318,0.0268 0.0477,0.0688 0.0477,0.12605 -10e-6,0.0599 -0.0221,0.10496 -0.0663,0.13509 -0.0442,0.0301 -0.11015,0.0452 -0.19787,0.0452 -0.0372,0 -0.0757,-0.003 -0.11551,-0.009 -0.0395,-0.006 -0.0802,-0.0144 -0.12203,-0.0261 l 0,-0.1366 c 0.0358,0.0174 0.0725,0.0305 0.10998,0.0392 0.0378,0.009 0.0762,0.0131 0.115,0.0131 0.0352,0 0.0616,-0.005 0.0793,-0.0146 0.0178,-0.01 0.0266,-0.0241 0.0266,-0.0432 0,-0.0161 -0.006,-0.028 -0.0186,-0.0357 -0.0121,-0.008 -0.0363,-0.0142 -0.0728,-0.0186 l -0.0316,-0.004 c -0.08,-0.01 -0.1361,-0.0286 -0.16824,-0.0557 -0.0321,-0.0271 -0.0482,-0.0683 -0.0482,-0.12354 0,-0.0596 0.0204,-0.10379 0.0613,-0.13258 0.0408,-0.0288 0.10345,-0.0432 0.18782,-0.0432 0.0331,0 0.068,0.003 0.10446,0.008 0.0365,0.005 0.0762,0.0129 0.11902,0.0236"
-         id="path3057"
-         style="font-size:1.02849805px;font-weight:bold;-inkscape-font-specification:Sans Bold" />
-      <path
-         d="m 882.22266,689.93015 0,-0.3435 0.18079,0 0,0.0563 c 0,0.0305 -1.7e-4,0.0688 -5e-4,0.115 -3.3e-4,0.0459 -5e-4,0.0765 -5e-4,0.0919 0,0.0452 10e-4,0.0778 0.004,0.0979 0.002,0.0198 0.006,0.0342 0.0121,0.0432 0.007,0.0117 0.0169,0.0208 0.0286,0.0271 0.0121,0.006 0.0258,0.01 0.0412,0.01 0.0375,0 0.067,-0.0144 0.0884,-0.0432 0.0214,-0.0288 0.0321,-0.0688 0.0321,-0.12003 l 0,-0.27771 0.17978,0 0,0.56246 -0.17978,0 0,-0.0814 c -0.0271,0.0328 -0.0559,0.0571 -0.0864,0.0728 -0.0301,0.0154 -0.0634,0.0231 -0.0999,0.0231 -0.0649,0 -0.1145,-0.0199 -0.14865,-0.0598 -0.0338,-0.0398 -0.0507,-0.0978 -0.0507,-0.17376"
-         id="path3059"
-         style="font-size:1.02849805px;font-weight:bold;-inkscape-font-specification:Sans Bold" />
-      <path
-         d="m 883.48317,689.68006 c 0.0228,-0.0348 0.0497,-0.0613 0.0809,-0.0793 0.0315,-0.0184 0.066,-0.0276 0.10345,-0.0276 0.0646,0 0.11383,0.0199 0.14765,0.0598 0.0338,0.0398 0.0507,0.0978 0.0507,0.17376 l 0,0.3425 -0.18079,0 0,-0.29328 c 3.3e-4,-0.004 5e-4,-0.009 5e-4,-0.0136 3.3e-4,-0.005 5e-4,-0.0114 5e-4,-0.0201 0,-0.0398 -0.006,-0.0686 -0.0176,-0.0864 -0.0117,-0.0181 -0.0306,-0.0271 -0.0567,-0.0271 -0.0342,0 -0.0606,0.0141 -0.0794,0.0422 -0.0184,0.0281 -0.028,0.0688 -0.0286,0.12203 l 0,0.27621 -0.18079,0 0,-0.29328 c 0,-0.0623 -0.005,-0.10228 -0.0161,-0.12003 -0.0107,-0.0181 -0.0298,-0.0271 -0.0573,-0.0271 -0.0345,0 -0.0611,0.0142 -0.0798,0.0427 -0.0187,0.0281 -0.0281,0.0685 -0.0281,0.12103 l 0,0.27671 -0.18079,0 0,-0.56246 0.18079,0 0,0.0824 c 0.0221,-0.0318 0.0474,-0.0557 0.0758,-0.0718 0.0288,-0.0161 0.0604,-0.0241 0.0949,-0.0241 0.0388,0 0.0732,0.009 0.10295,0.0281 0.0298,0.0187 0.0524,0.045 0.0678,0.0788"
-         id="path3061"
-         style="font-size:1.02849805px;font-weight:bold;-inkscape-font-specification:Sans Bold" />
-    </g>
-    <g
-       transform="scale(1.0447384,0.95717741)"
-       id="text5540"
-       style="font-size:48.46436691px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans">
-      <path
-         d="m 847.3858,720.32852 -0.1621,0.43956 0.3248,0 -0.1627,-0.43956 m -0.0674,-0.11773 0.13548,0 0.33662,0.88327 -0.12423,0 -0.0805,-0.22659 -0.39815,0 -0.0805,0.22659 -0.12601,0 0.33721,-0.88327"
-         id="path3064"
-         style="font-size:1.21160913px;-inkscape-font-specification:Sans" />
-    </g>
-    <g
-       id="text5544"
-       style="font-size:1px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans">
-      <path
-         d="m 883.88953,691.50378 0.13281,0 0.32324,0.60987 0,-0.60987 0.0957,0 0,0.72901 -0.13281,0 -0.32324,-0.60987 0,0.60987 -0.0957,0 0,-0.72901"
-         id="path3067" />
-      <path
-         d="m 885.10144,691.93689 0,0.0439 -0.41309,0 c 0.004,0.0619 0.0225,0.10905 0.0557,0.14161 0.0335,0.0322 0.0801,0.0483 0.13965,0.0483 0.0345,0 0.0679,-0.004 0.10009,-0.0127 0.0326,-0.008 0.0648,-0.0212 0.0967,-0.0381 l 0,0.085 c -0.0322,0.0137 -0.0653,0.0241 -0.0991,0.0312 -0.0339,0.007 -0.0682,0.0107 -0.10302,0.0107 -0.0872,0 -0.15642,-0.0254 -0.20752,-0.0762 -0.0508,-0.0508 -0.0762,-0.11947 -0.0762,-0.20606 0,-0.0895 0.0241,-0.16048 0.0723,-0.21289 0.0485,-0.0527 0.11377,-0.0791 0.1958,-0.0791 0.0736,0 0.13167,0.0238 0.17432,0.0713 0.043,0.0472 0.0645,0.11149 0.0645,0.19287 m -0.0898,-0.0264 c -6.5e-4,-0.0492 -0.0145,-0.0884 -0.0415,-0.11767 -0.0267,-0.0293 -0.0622,-0.0439 -0.10644,-0.0439 -0.0501,0 -0.0903,0.0142 -0.12061,0.0425 -0.0299,0.0283 -0.0472,0.0682 -0.0518,0.11963 l 0.32032,-4.9e-4"
-         id="path3069" />
-      <path
-         d="m 885.19666,691.68591 0.0898,0 0.1123,0.42676 0.11182,-0.42676 0.10596,0 0.1123,0.42676 0.11182,-0.42676 0.0898,0 -0.14306,0.54688 -0.10596,0 -0.11768,-0.44824 -0.11816,0.44824 -0.10596,0 -0.14306,-0.54688"
-         id="path3071" />
-    </g>
-    <g
-       id="text5548"
-       style="font-size:1px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans">
-      <path
-         d="m 883.88953,693.52722 0.13281,0 0.32324,0.60986 0,-0.60986 0.0957,0 0,0.72901 -0.13281,0 -0.32324,-0.60987 0,0.60987 -0.0957,0 0,-0.72901"
-         id="path3074" />
-      <path
-         d="m 885.10144,693.96033 0,0.0439 -0.41309,0 c 0.004,0.0618 0.0225,0.10905 0.0557,0.1416 0.0335,0.0322 0.0801,0.0483 0.13965,0.0483 0.0345,0 0.0679,-0.004 0.10009,-0.0127 0.0326,-0.008 0.0648,-0.0212 0.0967,-0.0381 l 0,0.085 c -0.0322,0.0137 -0.0653,0.0241 -0.0991,0.0312 -0.0339,0.007 -0.0682,0.0108 -0.10302,0.0108 -0.0872,0 -0.15642,-0.0254 -0.20752,-0.0762 -0.0508,-0.0508 -0.0762,-0.11946 -0.0762,-0.20605 0,-0.0895 0.0241,-0.16048 0.0723,-0.21289 0.0485,-0.0527 0.11377,-0.0791 0.1958,-0.0791 0.0736,0 0.13167,0.0238 0.17432,0.0713 0.043,0.0472 0.0645,0.11149 0.0645,0.19287 m -0.0898,-0.0264 c -6.5e-4,-0.0491 -0.0145,-0.0884 -0.0415,-0.11768 -0.0267,-0.0293 -0.0622,-0.0439 -0.10644,-0.0439 -0.0501,0 -0.0903,0.0142 -0.12061,0.0425 -0.0299,0.0283 -0.0472,0.0682 -0.0518,0.11963 l 0.32032,-4.9e-4"
-         id="path3076" />
-      <path
-         d="m 885.19666,693.70935 0.0898,0 0.1123,0.42676 0.11182,-0.42676 0.10596,0 0.1123,0.42676 0.11182,-0.42676 0.0898,0 -0.14306,0.54688 -0.10596,0 -0.11768,-0.44825 -0.11816,0.44825 -0.10596,0 -0.14306,-0.54688"
-         id="path3078" />
-    </g>
+    <path
+       d="m 885.19659,693.70929 c 0.18733,0.11152 0.2171,0.58028 0.28483,0.0765 0.21963,-0.21 0.25265,0.61085 0.31801,0.0641 0.27697,-0.42352 -0.0831,0.827 -0.17686,0.17405 -0.11702,-0.43251 -0.13186,0.58055 -0.33199,0.093 -0.0467,-0.13235 -0.0352,-0.27894 -0.0941,-0.40765 m -0.0951,0.25098 c -0.24545,-0.026 -0.58057,0.20963 -0.14983,0.20815 0.2341,0.24227 -0.5966,0.0435 -0.31586,-0.29597 0.073,-0.29368 0.48945,-0.19996 0.46582,0.0878 m -0.0898,-0.0264 c -0.008,-0.37273 -0.57907,0.10308 -3e-5,6e-5 m -1.12221,-0.4067 c 0.31303,-0.0182 0.47686,0.98363 0.45605,0.28209 0.0542,-0.83126 0.27546,1.00617 -0.15278,0.25362 -0.0894,-0.27779 -0.27195,-0.54907 -0.20757,-0.0888 -0.0326,0.82392 -0.13826,-0.33361 -0.0957,-0.44691 z m 1.30713,-1.84131 c 0.18733,0.11152 0.2171,0.58028 0.28483,0.0765 0.21963,-0.21 0.25265,0.61085 0.31801,0.0641 0.27697,-0.42352 -0.0831,0.827 -0.17686,0.17405 -0.11703,-0.43249 -0.13186,0.58055 -0.33199,0.093 -0.0467,-0.13235 -0.0352,-0.27894 -0.0941,-0.40765 m -0.0951,0.25098 c -0.24545,-0.026 -0.58058,0.20964 -0.14984,0.20816 0.23409,0.24222 -0.5966,0.0434 -0.31584,-0.29607 0.0729,-0.29368 0.48945,-0.19997 0.46581,0.0877 m -0.0898,-0.0264 c -0.008,-0.37272 -0.57905,0.1031 -3e-5,7e-5 m -1.12221,-0.40661 c 0.31303,-0.0182 0.47685,0.98364 0.45605,0.2821 0.0542,-0.83128 0.27546,1.00616 -0.15278,0.25361 -0.0894,-0.27779 -0.27195,-0.54907 -0.20757,-0.0888 -0.0326,0.82392 -0.13826,-0.33361 -0.0957,-0.44691 z m 1.40695,-2.02159 c -0.0925,0.22919 -0.31156,0.57023 0.14418,0.41318 -0.005,-0.13405 -0.10264,-0.27877 -0.14418,-0.41318 z m -0.0704,-0.11269 c 0.29905,0.0855 0.42028,0.62166 0.42088,0.84191 -0.13411,-0.4802 -0.68425,-0.0265 -0.73057,-0.076 0.0832,-0.2616 0.21061,-0.50913 0.3096,-0.76593 m -1.74281,0.31056 c 0.34612,-0.47913 0.56926,0.70098 0.21372,0.36363 0.0724,-0.32969 -0.28365,-0.36875 -0.1668,-0.0222 -0.26673,0.45246 -0.17742,-0.6565 -0.3994,-0.10395 -0.0864,0.678 -0.43164,-0.63601 0.14263,-0.31419 0.0903,0.008 0.17045,-0.0312 0.20982,0.0769 m -1.26048,0.25 c -0.10571,-0.34023 0.21201,-0.48784 0.17971,-0.0655 0.20532,0.47932 0.16846,-0.59018 0.40143,-0.15309 0.19369,0.48548 -0.51086,0.6449 -0.5806,0.21899 m -0.16777,-0.32628 c 0.003,0.21747 -0.51383,0.059 -0.0685,0.22157 0.38953,0.3392 -0.58676,0.41358 -0.309,0.22699 0.52432,-0.0372 -0.45958,-0.30319 0.0896,-0.4819 0.0946,-0.0287 0.2045,-0.0235 0.28796,0.0344 m -0.99688,0.46241 c 0.0892,0.4554 -0.3135,0.24019 -0.17953,-0.10036 -0.28045,-0.78623 1.07442,-0.23273 0.43248,0.1872 -0.0909,0.0271 -0.20018,-0.005 -0.25295,-0.0867 m 0.11952,-0.36409 c -0.39427,0.13009 0.34651,0.51437 0.0773,0.0311 l -0.034,-0.025 -0.0433,-0.006 z m -0.65285,-0.11717 c 0.42856,-0.041 0.0577,0.97963 -0.005,0.32973 0.003,-0.10996 0.007,-0.21971 0.005,-0.32973 z m 0,-0.21896 c 0.43196,-0.11169 -0.0481,0.43831 0,0 z m -0.64683,0.0316 c 0.44435,-0.0237 -0.0875,0.85036 0.53283,0.60364 -0.23411,0.42107 -0.67995,0.0409 -0.53283,-0.33773 0,-0.0886 0,-0.17727 0,-0.26591 z"
+       id="path3078"
+       style="fill:#000000;fill-opacity:1;stroke:none" />
     <rect
        width="2.8749001"
        height="2.8749392"
index 796adf3..6cf658f 100644 (file)
@@ -886,6 +886,49 @@ more stuff
                $this->assertEquals( "one", $page->getContent()->getNativeData() );
        }
 
+       /**
+        * @covers WikiPage::doRollback
+        */
+       public function testDoRollbackFailureSameContent() {
+               $admin = new User();
+               $admin->setName( "Admin" );
+               $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
+
+               $text = "one";
+               $page = $this->newPage( "WikiPageTest_testDoRollback" );
+               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
+                       "section one", EDIT_NEW, false, $admin );
+               $rev1 = $page->getRevision();
+
+               $user1 = new User();
+               $user1->setName( "127.0.1.11" );
+               $user1->addGroup( "sysop" ); #XXX: make the test user a sysop...
+               $text .= "\n\ntwo";
+               $page = new WikiPage( $page->getTitle() );
+               $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
+                       "adding section two", 0, false, $user1 );
+
+               # now, do a the rollback from the same user was doing the edit before
+               $resultDetails = array();
+               $token = $user1->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null );
+               $errors = $page->doRollback( $user1->getName(), "testing revert same user", $token, false, $resultDetails, $admin );
+
+               $this->assertEquals( array(), $errors, "Rollback failed same user" );
+
+               # now, try the rollback
+               $resultDetails = array();
+               $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null );
+               $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $resultDetails, $admin );
+
+               $this->assertEquals( array( array( 'alreadyrolled', 'WikiPageTest testDoRollback',
+                       '127.0.1.11', 'Admin' ) ), $errors, "Rollback not failed" );
+
+               $page = new WikiPage( $page->getTitle() );
+               $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
+                       "rollback did not revert to the correct revision" );
+               $this->assertEquals( "one", $page->getContent()->getNativeData() );
+       }
+
        public static function provideGetAutosummary() {
                return array(
                        array(
index 6930f38..ba00ff9 100644 (file)
@@ -1,6 +1,6 @@
 /*global CompletenessTest, sinon */
 /*jshint evil: true */
-( function ( $, mw, QUnit, undefined ) {
+( function ( $, mw, QUnit ) {
        'use strict';
 
        var mwTestIgnore, mwTester,
                liveMessages = mw.messages.values;
 
                function freshConfigCopy( custom ) {
+                       var copy, warn;
                        // Tests should mock all factors that directly influence the tested code.
-                       // For backwards compatibility though we set mw.config to a copy of the live config
-                       // and extend it with the (optionally) given custom settings for this test
-                       // (instead of starting blank with only the given custmo settings).
-                       // This is a shallow copy, so we don't end up with settings taking an array value
-                       // extended with the custom settings - setting a config property means you override it,
-                       // not extend it.
-                       return $.extend( {}, liveConfig, custom );
+                       // For backwards compatibility though we set mw.config to a fresh copy of the live
+                       // config. This way any modifications made to mw.config during the test will not
+                       // affect other tests, nor the global scope outside the test runner.
+                       // This is a shallow copy, since overriding an array or object value via "custom"
+                       // should replace it. Setting a config property means you override it, not extend it.
+                       // NOTE: It is important that we temporarily disable mw.log#warn as extend() will
+                       // trigger MWDeprecationWarning for each of the deprecated properties.
+                       warn = mw.log.warn;
+                       mw.log.warn = $.noop;
+
+                       copy = $.extend( {}, liveConfig, custom );
+
+                       mw.log.warn = warn;
+
+                       return copy;
                }
 
                function freshMessagesCopy( custom ) {
index 6e13e13..292c576 100644 (file)
@@ -17,6 +17,7 @@
                                // The values for gender are not significant,
                                // what matters is which of the values is choosen by the parser
                                'gender-msg': '$1: {{GENDER:$2|blue|pink|green}}',
+                               'gender-msg-currentuser': '{{GENDER:|blue|pink|green}}',
 
                                'plural-msg': 'Found $1 {{PLURAL:$1|item|items}}',
 
                assert.equal( formatParse( 'plural-msg', 2 ), 'Found 2 items', 'Plural test for english' );
        } );
 
-       QUnit.test( 'Gender', 11, function ( assert ) {
+       QUnit.test( 'Gender', 15, function ( assert ) {
+               var originalGender = mw.user.options.get( 'gender' );
+
                // TODO: These tests should be for mw.msg once mw.msg integrated with mw.jqueryMsg
                // TODO: English may not be the best language for these tests. Use a language like Arabic or Russian
-               var user = mw.user;
-
-               user.options.set( 'gender', 'male' );
+               mw.user.options.set( 'gender', 'male' );
                assert.equal(
                        formatParse( 'gender-msg', 'Bob', 'male' ),
                        'Bob: blue',
                        'Masculine from string "male"'
                );
                assert.equal(
-                       formatParse( 'gender-msg', 'Bob', user ),
+                       formatParse( 'gender-msg', 'Bob', mw.user ),
                        'Bob: blue',
                        'Masculine from mw.user object'
                );
-
-               user.options.set( 'gender', 'unknown' );
                assert.equal(
-                       formatParse( 'gender-msg', 'Foo', user ),
-                       'Foo: green',
-                       'Neutral from mw.user object' );
+                       formatParse( 'gender-msg-currentuser' ),
+                       'blue',
+                       'Masculine for current user'
+               );
+
+               mw.user.options.set( 'gender', 'female' );
                assert.equal(
                        formatParse( 'gender-msg', 'Alice', 'female' ),
                        'Alice: pink',
                        'Feminine from string "female"' );
+               assert.equal(
+                       formatParse( 'gender-msg', 'Alice', mw.user ),
+                       'Alice: pink',
+                       'Feminine from mw.user object'
+               );
+               assert.equal(
+                       formatParse( 'gender-msg-currentuser' ),
+                       'pink',
+                       'Feminine for current user'
+               );
+
+               mw.user.options.set( 'gender', 'unknown' );
+               assert.equal(
+                       formatParse( 'gender-msg', 'Foo', mw.user ),
+                       'Foo: green',
+                       'Neutral from mw.user object' );
                assert.equal(
                        formatParse( 'gender-msg', 'User' ),
                        'User: green',
                        'User: green',
                        'Neutral from string "unknown"'
                );
+               assert.equal(
+                       formatParse( 'gender-msg-currentuser' ),
+                       'green',
+                       'Neutral for current user'
+               );
 
                mw.messages.set( 'gender-msg-one-form', '{{GENDER:$1|User}}: $2 {{PLURAL:$2|edit|edits}}' );
 
                        ' test',
                        'Invalid syntax should result in {{gender}} simply being stripped away'
                );
+
+               mw.user.options.set( 'gender', originalGender );
        } );
 
        QUnit.test( 'Grammar', 2, function ( assert ) {