get the label, and "$key-value" or "$key-value-text"/"$key-value-html" to
format the value.
$key: Key for the limit report item (string)
-$value: Value of the limit report item
+&$value: Value of the limit report item
&$report: String onto which to append the data
$isHTML: If true, $report is an HTML table with two columns; if false, it's
text intended for display in a monospaced font.
'ParserLimitReportPrepare': Called at the end of Parser:parse() when the parser will
include comments about size of the text parsed. Hooks should use
-$output->setLimitReportData() to populate data.
+$output->setLimitReportData() to populate data. Functions for this hook should
+not use $wgLang; do that in ParserLimitReportFormat instead.
$parser: Parser object
$output: ParserOutput object
} elseif ( $this->getTitle()->quickUserCan( 'create', $this->getContext()->getUser() )
&& $this->getTitle()->quickUserCan( 'edit', $this->getContext()->getUser() )
) {
- $text = wfMessage( 'noarticletext' )->plain();
+ $message = $this->getContext()->getUser()->isLoggedIn() ? 'noarticletext' : 'noarticletextanon';
+ $text = wfMessage( $message )->plain();
} else {
$text = wfMessage( 'noarticletext-nopermission' )->plain();
}
'ResourceLoaderNoscriptModule' => 'includes/resourceloader/ResourceLoaderNoscriptModule.php',
'ResourceLoaderSiteModule' => 'includes/resourceloader/ResourceLoaderSiteModule.php',
'ResourceLoaderStartUpModule' => 'includes/resourceloader/ResourceLoaderStartUpModule.php',
- 'ResourceLoaderUserCSSPrefsModule' => 'includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php',
+ 'ResourceLoaderUserCSSPrefsModule' =>
+ 'includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php',
'ResourceLoaderUserGroupsModule' => 'includes/resourceloader/ResourceLoaderUserGroupsModule.php',
'ResourceLoaderUserModule' => 'includes/resourceloader/ResourceLoaderUserModule.php',
'ResourceLoaderUserOptionsModule' => 'includes/resourceloader/ResourceLoaderUserOptionsModule.php',
'ResourceLoaderUserTokensModule' => 'includes/resourceloader/ResourceLoaderUserTokensModule.php',
- 'ResourceLoaderLanguageDataModule' => 'includes/resourceloader/ResourceLoaderLanguageDataModule.php',
+ 'ResourceLoaderLanguageDataModule' =>
+ 'includes/resourceloader/ResourceLoaderLanguageDataModule.php',
'ResourceLoaderWikiModule' => 'includes/resourceloader/ResourceLoaderWikiModule.php',
# includes/revisiondelete
# includes/utils
'ArrayUtils' => 'includes/utils/ArrayUtils.php',
- 'CdbFunctions' => 'includes/utils/Cdb_PHP.php',
+ 'CdbFunctions' => 'includes/utils/CdbPHP.php',
'CdbReader' => 'includes/utils/Cdb.php',
- 'CdbReader_DBA' => 'includes/utils/Cdb.php',
- 'CdbReader_PHP' => 'includes/utils/Cdb_PHP.php',
+ 'CdbReaderDBA' => 'includes/utils/Cdb.php',
+ 'CdbReaderPHP' => 'includes/utils/CdbPHP.php',
'CdbWriter' => 'includes/utils/Cdb.php',
- 'CdbWriter_DBA' => 'includes/utils/Cdb.php',
- 'CdbWriter_PHP' => 'includes/utils/Cdb_PHP.php',
+ 'CdbWriterDBA' => 'includes/utils/Cdb.php',
+ 'CdbWriterPHP' => 'includes/utils/CdbPHP.php',
'ConfEditor' => 'includes/utils/ConfEditor.php',
'ConfEditorParseError' => 'includes/utils/ConfEditor.php',
'ConfEditorToken' => 'includes/utils/ConfEditor.php',
foreach ( $output->getLimitReportData() as $key => $value ) {
if ( wfRunHooks( 'ParserLimitReportFormat',
- array( $key, $value, &$limitReport, true, true )
+ array( $key, &$value, &$limitReport, true, true )
) ) {
$keyMsg = wfMessage( $key );
$valueMsg = wfMessage( array( "$key-value-html", "$key-value" ) );
*
* Copyright © 2008, Niklas Laxström
* Copyright © 2011, Antoine Musso
+ * Copyright © 2013, Bartosz Dziewoński
*
* 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
const STRING = 0;
/** Integer type, maps guessType() to WebRequest::getInt() */
const INT = 1;
+ /** Float type, maps guessType() to WebRequest::getFloat()
+ * @since 1.23 */
+ const FLOAT = 4;
/** Boolean type, maps guessType() to WebRequest::getBool() */
const BOOL = 2;
/** Integer type or null, maps to WebRequest::getIntOrNull()
return self::BOOL;
} elseif ( is_int( $data ) ) {
return self::INT;
+ } elseif ( is_float( $data ) ) {
+ return self::FLOAT;
} elseif ( is_string( $data ) ) {
return self::STRING;
} else {
}
/**
- * Validate and set an option integer value
- * The value will be altered to fit in the range.
+ * @see validateBounds()
+ */
+ public function validateIntBounds( $name, $min, $max ) {
+ $this->validateBounds( $name, $min, $max );
+ }
+
+ /**
+ * Constrain a numeric value for a given option to a given range. The value will be altered to fit
+ * in the range.
*
- * @param string $name option name
- * @param int $min minimum value
- * @param int $max maximum value
+ * @since 1.23
+ *
+ * @param string $name Option name
+ * @param int|float $min Minimum value
+ * @param int|float $max Maximum value
* @throws MWException If option is not of type INT
*/
- public function validateIntBounds( $name, $min, $max ) {
+ public function validateBounds( $name, $min, $max ) {
$this->validateName( $name, true );
+ $type = $this->options[$name]['type'];
- if ( $this->options[$name]['type'] !== self::INT ) {
- throw new MWException( "Option $name is not of type int" );
+ if ( $type !== self::INT && $type !== self::FLOAT ) {
+ throw new MWException( "Option $name is not of type INT or FLOAT" );
}
$value = $this->getValueReal( $this->options[$name] );
case self::INT:
$value = $r->getInt( $name, $default );
break;
+ case self::FLOAT:
+ $value = $r->getFloat( $name, $default );
+ break;
case self::STRING:
$value = $r->getText( $name, $default );
break;
if ( $useLogPipe ) {
$desc[3] = array( 'pipe', 'w' );
}
+
+ # TODO/FIXME: This is a bad hack to workaround an HHVM bug that prevents
+ # proc_open() from opening stdin/stdout, so use /dev/null *for now*
+ # See bug 56597 / https://github.com/facebook/hhvm/issues/1247 for more info
+ if ( wfIsHHVM() ) {
+ $desc[0] = array( 'file', '/dev/null', 'r' );
+ $desc[2] = array( 'file', '/dev/null', 'w' );
+ }
+
$pipes = null;
$proc = proc_open( $cmd, $desc, $pipes );
if ( !$proc ) {
: null;
}
+ /**
+ * Fetch a floating point value from the input or return $default if not set.
+ * Guaranteed to return a float; non-numeric input will typically
+ * return 0.
+ *
+ * @since 1.23
+ * @param $name String
+ * @param $default Float
+ * @return Float
+ */
+ public function getFloat( $name, $default = 0 ) {
+ return floatval( $this->getVal( $name, $default ) );
+ }
+
/**
* Fetch a boolean value from the input or return $default if not set.
* Guaranteed to return true or false, with normal PHP semantics for
$vals['patrolled'] = '';
}
+ if ( $this->fld_patrolled && ChangesList::isUnpatrolled( $row, $this->getUser() ) ) {
+ $vals['unpatrolled'] = '';
+ }
+
if ( $this->fld_loginfo && $row->rc_type == RC_LOG ) {
$vals['logid'] = intval( $row->rc_logid );
$vals['logtype'] = $row->rc_log_type;
' ids - Adds the page ID, recent changes ID and the new and old revision ID',
' sizes - Adds the new and old page length in bytes',
' redirect - Tags edit if page is a redirect',
- ' patrolled - Tags edits that have been patrolled',
+ ' patrolled - Tags patrollable edits as being patrolled or unpatrolled',
' loginfo - Adds log information (logid, logtype, etc) to log entries',
' tags - Lists tags for the entry',
' sha1 - Adds the content checksum for entries associated with a revision',
'redirect' => 'boolean'
),
'patrolled' => array(
- 'patrolled' => 'boolean'
+ 'patrolled' => 'boolean',
+ 'unpatrolled' => 'boolean'
),
'loginfo' => array(
'logid' => array(
$this->preCacheMessages();
}
- /**
- * Fetch an appropriate changes list class for the main context
- * This first argument used to be an User object.
- *
- * @deprecated in 1.18; use newFromContext() instead
- * @param string|User $unused Unused
- * @return ChangesList|EnhancedChangesList|OldChangesList derivative
- */
- public static function newFromUser( $unused ) {
- wfDeprecated( __METHOD__, '1.18' );
- return self::newFromContext( RequestContext::getMain() );
- }
-
/**
* Fetch an appropriate changes list class for the specified context
* Some users might want to use an enhanced list format, for instance
}
protected function showAsUnpatrolled( RecentChange $rc ) {
- $unpatrolled = false;
- if ( !$rc->mAttribs['rc_patrolled'] ) {
- if ( $this->getUser()->useRCPatrol() ) {
- $unpatrolled = true;
- } elseif ( $this->getUser()->useNPPatrol() && $rc->mAttribs['rc_type'] == RC_NEW ) {
- $unpatrolled = true;
+ return self::isUnpatrolled( $rc, $this->getUser() );
+ }
+
+ /**
+ * @param object|RecentChange $rc Database row from recentchanges or a RecentChange object
+ * @param User $user
+ * @return bool
+ */
+ public static function isUnpatrolled( $rc, User $user ) {
+ if ( $rc instanceof RecentChange ) {
+ $isPatrolled = $rc->mAttribs['rc_patrolled'];
+ $rcType = $rc->mAttribs['rc_type'];
+ } else {
+ $isPatrolled = $rc->rc_patrolled;
+ $rcType = $rc->rc_type;
+ }
+
+ if ( !$isPatrolled ) {
+ if ( $user->useRCPatrol() ) {
+ return true;
+ }
+ if ( $user->useNPPatrol() && $rcType == RC_NEW ) {
+ return true;
}
}
- return $unpatrolled;
+
+ return false;
}
}
'jquery.makeCollapsible',
'mediawiki.icon',
) );
+
return '';
}
+
/**
* Format a line for enhanced recentchange (aka with javascript and block of lines).
*
wfProfileIn( __METHOD__ );
# Create a specialised object
- $rc = RCCacheEntry::newFromParent( $baseRC );
+ $cacheEntry = RCCacheEntry::newFromParent( $baseRC );
- $curIdEq = array( 'curid' => $rc->mAttribs['rc_cur_id'] );
+ $curIdEq = array( 'curid' => $cacheEntry->mAttribs['rc_cur_id'] );
# If it's a new day, add the headline and flush the cache
- $date = $this->getLanguage()->userDate( $rc->mAttribs['rc_timestamp'], $this->getUser() );
+ $date = $this->getLanguage()->userDate(
+ $cacheEntry->mAttribs['rc_timestamp'],
+ $this->getUser()
+ );
+
$ret = '';
+
if ( $date != $this->lastdate ) {
# Process current cache
$ret = $this->recentChangesBlock();
}
# Should patrol-related stuff be shown?
- $rc->unpatrolled = $this->showAsUnpatrolled( $rc );
+ $cacheEntry->unpatrolled = $this->showAsUnpatrolled( $cacheEntry );
$showdifflinks = true;
+
# Make article link
- $type = $rc->mAttribs['rc_type'];
- $logType = $rc->mAttribs['rc_log_type'];
+ $type = $cacheEntry->mAttribs['rc_type'];
+ $logType = $cacheEntry->mAttribs['rc_log_type'];
+
// Page moves, very old style, not supported anymore
if ( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
// New unpatrolled pages
- } elseif ( $rc->unpatrolled && $type == RC_NEW ) {
- $clink = Linker::linkKnown( $rc->getTitle() );
+ } elseif ( $cacheEntry->unpatrolled && $type == RC_NEW ) {
+ $clink = Linker::linkKnown( $cacheEntry->getTitle() );
// Log entries
} elseif ( $type == RC_LOG ) {
if ( $logType ) {
$logname = $logpage->getName()->escaped();
$clink = $this->msg( 'parentheses' )->rawParams( Linker::linkKnown( $logtitle, $logname ) )->escaped();
} else {
- $clink = Linker::link( $rc->getTitle() );
+ $clink = Linker::link( $cacheEntry->getTitle() );
}
$watched = false;
// Log entries (old format) and special pages
- } elseif ( $rc->mAttribs['rc_namespace'] == NS_SPECIAL ) {
+ } elseif ( $cacheEntry->mAttribs['rc_namespace'] == NS_SPECIAL ) {
wfDebug( "Unexpected special page in recentchanges\n" );
$clink = '';
// Edits
} else {
- $clink = Linker::linkKnown( $rc->getTitle() );
+ $clink = Linker::linkKnown( $cacheEntry->getTitle() );
}
# Don't show unusable diff links
- if ( !ChangesList::userCan( $rc, Revision::DELETED_TEXT, $this->getUser() ) ) {
+ if ( !ChangesList::userCan( $cacheEntry, Revision::DELETED_TEXT, $this->getUser() ) ) {
$showdifflinks = false;
}
- $time = $this->getLanguage()->userTime( $rc->mAttribs['rc_timestamp'], $this->getUser() );
- $rc->watched = $watched;
- $rc->link = $clink;
- $rc->timestamp = $time;
- $rc->numberofWatchingusers = $baseRC->numberofWatchingusers;
+ $time = $this->getLanguage()->userTime( $cacheEntry->mAttribs['rc_timestamp'], $this->getUser() );
+
+ $cacheEntry->watched = $watched;
+ $cacheEntry->link = $clink;
+ $cacheEntry->timestamp = $time;
+ $cacheEntry->numberofWatchingusers = $baseRC->numberofWatchingusers;
# Make "cur" and "diff" links. Do not use link(), it is too slow if
# called too many times (50% of CPU time on RecentChanges!).
- $thisOldid = $rc->mAttribs['rc_this_oldid'];
- $lastOldid = $rc->mAttribs['rc_last_oldid'];
+ $thisOldid = $cacheEntry->mAttribs['rc_this_oldid'];
+ $lastOldid = $cacheEntry->mAttribs['rc_last_oldid'];
$querycur = $curIdEq + array( 'diff' => '0', 'oldid' => $thisOldid );
$querydiff = $curIdEq + array( 'diff' => $thisOldid, 'oldid' => $lastOldid );
if ( $type != RC_NEW ) {
$curLink = $this->message['cur'];
} else {
- $curUrl = htmlspecialchars( $rc->getTitle()->getLinkURL( $querycur ) );
+ $curUrl = htmlspecialchars( $cacheEntry->getTitle()->getLinkURL( $querycur ) );
$curLink = "<a href=\"$curUrl\" tabindex=\"{$baseRC->counter}\">{$this->message['cur']}</a>";
}
$diffLink = $this->message['diff'];
} else {
- $diffUrl = htmlspecialchars( $rc->getTitle()->getLinkURL( $querydiff ) );
- $curUrl = htmlspecialchars( $rc->getTitle()->getLinkURL( $querycur ) );
+ $diffUrl = htmlspecialchars( $cacheEntry->getTitle()->getLinkURL( $querydiff ) );
+ $curUrl = htmlspecialchars( $cacheEntry->getTitle()->getLinkURL( $querycur ) );
$diffLink = "<a href=\"$diffUrl\" tabindex=\"{$baseRC->counter}\">{$this->message['diff']}</a>";
$curLink = "<a href=\"$curUrl\" tabindex=\"{$baseRC->counter}\">{$this->message['cur']}</a>";
}
} elseif ( in_array( $type, array( RC_LOG, RC_MOVE, RC_MOVE_OVER_REDIRECT ) ) ) {
$lastLink = $this->message['last'];
} else {
- $lastLink = Linker::linkKnown( $rc->getTitle(), $this->message['last'],
+ $lastLink = Linker::linkKnown( $cacheEntry->getTitle(), $this->message['last'],
array(), $curIdEq + array( 'diff' => $thisOldid, 'oldid' => $lastOldid ) );
}
# Make user links
- if ( $this->isDeleted( $rc, Revision::DELETED_USER ) ) {
- $rc->userlink = ' <span class="history-deleted">' . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
+ if ( $this->isDeleted( $cacheEntry, Revision::DELETED_USER ) ) {
+ $cacheEntry->userlink = ' <span class="history-deleted">' . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
} else {
- $rc->userlink = Linker::userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
- $rc->usertalklink = Linker::userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
+ $cacheEntry->userlink = Linker::userLink(
+ $cacheEntry->mAttribs['rc_user'],
+ $cacheEntry->mAttribs['rc_user_text']
+ );
+
+ $cacheEntry->usertalklink = Linker::userToolLinks(
+ $cacheEntry->mAttribs['rc_user'],
+ $cacheEntry->mAttribs['rc_user_text']
+ );
}
- $rc->lastlink = $lastLink;
- $rc->curlink = $curLink;
- $rc->difflink = $diffLink;
+ $cacheEntry->lastlink = $lastLink;
+ $cacheEntry->curlink = $curLink;
+ $cacheEntry->difflink = $diffLink;
# Put accumulated information into the cache, for later display
# Page moves go on their own line
- $title = $rc->getTitle();
+ $title = $cacheEntry->getTitle();
$secureName = $title->getPrefixedDBkey();
+
if ( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
# Use an @ character to prevent collision with page names
- $this->rc_cache['@@' . ( $this->rcMoveIndex++ )] = array( $rc );
+ $this->rc_cache['@@' . ( $this->rcMoveIndex++ )] = array( $cacheEntry );
} else {
# Logs are grouped by type
if ( $type == RC_LOG ) {
$this->rc_cache[$secureName] = array();
}
- array_push( $this->rc_cache[$secureName], $rc );
+ array_push( $this->rc_cache[$secureName], $cacheEntry );
}
wfProfileOut( __METHOD__ );
* connection object, by specifying no parameters to __construct(). This
* feature is deprecated and should be removed.
*
- * FIXME: The long list of formal parameters here is not really appropriate
- * for MySQL, and not at all appropriate for any other DBMS. It should be
- * replaced by named parameters as in DatabaseBase::factory().
- *
* DatabaseBase subclasses should not be constructed directly in external
* code. DatabaseBase::factory() should be used instead.
*
- * @param string $server database server host
- * @param string $user database user name
- * @param string $password database user password
- * @param string $dbName database name
- * @param $flags
- * @param string $tablePrefix database table prefixes. By default use the prefix gave in LocalSettings.php
- * @param bool $foreign disable some operations specific to local databases
+ * @param array Parameters passed from DatabaseBase::factory()
*/
- function __construct( $server = false, $user = false, $password = false, $dbName = false,
- $flags = 0, $tablePrefix = 'get from global', $foreign = false
- ) {
+ function __construct( $params = null ) {
global $wgDBprefix, $wgCommandLineMode, $wgDebugDBTransactions;
$this->mTrxAtomicLevels = new SplStack;
- $this->mFlags = $flags;
+ if ( is_array( $params ) ) { // MW 1.22
+ $server = $params['host'];
+ $user = $params['user'];
+ $password = $params['password'];
+ $dbName = $params['dbname'];
+ $flags = $params['flags'];
+ $tablePrefix = $params['tablePrefix'];
+ $foreign = $params['foreign'];
+ } else { // legacy calling pattern
+ wfDeprecated( __METHOD__ . " method called without parameter array.", "1.22" );
+ $args = func_get_args();
+ $server = isset( $args[0] ) ? $args[0] : false;
+ $user = isset( $args[1] ) ? $args[1] : false;
+ $password = isset( $args[2] ) ? $args[2] : false;
+ $dbName = isset( $args[3] ) ? $args[3] : false;
+ $flags = isset( $args[4] ) ? $args[4] : 0;
+ $tablePrefix = isset( $args[5] ) ? $args[5] : 'get from global';
+ $foreign = isset( $args[6] ) ? $args[6] : false;
+ }
+
+ $this->mFlags = $flags;
if ( $this->mFlags & DBO_DEFAULT ) {
if ( $wgCommandLineMode ) {
$this->mFlags &= ~DBO_TRX;
$class = 'Database' . ucfirst( $driver );
if ( class_exists( $class ) && is_subclass_of( $class, 'DatabaseBase' ) ) {
- return new $class(
- isset( $p['host'] ) ? $p['host'] : false,
- isset( $p['user'] ) ? $p['user'] : false,
- isset( $p['password'] ) ? $p['password'] : false,
- isset( $p['dbname'] ) ? $p['dbname'] : false,
- isset( $p['flags'] ) ? $p['flags'] : 0,
- isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : 'get from global',
- isset( $p['foreign'] ) ? $p['foreign'] : false
+ $params = array(
+ 'host' => isset( $p['host'] ) ? $p['host'] : false,
+ 'user' => isset( $p['user'] ) ? $p['user'] : false,
+ 'password' => isset( $p['password'] ) ? $p['password'] : false,
+ 'dbname' => isset( $p['dbname'] ) ? $p['dbname'] : false,
+ 'flags' => isset( $p['flags'] ) ? $p['flags'] : 0,
+ 'tablePrefix' => isset( $p['tablePrefix'] ) ? $p['tablePrefix'] : 'get from global',
+ 'foreign' => isset( $p['foreign'] ) ? $p['foreign'] : false
);
+ return new $class( $params );
} else {
return null;
}
var $mFieldInfoCache = array();
- function __construct( $server = false, $user = false, $password = false, $dbName = false,
- $flags = 0, $tablePrefix = 'get from global' )
- {
+ function __construct( $p = null ) {
global $wgDBprefix;
- $tablePrefix = $tablePrefix == 'get from global' ? strtoupper( $wgDBprefix ) : strtoupper( $tablePrefix );
- parent::__construct( $server, $user, $password, $dbName, $flags, $tablePrefix );
+
+ if ( !is_array( $p ) ) { // legacy calling pattern
+ wfDeprecated( __METHOD__ . " method called without parameter array.", "1.22" );
+ $args = func_get_args();
+ $p = array(
+ 'host' => isset( $args[0] ) ? $args[0] : false,
+ 'user' => isset( $args[1] ) ? $args[1] : false,
+ 'password' => isset( $args[2] ) ? $args[2] : false,
+ 'dbname' => isset( $args[3] ) ? $args[3] : false,
+ 'flags' => isset( $args[4] ) ? $args[4] : 0,
+ 'tablePrefix' => isset( $args[5] ) ? $args[5] : 'get from global',
+ 'foreign' => isset( $args[6] ) ? $args[6] : false
+ );
+ }
+ if ( $p['tablePrefix'] == 'get from global' ) {
+ $p['tablePrefix'] = $wgDBprefix;
+ }
+ $p['tablePrefix'] = strtoupper( $p['tablePrefix'] );
+ parent::__construct( $p );
wfRunHooks( 'DatabaseOraclePostInit', array( $this ) );
}
*/
protected $mConn;
- /**
- * Constructor.
- * Parameters $server, $user and $password are not used.
- * @param $server string
- * @param $user string
- * @param $password string
- * @param $dbName string
- * @param $flags int
- */
- function __construct( $server = false, $user = false, $password = false, $dbName = false, $flags = 0 ) {
- $this->mName = $dbName;
- parent::__construct( $server, $user, $password, $dbName, $flags );
+ function __construct( $p = null ) {
+ global $wgSharedDB;
+
+ if ( !is_array( $p ) ) { // legacy calling pattern
+ wfDeprecated( __METHOD__ . " method called without parameter array.", "1.22" );
+ $args = func_get_args();
+ $p = array(
+ 'host' => isset( $args[0] ) ? $args[0] : false,
+ 'user' => isset( $args[1] ) ? $args[1] : false,
+ 'password' => isset( $args[2] ) ? $args[2] : false,
+ 'dbname' => isset( $args[3] ) ? $args[3] : false,
+ 'flags' => isset( $args[4] ) ? $args[4] : 0,
+ 'tablePrefix' => isset( $args[5] ) ? $args[5] : 'get from global',
+ 'foreign' => isset( $args[6] ) ? $args[6] : false
+ );
+ }
+ $this->mName = $p['dbname'];
+ parent::__construct( $p );
// parent doesn't open when $user is false, but we can work with $dbName
- if ( $dbName && !$this->isOpen() ) {
- global $wgSharedDB;
- if ( $this->open( $server, $user, $password, $dbName ) && $wgSharedDB ) {
- $this->attachDatabase( $wgSharedDB );
+ if ( $p['dbname'] && !$this->isOpen() ) {
+ if ( $this->open( $p['host'], $p['user'], $p['password'], $p['dbname'] ) ) {
+ if ( $wgSharedDB ) {
+ $this->attachDatabase( $wgSharedDB );
+ }
}
}
}
protected $maxFileSize = 4294967296; // integer bytes (4GiB)
const CACHE_TTL = 10; // integer; TTL in seconds for process cache entries
- const CACHE_CHEAP_SIZE = 300; // integer; max entries in "cheap cache"
+ const CACHE_CHEAP_SIZE = 500; // integer; max entries in "cheap cache"
const CACHE_EXPENSIVE_SIZE = 5; // integer; max entries in "expensive cache"
/**
*
* @param string $fullCont Resolved container name
* @param string $dir Resolved storage directory with no trailing slash
- * @param string|null $after Storage path of file to list items after
+ * @param string|null $after Resolved container relative path to list items after
* @param integer $limit Max number of items to list
* @param array $params Parameters for getDirectoryList()
- * @return Array List of resolved paths of directories directly under $dir
+ * @return Array List of container relative resolved paths of directories directly under $dir
* @throws FileBackendError
*/
public function getDirListPageInternal( $fullCont, $dir, &$after, $limit, array $params ) {
*
* @param string $fullCont Resolved container name
* @param string $dir Resolved storage directory with no trailing slash
- * @param string|null $after Storage path of file to list items after
+ * @param string|null $after Resolved container relative path of file to list items after
* @param integer $limit Max number of items to list
* @param array $params Parameters for getDirectoryList()
- * @return Array List of resolved paths of files under $dir
+ * @return Array List of resolved container relative paths of files under $dir
* @throws FileBackendError
*/
public function getFileListPageInternal( $fullCont, $dir, &$after, $limit, array $params ) {
- $files = array();
+ $files = array(); // list of (path, stat array or null) entries
if ( $after === INF ) {
return $files; // nothing more
}
try {
$container = $this->getContainer( $fullCont );
$prefix = ( $dir == '' ) ? null : "{$dir}/";
+ $objects = array(); // list of unfiltered names or CF_Object items
// Non-recursive: only list files right under $dir
- if ( !empty( $params['topOnly'] ) ) { // files and dirs
+ if ( !empty( $params['topOnly'] ) ) {
if ( !empty( $params['adviseStat'] ) ) {
- $limit = min( $limit, self::CACHE_CHEAP_SIZE );
// Note: get_objects() does not include directories
- $objects = $this->loadObjectListing( $params, $dir,
- $container->get_objects( $limit, $after, $prefix, null, '/' ) );
- $files = $objects;
+ $objects = $container->get_objects( $limit, $after, $prefix, null, '/' );
} else {
+ // Note: list_objects() includes directories here
$objects = $container->list_objects( $limit, $after, $prefix, null, '/' );
- foreach ( $objects as $object ) { // files and directories
- if ( substr( $object, -1 ) !== '/' ) {
- $files[] = $object; // directories end in '/'
- }
- }
}
+ $files = $this->buildFileObjectListing( $params, $dir, $objects );
// Recursive: list all files under $dir and its subdirs
- } else { // files
+ } else {
+ // Note: get_objects()/list_objects() here only return file objects
if ( !empty( $params['adviseStat'] ) ) {
- $limit = min( $limit, self::CACHE_CHEAP_SIZE );
- $objects = $this->loadObjectListing( $params, $dir,
- $container->get_objects( $limit, $after, $prefix ) );
+ $objects = $container->get_objects( $limit, $after, $prefix );
} else {
$objects = $container->list_objects( $limit, $after, $prefix );
}
- $files = $objects;
+ $files = $this->buildFileObjectListing( $params, $dir, $objects );
}
// Page on the unfiltered object listing (what is returned may be filtered)
if ( count( $objects ) < $limit ) {
$after = INF; // avoid a second RTT
} else {
$after = end( $objects ); // update last item
+ $after = is_object( $after ) ? $after->name : $after;
}
} catch ( NoSuchContainerException $e ) {
} catch ( CloudFilesException $e ) { // some other exception?
}
/**
- * Load a list of objects that belong under $dir into stat cache
- * and return a list of the names of the objects in the same order.
+ * Build a list of file objects, filtering out any directories
+ * and extracting any stat info if provided in $objects (for CF_Objects)
*
* @param array $params Parameters for getDirectoryList()
* @param string $dir Resolved container directory path
- * @param array $cfObjects List of CF_Object items
- * @return array List of object names
+ * @param array $objects List of CF_Object items or object names
+ * @return array List of (names,stat array or null) entries
*/
- private function loadObjectListing( array $params, $dir, array $cfObjects ) {
+ private function buildFileObjectListing( array $params, $dir, array $objects ) {
$names = array();
- $storageDir = rtrim( $params['dir'], '/' );
- $suffixStart = ( $dir === '' ) ? 0 : strlen( $dir ) + 1; // size of "path/to/dir/"
- // Iterate over the list *backwards* as this primes the stat cache, which is LRU.
- // If this fills the cache and the caller stats an uncached file before stating
- // the ones on the listing, there would be zero cache hits if this went forwards.
- for ( end( $cfObjects ); key( $cfObjects ) !== null; prev( $cfObjects ) ) {
- $object = current( $cfObjects );
- $path = "{$storageDir}/" . substr( $object->name, $suffixStart );
- $val = array(
- // Convert various random Swift dates to TS_MW
- 'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
- 'size' => (int)$object->content_length,
- 'latest' => false // eventually consistent
- );
- $this->cheapCache->set( $path, 'stat', $val );
- $names[] = $object->name;
+ foreach ( $objects as $object ) {
+ if ( is_object( $object ) ) {
+ $stat = array(
+ // Convert various random Swift dates to TS_MW
+ 'mtime' => $this->convertSwiftDate( $object->last_modified, TS_MW ),
+ 'size' => (int)$object->content_length,
+ 'latest' => false // eventually consistent
+ );
+ $names[] = array( $object->name, $stat );
+ } elseif ( substr( $object, -1 ) !== '/' ) {
+ // Omit directories, which end in '/' in listings
+ $names[] = array( $object, null );
+ }
}
- return array_reverse( $names ); // keep the paths in original order
+ return $names;
+ }
+
+ /**
+ * Do not call this function outside of SwiftFileBackendFileList
+ *
+ * @param string $path Storage path
+ * @param array $val Stat value
+ * @return void
+ */
+ public function loadListingStatInternal( $path, array $val ) {
+ $this->cheapCache->set( $path, 'stat', $val );
}
protected function doGetFileSha1base36( array $params ) {
* @ingroup FileBackend
*/
abstract class SwiftFileBackendList implements Iterator {
- /** @var Array */
+ /** @var Array List of path or (path,stat array) entries */
protected $bufferIter = array();
protected $bufferAfter = null; // string; list items *after* this path
protected $pos = 0; // integer
* @return string|bool String (relative path) or false
*/
public function current() {
- return substr( current( $this->bufferIter ), $this->suffixStart );
+ list( $path, $stat ) = current( $this->bufferIter );
+ $relPath = substr( $path, $this->suffixStart );
+ if ( is_array( $stat ) ) {
+ $storageDir = rtrim( $this->params['dir'], '/' );
+ $this->backend->loadListingStatInternal( "$storageDir/$path", $stat );
+ }
+ return $relPath;
}
/**
if ( !$this->db->tableExists( 'user_rights', __METHOD__ ) ) {
if ( $this->db->fieldExists( 'user', 'user_rights', __METHOD__ ) ) {
- $this->db->applyPatch(
+ $this->applyPatch(
'patch-user_rights.sql',
false,
'Upgrading from a 1.3 or older database? Breaking out user_rights for conversion'
}
foreach ( $this->mOutput->getLimitReportData() as $key => $value ) {
if ( wfRunHooks( 'ParserLimitReportFormat',
- array( $key, $value, &$limitReport, false, false )
+ array( $key, &$value, &$limitReport, false, false )
) ) {
$keyMsg = wfMessage( $key )->inLanguage( 'en' )->useDatabase( false );
$valueMsg = wfMessage( array( "$key-value-text", "$key-value" ) )
*/
class SpecialEditWatchlist extends UnlistedSpecialPage {
/**
- * Editing modes
+ * Editing modes. EDIT_CLEAR is no longer used; the "Clear" link scared people
+ * too much. Now it's passed on to the raw editor, from which it's very easy to clear.
*/
const EDIT_CLEAR = 1;
const EDIT_RAW = 2;
$mode = self::getMode( $this->getRequest(), $mode );
switch ( $mode ) {
- case self::EDIT_CLEAR:
- // The "Clear" link scared people too much.
- // Pass on to the raw editor, from which it's very easy to clear.
-
case self::EDIT_RAW:
$out->setPageTitle( $this->msg( 'watchlistedit-raw-title' ) );
$form = $this->getRawForm();
switch ( $mode ) {
case 'clear':
case self::EDIT_CLEAR:
- return self::EDIT_CLEAR;
case 'raw':
case self::EDIT_RAW:
return self::EDIT_RAW;
)
);
$out->addHtml(
- Xml::openElement( 'table', array( 'id' => 'mw-search-top-table', 'cellpadding' => 0, 'cellspacing' => 0 ) ) .
- Xml::openElement( 'tr' ) .
- Xml::openElement( 'td' ) . "\n" .
+ # This is an awful awful ID name. It's not a table, but we
+ # named it poorly from when this was a table so now we're
+ # stuck with it
+ Xml::openElement( 'div', array( 'id' => 'mw-search-top-table' ) ) .
$this->shortDialog( $term ) .
- Xml::closeElement( 'td' ) .
- Xml::closeElement( 'tr' ) .
- Xml::closeElement( 'table' )
+ Xml::closeElement( 'div' )
);
// Sometimes the search engine knows there are too many hits
$mode = SpecialEditWatchlist::getMode( $request, $par );
if ( $mode !== false ) {
- # TODO: localise?
- switch ( $mode ) {
- case SpecialEditWatchlist::EDIT_CLEAR:
- $mode = 'clear';
- break;
- case SpecialEditWatchlist::EDIT_RAW:
- $mode = 'raw';
- break;
- default:
- $mode = null;
+ if ( $mode === SpecialEditWatchlist::EDIT_RAW ) {
+ $title = SpecialPage::getTitleFor( 'EditWatchlist', 'raw' );
+ } else {
+ $title = SpecialPage::getTitleFor( 'EditWatchlist' );
}
- $title = SpecialPage::getTitleFor( 'EditWatchlist', $mode );
+
$output->redirect( $title->getLocalURL() );
return;
}
*/
public static function open( $fileName ) {
if ( self::haveExtension() ) {
- return new CdbReader_DBA( $fileName );
+ return new CdbReaderDBA( $fileName );
} else {
wfDebug( "Warning: no dba extension found, using emulation.\n" );
- return new CdbReader_PHP( $fileName );
+ return new CdbReaderPHP( $fileName );
}
}
*
* @param $fileName string
*
- * @return CdbWriter_DBA|CdbWriter_PHP
+ * @return CdbWriterDBA|CdbWriterPHP
*/
public static function open( $fileName ) {
if ( CdbReader::haveExtension() ) {
- return new CdbWriter_DBA( $fileName );
+ return new CdbWriterDBA( $fileName );
} else {
wfDebug( "Warning: no dba extension found, using emulation.\n" );
- return new CdbWriter_PHP( $fileName );
+ return new CdbWriterPHP( $fileName );
}
}
/**
* Reader class which uses the DBA extension
*/
-class CdbReader_DBA {
+class CdbReaderDBA {
var $handle;
function __construct( $fileName ) {
/**
* Writer class which uses the DBA extension
*/
-class CdbWriter_DBA {
+class CdbWriterDBA {
var $handle, $realFileName, $tmpFileName;
function __construct( $fileName ) {
--- /dev/null
+<?php
+/**
+ * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that
+ * appears in PHP 5.3. Changes are:
+ * * Error returns replaced with exceptions
+ * * Exception thrown if sizes or offsets are between 2GB and 4GB
+ * * Some variables renamed
+ *
+ * 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
+ */
+
+/**
+ * Common functions for readers and writers
+ */
+class CdbFunctions {
+ /**
+ * Take a modulo of a signed integer as if it were an unsigned integer.
+ * $b must be less than 0x40000000 and greater than 0
+ *
+ * @param $a
+ * @param $b
+ *
+ * @return int
+ */
+ public static function unsignedMod( $a, $b ) {
+ if ( $a & 0x80000000 ) {
+ $m = ( $a & 0x7fffffff ) % $b + 2 * ( 0x40000000 % $b );
+
+ return $m % $b;
+ } else {
+ return $a % $b;
+ }
+ }
+
+ /**
+ * Shift a signed integer right as if it were unsigned
+ * @param $a
+ * @param $b
+ * @return int
+ */
+ public static function unsignedShiftRight( $a, $b ) {
+ if ( $b == 0 ) {
+ return $a;
+ }
+ if ( $a & 0x80000000 ) {
+ return ( ( $a & 0x7fffffff ) >> $b ) | ( 0x40000000 >> ( $b - 1 ) );
+ } else {
+ return $a >> $b;
+ }
+ }
+
+ /**
+ * The CDB hash function.
+ *
+ * @param $s string
+ *
+ * @return
+ */
+ public static function hash( $s ) {
+ $h = 5381;
+ $len = strlen( $s );
+ for ( $i = 0; $i < $len; $i++ ) {
+ $h5 = ( $h << 5 ) & 0xffffffff;
+ // Do a 32-bit sum
+ // Inlined here for speed
+ $sum = ( $h & 0x3fffffff ) + ( $h5 & 0x3fffffff );
+ $h =
+ (
+ ( $sum & 0x40000000 ? 1 : 0 )
+ + ( $h & 0x80000000 ? 2 : 0 )
+ + ( $h & 0x40000000 ? 1 : 0 )
+ + ( $h5 & 0x80000000 ? 2 : 0 )
+ + ( $h5 & 0x40000000 ? 1 : 0 )
+ ) << 30
+ | ( $sum & 0x3fffffff );
+ $h ^= ord( $s[$i] );
+ $h &= 0xffffffff;
+ }
+
+ return $h;
+ }
+}
+
+/**
+ * CDB reader class
+ */
+class CdbReaderPHP extends CdbReader {
+ /** The filename */
+ var $fileName;
+
+ /** The file handle */
+ var $handle;
+
+ /* number of hash slots searched under this key */
+ var $loop;
+
+ /* initialized if loop is nonzero */
+ var $khash;
+
+ /* initialized if loop is nonzero */
+ var $kpos;
+
+ /* initialized if loop is nonzero */
+ var $hpos;
+
+ /* initialized if loop is nonzero */
+ var $hslots;
+
+ /* initialized if findNext() returns true */
+ var $dpos;
+
+ /* initialized if cdb_findnext() returns 1 */
+ var $dlen;
+
+ /**
+ * @param $fileName string
+ * @throws MWException
+ */
+ function __construct( $fileName ) {
+ $this->fileName = $fileName;
+ $this->handle = fopen( $fileName, 'rb' );
+ if ( !$this->handle ) {
+ throw new MWException( 'Unable to open CDB file "' . $this->fileName . '".' );
+ }
+ $this->findStart();
+ }
+
+ function close() {
+ if ( isset( $this->handle ) ) {
+ fclose( $this->handle );
+ }
+ unset( $this->handle );
+ }
+
+ /**
+ * @param $key
+ * @return bool|string
+ */
+ public function get( $key ) {
+ // strval is required
+ if ( $this->find( strval( $key ) ) ) {
+ return $this->read( $this->dlen, $this->dpos );
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * @param $key
+ * @param $pos
+ * @return bool
+ */
+ protected function match( $key, $pos ) {
+ $buf = $this->read( strlen( $key ), $pos );
+
+ return $buf === $key;
+ }
+
+ protected function findStart() {
+ $this->loop = 0;
+ }
+
+ /**
+ * @throws MWException
+ * @param $length
+ * @param $pos
+ * @return string
+ */
+ protected function read( $length, $pos ) {
+ if ( fseek( $this->handle, $pos ) == -1 ) {
+ // This can easily happen if the internal pointers are incorrect
+ throw new MWException(
+ 'Seek failed, file "' . $this->fileName . '" may be corrupted.' );
+ }
+
+ if ( $length == 0 ) {
+ return '';
+ }
+
+ $buf = fread( $this->handle, $length );
+ if ( $buf === false || strlen( $buf ) !== $length ) {
+ throw new MWException(
+ 'Read from CDB file failed, file "' . $this->fileName . '" may be corrupted.' );
+ }
+
+ return $buf;
+ }
+
+ /**
+ * Unpack an unsigned integer and throw an exception if it needs more than 31 bits
+ * @param $s
+ * @throws MWException
+ * @return mixed
+ */
+ protected function unpack31( $s ) {
+ $data = unpack( 'V', $s );
+ if ( $data[1] > 0x7fffffff ) {
+ throw new MWException(
+ 'Error in CDB file "' . $this->fileName . '", integer too big.' );
+ }
+
+ return $data[1];
+ }
+
+ /**
+ * Unpack a 32-bit signed integer
+ * @param $s
+ * @return int
+ */
+ protected function unpackSigned( $s ) {
+ $data = unpack( 'va/vb', $s );
+
+ return $data['a'] | ( $data['b'] << 16 );
+ }
+
+ /**
+ * @param $key
+ * @return bool
+ */
+ protected function findNext( $key ) {
+ if ( !$this->loop ) {
+ $u = CdbFunctions::hash( $key );
+ $buf = $this->read( 8, ( $u << 3 ) & 2047 );
+ $this->hslots = $this->unpack31( substr( $buf, 4 ) );
+ if ( !$this->hslots ) {
+ return false;
+ }
+ $this->hpos = $this->unpack31( substr( $buf, 0, 4 ) );
+ $this->khash = $u;
+ $u = CdbFunctions::unsignedShiftRight( $u, 8 );
+ $u = CdbFunctions::unsignedMod( $u, $this->hslots );
+ $u <<= 3;
+ $this->kpos = $this->hpos + $u;
+ }
+
+ while ( $this->loop < $this->hslots ) {
+ $buf = $this->read( 8, $this->kpos );
+ $pos = $this->unpack31( substr( $buf, 4 ) );
+ if ( !$pos ) {
+ return false;
+ }
+ $this->loop += 1;
+ $this->kpos += 8;
+ if ( $this->kpos == $this->hpos + ( $this->hslots << 3 ) ) {
+ $this->kpos = $this->hpos;
+ }
+ $u = $this->unpackSigned( substr( $buf, 0, 4 ) );
+ if ( $u === $this->khash ) {
+ $buf = $this->read( 8, $pos );
+ $keyLen = $this->unpack31( substr( $buf, 0, 4 ) );
+ if ( $keyLen == strlen( $key ) && $this->match( $key, $pos + 8 ) ) {
+ // Found
+ $this->dlen = $this->unpack31( substr( $buf, 4 ) );
+ $this->dpos = $pos + 8 + $keyLen;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @param $key
+ * @return bool
+ */
+ protected function find( $key ) {
+ $this->findStart();
+
+ return $this->findNext( $key );
+ }
+}
+
+/**
+ * CDB writer class
+ */
+class CdbWriterPHP extends CdbWriter {
+ var $handle, $realFileName, $tmpFileName;
+
+ var $hplist;
+ var $numentries, $pos;
+
+ /**
+ * @param $fileName string
+ */
+ function __construct( $fileName ) {
+ $this->realFileName = $fileName;
+ $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff );
+ $this->handle = fopen( $this->tmpFileName, 'wb' );
+ if ( !$this->handle ) {
+ $this->throwException(
+ 'Unable to open CDB file "' . $this->tmpFileName . '" for write.' );
+ }
+ $this->hplist = array();
+ $this->numentries = 0;
+ $this->pos = 2048; // leaving space for the pointer array, 256 * 8
+ if ( fseek( $this->handle, $this->pos ) == -1 ) {
+ $this->throwException( 'fseek failed in file "' . $this->tmpFileName . '".' );
+ }
+ }
+
+ function __destruct() {
+ if ( isset( $this->handle ) ) {
+ $this->close();
+ }
+ }
+
+ /**
+ * @param $key
+ * @param $value
+ * @return
+ */
+ public function set( $key, $value ) {
+ if ( strval( $key ) === '' ) {
+ // DBA cross-check hack
+ return;
+ }
+ $this->addbegin( strlen( $key ), strlen( $value ) );
+ $this->write( $key );
+ $this->write( $value );
+ $this->addend( strlen( $key ), strlen( $value ), CdbFunctions::hash( $key ) );
+ }
+
+ /**
+ * @throws MWException
+ */
+ public function close() {
+ $this->finish();
+ if ( isset( $this->handle ) ) {
+ fclose( $this->handle );
+ }
+ if ( wfIsWindows() && file_exists( $this->realFileName ) ) {
+ unlink( $this->realFileName );
+ }
+ if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
+ $this->throwException( 'Unable to move the new CDB file into place.' );
+ }
+ unset( $this->handle );
+ }
+
+ /**
+ * @throws MWException
+ * @param $buf
+ */
+ protected function write( $buf ) {
+ $len = fwrite( $this->handle, $buf );
+ if ( $len !== strlen( $buf ) ) {
+ $this->throwException( 'Error writing to CDB file "' . $this->tmpFileName . '".' );
+ }
+ }
+
+ /**
+ * @throws MWException
+ * @param $len
+ */
+ protected function posplus( $len ) {
+ $newpos = $this->pos + $len;
+ if ( $newpos > 0x7fffffff ) {
+ $this->throwException(
+ 'A value in the CDB file "' . $this->tmpFileName . '" is too large.' );
+ }
+ $this->pos = $newpos;
+ }
+
+ /**
+ * @param $keylen
+ * @param $datalen
+ * @param $h
+ */
+ protected function addend( $keylen, $datalen, $h ) {
+ $this->hplist[] = array(
+ 'h' => $h,
+ 'p' => $this->pos
+ );
+
+ $this->numentries++;
+ $this->posplus( 8 );
+ $this->posplus( $keylen );
+ $this->posplus( $datalen );
+ }
+
+ /**
+ * @throws MWException
+ * @param $keylen
+ * @param $datalen
+ */
+ protected function addbegin( $keylen, $datalen ) {
+ if ( $keylen > 0x7fffffff ) {
+ $this->throwException( 'Key length too long in file "' . $this->tmpFileName . '".' );
+ }
+ if ( $datalen > 0x7fffffff ) {
+ $this->throwException( 'Data length too long in file "' . $this->tmpFileName . '".' );
+ }
+ $buf = pack( 'VV', $keylen, $datalen );
+ $this->write( $buf );
+ }
+
+ /**
+ * @throws MWException
+ */
+ protected function finish() {
+ // Hack for DBA cross-check
+ $this->hplist = array_reverse( $this->hplist );
+
+ // Calculate the number of items that will be in each hashtable
+ $counts = array_fill( 0, 256, 0 );
+ foreach ( $this->hplist as $item ) {
+ ++$counts[255 & $item['h']];
+ }
+
+ // Fill in $starts with the *end* indexes
+ $starts = array();
+ $pos = 0;
+ for ( $i = 0; $i < 256; ++$i ) {
+ $pos += $counts[$i];
+ $starts[$i] = $pos;
+ }
+
+ // Excessively clever and indulgent code to simultaneously fill $packedTables
+ // with the packed hashtables, and adjust the elements of $starts
+ // to actually point to the starts instead of the ends.
+ $packedTables = array_fill( 0, $this->numentries, false );
+ foreach ( $this->hplist as $item ) {
+ $packedTables[--$starts[255 & $item['h']]] = $item;
+ }
+
+ $final = '';
+ for ( $i = 0; $i < 256; ++$i ) {
+ $count = $counts[$i];
+
+ // The size of the hashtable will be double the item count.
+ // The rest of the slots will be empty.
+ $len = $count + $count;
+ $final .= pack( 'VV', $this->pos, $len );
+
+ $hashtable = array();
+ for ( $u = 0; $u < $len; ++$u ) {
+ $hashtable[$u] = array( 'h' => 0, 'p' => 0 );
+ }
+
+ // Fill the hashtable, using the next empty slot if the hashed slot
+ // is taken.
+ for ( $u = 0; $u < $count; ++$u ) {
+ $hp = $packedTables[$starts[$i] + $u];
+ $where = CdbFunctions::unsignedMod(
+ CdbFunctions::unsignedShiftRight( $hp['h'], 8 ), $len );
+ while ( $hashtable[$where]['p'] ) {
+ if ( ++$where == $len ) {
+ $where = 0;
+ }
+ }
+ $hashtable[$where] = $hp;
+ }
+
+ // Write the hashtable
+ for ( $u = 0; $u < $len; ++$u ) {
+ $buf = pack( 'vvV',
+ $hashtable[$u]['h'] & 0xffff,
+ CdbFunctions::unsignedShiftRight( $hashtable[$u]['h'], 16 ),
+ $hashtable[$u]['p'] );
+ $this->write( $buf );
+ $this->posplus( 8 );
+ }
+ }
+
+ // Write the pointer array at the start of the file
+ rewind( $this->handle );
+ if ( ftell( $this->handle ) != 0 ) {
+ $this->throwException( 'Error rewinding to start of file "' . $this->tmpFileName . '".' );
+ }
+ $this->write( $final );
+ }
+
+ /**
+ * Clean up the temp file and throw an exception
+ *
+ * @param $msg string
+ * @throws MWException
+ */
+ protected function throwException( $msg ) {
+ if ( $this->handle ) {
+ fclose( $this->handle );
+ unlink( $this->tmpFileName );
+ }
+ throw new MWException( $msg );
+ }
+}
+++ /dev/null
-<?php
-/**
- * This is a port of D.J. Bernstein's CDB to PHP. It's based on the copy that
- * appears in PHP 5.3. Changes are:
- * * Error returns replaced with exceptions
- * * Exception thrown if sizes or offsets are between 2GB and 4GB
- * * Some variables renamed
- *
- * 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
- */
-
-/**
- * Common functions for readers and writers
- */
-class CdbFunctions {
- /**
- * Take a modulo of a signed integer as if it were an unsigned integer.
- * $b must be less than 0x40000000 and greater than 0
- *
- * @param $a
- * @param $b
- *
- * @return int
- */
- public static function unsignedMod( $a, $b ) {
- if ( $a & 0x80000000 ) {
- $m = ( $a & 0x7fffffff ) % $b + 2 * ( 0x40000000 % $b );
-
- return $m % $b;
- } else {
- return $a % $b;
- }
- }
-
- /**
- * Shift a signed integer right as if it were unsigned
- * @param $a
- * @param $b
- * @return int
- */
- public static function unsignedShiftRight( $a, $b ) {
- if ( $b == 0 ) {
- return $a;
- }
- if ( $a & 0x80000000 ) {
- return ( ( $a & 0x7fffffff ) >> $b ) | ( 0x40000000 >> ( $b - 1 ) );
- } else {
- return $a >> $b;
- }
- }
-
- /**
- * The CDB hash function.
- *
- * @param $s string
- *
- * @return
- */
- public static function hash( $s ) {
- $h = 5381;
- for ( $i = 0; $i < strlen( $s ); $i++ ) {
- $h5 = ( $h << 5 ) & 0xffffffff;
- // Do a 32-bit sum
- // Inlined here for speed
- $sum = ( $h & 0x3fffffff ) + ( $h5 & 0x3fffffff );
- $h =
- (
- ( $sum & 0x40000000 ? 1 : 0 )
- + ( $h & 0x80000000 ? 2 : 0 )
- + ( $h & 0x40000000 ? 1 : 0 )
- + ( $h5 & 0x80000000 ? 2 : 0 )
- + ( $h5 & 0x40000000 ? 1 : 0 )
- ) << 30
- | ( $sum & 0x3fffffff );
- $h ^= ord( $s[$i] );
- $h &= 0xffffffff;
- }
-
- return $h;
- }
-}
-
-/**
- * CDB reader class
- */
-class CdbReader_PHP extends CdbReader {
- /** The filename */
- var $fileName;
-
- /** The file handle */
- var $handle;
-
- /* number of hash slots searched under this key */
- var $loop;
-
- /* initialized if loop is nonzero */
- var $khash;
-
- /* initialized if loop is nonzero */
- var $kpos;
-
- /* initialized if loop is nonzero */
- var $hpos;
-
- /* initialized if loop is nonzero */
- var $hslots;
-
- /* initialized if findNext() returns true */
- var $dpos;
-
- /* initialized if cdb_findnext() returns 1 */
- var $dlen;
-
- /**
- * @param $fileName string
- * @throws MWException
- */
- function __construct( $fileName ) {
- $this->fileName = $fileName;
- $this->handle = fopen( $fileName, 'rb' );
- if ( !$this->handle ) {
- throw new MWException( 'Unable to open CDB file "' . $this->fileName . '".' );
- }
- $this->findStart();
- }
-
- function close() {
- if ( isset( $this->handle ) ) {
- fclose( $this->handle );
- }
- unset( $this->handle );
- }
-
- /**
- * @param $key
- * @return bool|string
- */
- public function get( $key ) {
- // strval is required
- if ( $this->find( strval( $key ) ) ) {
- return $this->read( $this->dlen, $this->dpos );
- } else {
- return false;
- }
- }
-
- /**
- * @param $key
- * @param $pos
- * @return bool
- */
- protected function match( $key, $pos ) {
- $buf = $this->read( strlen( $key ), $pos );
-
- return $buf === $key;
- }
-
- protected function findStart() {
- $this->loop = 0;
- }
-
- /**
- * @throws MWException
- * @param $length
- * @param $pos
- * @return string
- */
- protected function read( $length, $pos ) {
- if ( fseek( $this->handle, $pos ) == -1 ) {
- // This can easily happen if the internal pointers are incorrect
- throw new MWException(
- 'Seek failed, file "' . $this->fileName . '" may be corrupted.' );
- }
-
- if ( $length == 0 ) {
- return '';
- }
-
- $buf = fread( $this->handle, $length );
- if ( $buf === false || strlen( $buf ) !== $length ) {
- throw new MWException(
- 'Read from CDB file failed, file "' . $this->fileName . '" may be corrupted.' );
- }
-
- return $buf;
- }
-
- /**
- * Unpack an unsigned integer and throw an exception if it needs more than 31 bits
- * @param $s
- * @throws MWException
- * @return mixed
- */
- protected function unpack31( $s ) {
- $data = unpack( 'V', $s );
- if ( $data[1] > 0x7fffffff ) {
- throw new MWException(
- 'Error in CDB file "' . $this->fileName . '", integer too big.' );
- }
-
- return $data[1];
- }
-
- /**
- * Unpack a 32-bit signed integer
- * @param $s
- * @return int
- */
- protected function unpackSigned( $s ) {
- $data = unpack( 'va/vb', $s );
-
- return $data['a'] | ( $data['b'] << 16 );
- }
-
- /**
- * @param $key
- * @return bool
- */
- protected function findNext( $key ) {
- if ( !$this->loop ) {
- $u = CdbFunctions::hash( $key );
- $buf = $this->read( 8, ( $u << 3 ) & 2047 );
- $this->hslots = $this->unpack31( substr( $buf, 4 ) );
- if ( !$this->hslots ) {
- return false;
- }
- $this->hpos = $this->unpack31( substr( $buf, 0, 4 ) );
- $this->khash = $u;
- $u = CdbFunctions::unsignedShiftRight( $u, 8 );
- $u = CdbFunctions::unsignedMod( $u, $this->hslots );
- $u <<= 3;
- $this->kpos = $this->hpos + $u;
- }
-
- while ( $this->loop < $this->hslots ) {
- $buf = $this->read( 8, $this->kpos );
- $pos = $this->unpack31( substr( $buf, 4 ) );
- if ( !$pos ) {
- return false;
- }
- $this->loop += 1;
- $this->kpos += 8;
- if ( $this->kpos == $this->hpos + ( $this->hslots << 3 ) ) {
- $this->kpos = $this->hpos;
- }
- $u = $this->unpackSigned( substr( $buf, 0, 4 ) );
- if ( $u === $this->khash ) {
- $buf = $this->read( 8, $pos );
- $keyLen = $this->unpack31( substr( $buf, 0, 4 ) );
- if ( $keyLen == strlen( $key ) && $this->match( $key, $pos + 8 ) ) {
- // Found
- $this->dlen = $this->unpack31( substr( $buf, 4 ) );
- $this->dpos = $pos + 8 + $keyLen;
-
- return true;
- }
- }
- }
-
- return false;
- }
-
- /**
- * @param $key
- * @return bool
- */
- protected function find( $key ) {
- $this->findStart();
-
- return $this->findNext( $key );
- }
-}
-
-/**
- * CDB writer class
- */
-class CdbWriter_PHP extends CdbWriter {
- var $handle, $realFileName, $tmpFileName;
-
- var $hplist;
- var $numentries, $pos;
-
- /**
- * @param $fileName string
- */
- function __construct( $fileName ) {
- $this->realFileName = $fileName;
- $this->tmpFileName = $fileName . '.tmp.' . mt_rand( 0, 0x7fffffff );
- $this->handle = fopen( $this->tmpFileName, 'wb' );
- if ( !$this->handle ) {
- $this->throwException(
- 'Unable to open CDB file "' . $this->tmpFileName . '" for write.' );
- }
- $this->hplist = array();
- $this->numentries = 0;
- $this->pos = 2048; // leaving space for the pointer array, 256 * 8
- if ( fseek( $this->handle, $this->pos ) == -1 ) {
- $this->throwException( 'fseek failed in file "' . $this->tmpFileName . '".' );
- }
- }
-
- function __destruct() {
- if ( isset( $this->handle ) ) {
- $this->close();
- }
- }
-
- /**
- * @param $key
- * @param $value
- * @return
- */
- public function set( $key, $value ) {
- if ( strval( $key ) === '' ) {
- // DBA cross-check hack
- return;
- }
- $this->addbegin( strlen( $key ), strlen( $value ) );
- $this->write( $key );
- $this->write( $value );
- $this->addend( strlen( $key ), strlen( $value ), CdbFunctions::hash( $key ) );
- }
-
- /**
- * @throws MWException
- */
- public function close() {
- $this->finish();
- if ( isset( $this->handle ) ) {
- fclose( $this->handle );
- }
- if ( wfIsWindows() && file_exists( $this->realFileName ) ) {
- unlink( $this->realFileName );
- }
- if ( !rename( $this->tmpFileName, $this->realFileName ) ) {
- $this->throwException( 'Unable to move the new CDB file into place.' );
- }
- unset( $this->handle );
- }
-
- /**
- * @throws MWException
- * @param $buf
- */
- protected function write( $buf ) {
- $len = fwrite( $this->handle, $buf );
- if ( $len !== strlen( $buf ) ) {
- $this->throwException( 'Error writing to CDB file "' . $this->tmpFileName . '".' );
- }
- }
-
- /**
- * @throws MWException
- * @param $len
- */
- protected function posplus( $len ) {
- $newpos = $this->pos + $len;
- if ( $newpos > 0x7fffffff ) {
- $this->throwException(
- 'A value in the CDB file "' . $this->tmpFileName . '" is too large.' );
- }
- $this->pos = $newpos;
- }
-
- /**
- * @param $keylen
- * @param $datalen
- * @param $h
- */
- protected function addend( $keylen, $datalen, $h ) {
- $this->hplist[] = array(
- 'h' => $h,
- 'p' => $this->pos
- );
-
- $this->numentries++;
- $this->posplus( 8 );
- $this->posplus( $keylen );
- $this->posplus( $datalen );
- }
-
- /**
- * @throws MWException
- * @param $keylen
- * @param $datalen
- */
- protected function addbegin( $keylen, $datalen ) {
- if ( $keylen > 0x7fffffff ) {
- $this->throwException( 'Key length too long in file "' . $this->tmpFileName . '".' );
- }
- if ( $datalen > 0x7fffffff ) {
- $this->throwException( 'Data length too long in file "' . $this->tmpFileName . '".' );
- }
- $buf = pack( 'VV', $keylen, $datalen );
- $this->write( $buf );
- }
-
- /**
- * @throws MWException
- */
- protected function finish() {
- // Hack for DBA cross-check
- $this->hplist = array_reverse( $this->hplist );
-
- // Calculate the number of items that will be in each hashtable
- $counts = array_fill( 0, 256, 0 );
- foreach ( $this->hplist as $item ) {
- ++$counts[255 & $item['h']];
- }
-
- // Fill in $starts with the *end* indexes
- $starts = array();
- $pos = 0;
- for ( $i = 0; $i < 256; ++$i ) {
- $pos += $counts[$i];
- $starts[$i] = $pos;
- }
-
- // Excessively clever and indulgent code to simultaneously fill $packedTables
- // with the packed hashtables, and adjust the elements of $starts
- // to actually point to the starts instead of the ends.
- $packedTables = array_fill( 0, $this->numentries, false );
- foreach ( $this->hplist as $item ) {
- $packedTables[--$starts[255 & $item['h']]] = $item;
- }
-
- $final = '';
- for ( $i = 0; $i < 256; ++$i ) {
- $count = $counts[$i];
-
- // The size of the hashtable will be double the item count.
- // The rest of the slots will be empty.
- $len = $count + $count;
- $final .= pack( 'VV', $this->pos, $len );
-
- $hashtable = array();
- for ( $u = 0; $u < $len; ++$u ) {
- $hashtable[$u] = array( 'h' => 0, 'p' => 0 );
- }
-
- // Fill the hashtable, using the next empty slot if the hashed slot
- // is taken.
- for ( $u = 0; $u < $count; ++$u ) {
- $hp = $packedTables[$starts[$i] + $u];
- $where = CdbFunctions::unsignedMod(
- CdbFunctions::unsignedShiftRight( $hp['h'], 8 ), $len );
- while ( $hashtable[$where]['p'] ) {
- if ( ++$where == $len ) {
- $where = 0;
- }
- }
- $hashtable[$where] = $hp;
- }
-
- // Write the hashtable
- for ( $u = 0; $u < $len; ++$u ) {
- $buf = pack( 'vvV',
- $hashtable[$u]['h'] & 0xffff,
- CdbFunctions::unsignedShiftRight( $hashtable[$u]['h'], 16 ),
- $hashtable[$u]['p'] );
- $this->write( $buf );
- $this->posplus( 8 );
- }
- }
-
- // Write the pointer array at the start of the file
- rewind( $this->handle );
- if ( ftell( $this->handle ) != 0 ) {
- $this->throwException( 'Error rewinding to start of file "' . $this->tmpFileName . '".' );
- }
- $this->write( $final );
- }
-
- /**
- * Clean up the temp file and throw an exception
- *
- * @param $msg string
- * @throws MWException
- */
- protected function throwException( $msg ) {
- if ( $this->handle ) {
- fclose( $this->handle );
- unlink( $this->tmpFileName );
- }
- throw new MWException( $msg );
- }
-}
$this->nextToken();
}
$regionEnd = $path['endByte']; // past the end
- for ( $offset = 0; $offset < count( $this->tokens ) - $this->pos; $offset++ ) {
+ $count = count( $this->tokens );
+ for ( $offset = 0; $offset < $count - $this->pos; $offset++ ) {
$token = $this->getTokenAhead( $offset );
if ( !$token->isSkip() ) {
break;
*/
class MWCryptRand {
-
/**
* Minimum number of iterations we want to make in our drift calculations.
*/
$files[] = __DIR__;
$files[] = dirname( __DIR__ );
- // The config file is likely the most often edited file we know should be around
- // so include its stat info into the state.
- // The constant with its location will almost always be defined, as WebStart.php defines
- // MW_CONFIG_FILE to $IP/LocalSettings.php unless being configured with MW_CONFIG_CALLBACK (eg. the installer)
+ // The config file is likely the most often edited file we know should
+ // be around so include its stat info into the state.
+ // The constant with its location will almost always be defined, as
+ // WebStart.php defines MW_CONFIG_FILE to $IP/LocalSettings.php unless
+ // being configured with MW_CONFIG_CALLBACK (e.g. the installer).
if ( defined( 'MW_CONFIG_FILE' ) ) {
$files[] = MW_CONFIG_FILE;
}
* @author Tim Starling
*/
protected function driftHash( $data ) {
- // Minimum number of iterations (to avoid slow operations causing the loop to gather little entropy)
+ // Minimum number of iterations (to avoid slow operations causing the
+ // loop to gather little entropy)
$minIterations = self::MIN_ITERATIONS;
// Duration of time to spend doing calculations (in seconds)
$duration = ( self::MSEC_PER_BYTE / 1000 ) * $this->hashLength();
public function realGenerate( $bytes, $forceStrong = false ) {
wfProfileIn( __METHOD__ );
- wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " . wfGetAllCallers( 5 ) . "\n" );
+ wfDebug( __METHOD__ . ": Generating cryptographic random bytes for " .
+ wfGetAllCallers( 5 ) . "\n" );
$bytes = floor( $bytes );
static $buffer = '';
wfDebug( __METHOD__ . ": mcrypt_create_iv returned false.\n" );
} else {
$buffer .= $iv;
- wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) . " bytes of randomness.\n" );
+ wfDebug( __METHOD__ . ": mcrypt_create_iv generated " . strlen( $iv ) .
+ " bytes of randomness.\n" );
}
wfProfileOut( __METHOD__ . '-mcrypt' );
}
}
if ( strlen( $buffer ) < $bytes ) {
- // If available make use of openssl's random_pseudo_bytes method to attempt to generate randomness.
- // However don't do this on Windows with PHP < 5.3.4 due to a bug:
+ // If available make use of openssl's random_pseudo_bytes method to
+ // attempt to generate randomness. However don't do this on Windows
+ // with PHP < 5.3.4 due to a bug:
// http://stackoverflow.com/questions/1940168/openssl-random-pseudo-bytes-is-slow-php
// http://git.php.net/?p=php-src.git;a=commitdiff;h=cd62a70863c261b07f6dadedad9464f7e213cad5
if ( function_exists( 'openssl_random_pseudo_bytes' )
wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes returned false.\n" );
} else {
$buffer .= $openssl_bytes;
- wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes generated " . strlen( $openssl_bytes ) . " bytes of " . ( $openssl_strong ? "strong" : "weak" ) . " randomness.\n" );
+ wfDebug( __METHOD__ . ": openssl_random_pseudo_bytes generated " .
+ strlen( $openssl_bytes ) . " bytes of " .
+ ( $openssl_strong ? "strong" : "weak" ) . " randomness.\n" );
}
if ( strlen( $buffer ) >= $bytes ) {
// openssl tells us if the random source was strong, if some of our data was generated
}
// Only read from urandom if we can control the buffer size or were passed forceStrong
- if ( strlen( $buffer ) < $bytes && ( function_exists( 'stream_set_read_buffer' ) || $forceStrong ) ) {
+ if ( strlen( $buffer ) < $bytes &&
+ ( function_exists( 'stream_set_read_buffer' ) || $forceStrong )
+ ) {
wfProfileIn( __METHOD__ . '-fopen-urandom' );
$rem = $bytes - strlen( $buffer );
if ( !function_exists( 'stream_set_read_buffer' ) && $forceStrong ) {
- wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom without control over the buffer size.\n" );
+ wfDebug( __METHOD__ . ": Was forced to read from /dev/urandom " .
+ "without control over the buffer size.\n" );
}
// /dev/urandom is generally considered the best possible commonly
// available random source, and is available on most *nix systems.
$random_bytes = fread( $urandom, max( $chunk_size, $rem ) );
$buffer .= $random_bytes;
fclose( $urandom );
- wfDebug( __METHOD__ . ": /dev/urandom generated " . strlen( $random_bytes ) . " bytes of randomness.\n" );
+ wfDebug( __METHOD__ . ": /dev/urandom generated " . strlen( $random_bytes ) .
+ " bytes of randomness.\n" );
+
if ( strlen( $buffer ) >= $bytes ) {
// urandom is always strong, set to true if all our data was generated using it
$this->strong = true;
// We hash the random state with more salt to avoid the state from leaking
// out and being used to predict the /randomness/ that follows.
if ( strlen( $buffer ) < $bytes ) {
- wfDebug( __METHOD__ . ": Falling back to using a pseudo random state to generate randomness.\n" );
+ wfDebug( __METHOD__ .
+ ": Falling back to using a pseudo random state to generate randomness.\n" );
}
while ( strlen( $buffer ) < $bytes ) {
wfProfileIn( __METHOD__ . '-fallback' );
$generated = substr( $buffer, 0, $bytes );
$buffer = substr( $buffer, $bytes );
- wfDebug( __METHOD__ . ": " . strlen( $buffer ) . " bytes of randomness leftover in the buffer.\n" );
+ wfDebug( __METHOD__ . ": " . strlen( $buffer ) .
+ " bytes of randomness leftover in the buffer.\n" );
wfProfileOut( __METHOD__ );
* A collection of static methods to play with strings.
*/
class StringUtils {
-
/**
* Test whether a string is valid UTF-8.
*
* @throws MWException
* @return string
*/
- static function delimiterReplaceCallback( $startDelim, $endDelim, $callback, $subject, $flags = '' ) {
+ static function delimiterReplaceCallback( $startDelim, $endDelim, $callback,
+ $subject, $flags = ''
+ ) {
$inputPos = 0;
$outputPos = 0;
$output = '';
* StringUtils::delimiterReplaceCallback()
*/
class Replacer {
-
/**
* @return array
*/
* Class to replace regex matches with a string similar to that used in preg_replace()
*/
class RegexlikeReplacer extends Replacer {
- var $r;
+ private $r;
/**
* @param string $r
* Class to perform secondary replacement within each replacement string
*/
class DoubleReplacer extends Replacer {
-
/**
* @param $from
* @param $to
* Class to perform replacement based on a simple hashtable lookup
*/
class HashtableReplacer extends Replacer {
- var $table, $index;
+ private $table, $index;
/**
* @param $table
* Supports lazy initialisation of FSS resource
*/
class ReplacementArray {
- /*mostly private*/ var $data = false;
- /*mostly private*/ var $fss = false;
+ private $data = false;
+ private $fss = false;
/**
* Create an object with the specified replacement array
*/
class ExplodeIterator implements Iterator {
// The subject string
- var $subject, $subjectLength;
+ private $subject, $subjectLength;
// The delimiter
- var $delim, $delimLength;
+ private $delim, $delimLength;
// The position of the start of the line
- var $curPos;
+ private $curPos;
// The position after the end of the next delimiter
- var $endPos;
+ private $endPos;
// The current token
- var $current;
+ private $current;
/**
* Construct a DelimIterator
}
/** The file name */
- var $fileName;
+ protected $fileName;
/** The opened file resource */
- var $file;
+ protected $file;
/** The cached length of the file, or null if it has not been loaded yet. */
- var $fileLength;
+ protected $fileLength;
/** A segmented cache of the file contents */
- var $buffer;
+ protected $buffer;
/** The file data callback */
- var $callback;
+ protected $callback;
/** The ZIP64 mode */
- var $zip64 = false;
+ protected $zip64 = false;
/** Stored headers */
- var $eocdr, $eocdr64, $eocdr64Locator;
+ protected $eocdr, $eocdr64, $eocdr64Locator;
- var $data;
+ protected $data;
/** The "extra field" ID for ZIP64 central directory entries */
const ZIP64_EXTRA_HEADER = 0x0001;
);
$structSize = $this->getStructSize( $info );
- $block = $this->getBlock( $this->getFileLength() - $this->eocdr['EOCDR size']
- - $structSize, $structSize );
+ $start = $this->getFileLength() - $this->eocdr['EOCDR size'] - $structSize;
+ $block = $this->getBlock( $start, $structSize );
$this->eocdr64Locator = $data = $this->unpack( $block, $info );
if ( $data['signature'] !== "PK\x06\x07" ) {
* Internal exception class. Will be caught by private code.
*/
class ZipDirectoryReaderError extends Exception {
- var $errorCode;
+ protected $errorCode;
function __construct( $code ) {
$this->errorCode = $code;
$nlink = htmlspecialchars( $next );
} else {
$nlink = $this->numLink( $title, $offset + $limit, $limit,
- $query, $next, 'prevn-title', 'mw-nextlink' );
+ $query, $next, 'nextn-title', 'mw-nextlink' );
}
# Make links to set number of items per page
$messages = array(
# User preference toggles
-'tog-underline' => 'Bôh garéh yup bak hubông:',
+'tog-underline' => 'Bôh garéh yup peunawôt:',
'tog-justify' => 'Peurata paragraf',
-'tog-hideminor' => 'Peusom neuandam bacut bak neuubah paléng barô',
-'tog-hidepatrolled' => 'Peusom neuandam teupatroli bak neuubah paléng barô',
-'tog-newpageshidepatrolled' => 'Peusom ôn teupatroli nibak dapeuta ôn barô',
-'tog-extendwatchlist' => 'Peuhah dapeuta keunalön keu peuleumah ban dum neuubah, kon nyang paléng barô mantöng',
+'tog-hideminor' => 'Peusom neuandam bacut bak neuubah barô',
+'tog-hidepatrolled' => 'Peusom neuandam teurunda bak neuubah barô',
+'tog-newpageshidepatrolled' => 'Peusom laman teurunda nibak dapeuta ôn barô',
+'tog-extendwatchlist' => 'Peuhah dapeuta keunalön keu peuleumah ban dum neuubah, kon nyang barô mantöng',
'tog-usenewrc' => 'Peusaho neuandam bak neuleumah neuubah barô ngon dapeuta keunalon meunurot ôn',
'tog-numberheadings' => 'Bôh numbô nan keudroë',
'tog-showtoolbar' => 'Peuleumah bateuëng alat andam',
'otherlanguages' => 'Bahsa la’én',
'redirectedfrom' => '(Geupeupinah nibak $1)',
'redirectpagesub' => 'Ôn peuninah',
-'lastmodifiedat' => 'Ôn nyoë seuneulheuëh geuubah bak $2, $1.',
+'lastmodifiedat' => 'Laman nyoë seuneulheuëh geuubah bak $1 poh $2.',
'viewcount' => 'On nyoe ka geusaweue {{PLURAL:$1|sigo|$sigo}}.<br />',
'protectedpage' => 'Ôn teupeulindông',
'jumpto' => 'Grôp u:',
# Short words for each namespace, by default used in the namespace tab in monobook
'nstab-main' => 'Ôn',
-'nstab-user' => 'Ureuëng nguy',
+'nstab-user' => 'Ureuëng ngui',
'nstab-media' => 'Ôn media',
'nstab-special' => 'Kusuih',
'nstab-project' => 'Buët ôn',
'userlogin-yourpassword' => 'Lageuëm rahsia',
'userlogin-yourpassword-ph' => 'Pasoë lageuëm rahsia droëneuh',
'createacct-yourpassword-ph' => 'Pasoë lageuëm rahsia',
-'yourpasswordagain' => 'Pasoë lom lageuëm:',
+'yourpasswordagain' => 'Pasoë lom lageuëm rahsia:',
'createacct-yourpasswordagain' => 'Peunyo lageuëm rahsia',
'createacct-yourpasswordagain-ph' => 'Pasoë lom lageuëm rahsia',
'remembermypassword' => 'Ingat lôn tamong bak peuramban nyoë (keu paleng trep $1 {{PLURAL:$1|uroë|uroë}})',
'gotaccount' => "Ka lheuëh neudapeuta? '''$1'''.",
'gotaccountlink' => 'Tamong',
'userlogin-resetlink' => 'Tuwo ngon rincian tamong Droeneuh?',
-'userlogin-resetpassword-link' => 'Peugöt lageuëm rahsia la’én',
+'userlogin-resetpassword-link' => 'Tuwö lageuëm rahsia?',
'helplogin-url' => 'Help:Tamong',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Bantu tamöng]]',
'userlogin-loggedin' => 'Droëneuh ka neutamöng seubagoë $1. Neunguy blangko di yup keu neutamöng seubagoë ureuëng nguy la’én',
'wrongpassword' => 'Lageuëm nyang neupasoë salah. Neuci lom.',
'wrongpasswordempty' => 'Droëneuh hana neupasoë lageuëm. Neuci lom.',
'passwordtooshort' => "Lageuëm paléng h'an haroh na {{PLURAL:$1|1 karakter|$1 karakter}}.",
-'mailmypassword' => "Peu'ét lageuëm barô",
+'mailmypassword' => "Peu'ét lageuëm rahsia barô u surat-e",
'passwordremindertitle' => 'Lageuëm seumeuntara barô keu {{SITENAME}}',
'passwordremindertext' => 'Salah sidroë (kadang Droëneuh, ngön alamat IP $1) geulakèë lageuëm barô keu {{SITENAME}} ($4). Lageuëm si\'at keu ureuëng nguy "$2" ka geupeuna ngon ka geuato jeuet keu "$3". Meunyo nyoe nakeuh meukeusud droeneuh, droeneuh peureulee neutamong ngon neupileh lageuem baro jinoe. Lageuem siat droeneuh meung abeh lam {{PLURAL:$5|siuroe|$5 uroe}}.
'loginlanguagelabel' => 'Bahsa: $1',
# Change password dialog
-'retypenew' => 'Pasoë teuma lageuëm barô:',
+'resetpass' => 'Gantoë lageuëm rahsia',
+'resetpass_header' => 'Gantoë lageuëm rahsia nan ureuëng ngui',
+'oldpassword' => 'Lageuëm rahsia awai:',
+'newpassword' => 'Lageuëm rahsia barô:',
+'retypenew' => 'Pasoë lom lageuëm barô:',
+'resetpass_submit' => 'Atô lageuëm rahsia lheuëh nyan tamöng',
+'changepassword-success' => 'Lageuëm rahsia droëneuh meuhasé geugantoë!',
+'resetpass_forbidden' => "Lageuëm rahsia h'an jeuët geugantoë",
+'resetpass-no-info' => "Droëneuh suwah neutamöng mangat jeuët neu'eu laman nyoë",
+'resetpass-submit-loggedin' => 'Gantoë lageuëm rahsia',
+'resetpass-submit-cancel' => 'Pubateuë',
# Edit page toolbar
-'bold_sample' => 'Rakam teubay',
+'bold_sample' => 'Rakam teubai',
'bold_tip' => 'Haraih teubay',
'italic_sample' => 'Rakam singèt naseukah nyoë',
'italic_tip' => 'Rakam singèt',
'link_sample' => 'Nan hubông',
-'link_tip' => 'Hubông dalam',
+'link_tip' => 'Peunawôt dalam',
'extlink_sample' => 'http://www.example.com nan hubông',
-'extlink_tip' => 'Hubông luwa (bèk tuwoë bôh http:// bak away)',
+'extlink_tip' => 'Peunawôt luwa (neubôh http:// bak awai)',
'headline_sample' => 'Naseukah nan',
'headline_tip' => 'Aneuk beunagi tingkat 1',
'nowiki_sample' => 'Bèk format naseukah nyoë',
Droëneuh jeuët [[Special:Search/{{PAGENAME}}|neumita keu nan ôn nyoë]] bak ôn-ôn la\'én,
atawa <span class="plainlinks">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} neumita log nyang na meuhubông]</span>, tapi Droëneuh hana idin keu neupeugöt ôn nyoë',
'updated' => '(Seubarô)',
-'note' => "'''Ceunatat:'''",
+'note' => "'''Hareutoë:'''",
'previewnote' => "'''Beu neuingat meunyo laman nyoë goh lom neukeubah!'''",
'editing' => 'Andam $1',
'editingsection' => 'Andam $1 (bideuëng)',
# Revision deletion
'rev-delundel' => 'peuleumah/peusom',
-'revdel-restore' => 'Ubah neuleumah',
+'revdel-restore' => 'Gantoë seuneudeuih',
'revdel-restore-deleted' => 'geunantoe nyang ka geusampôh',
-'revdel-restore-visible' => 'geunantoe nyang leumah',
+'revdel-restore-visible' => 'geunantoë nyang deuih',
# Merge log
'revertmerge' => 'Hana jadèh peugabông',
'searchmenu-exists' => "'''Na on ngon nan \"[[:\$1]]\" bak wiki nyoe.'''",
'searchmenu-new' => "'''Peugöt ôn \"[[:\$1]]\" bak wiki nyoë!'''",
'searchprofile-articles' => 'Ôn asoë',
-'searchprofile-project' => 'Ôn Beunantu ngön Buët',
+'searchprofile-project' => 'Laman Beunantu ngön Buët',
'searchprofile-images' => 'Multimedia',
'searchprofile-everything' => 'Ban dum',
'searchprofile-advanced' => 'Tingkat lanjut',
'searchrelated' => 'meusambat',
'searchall' => 'ban dum',
'showingresultsheader' => "{{PLURAL:$5|Hase '''$1''' nibak '''$3'''|Hase '''$1 - $2''' nibak '''$3'''}} keu '''$4'''",
-'nonefound' => "'''Ceunatat''': Cit ladôm ruweuëng nyang seucara baku geupeutamöng lam meunita. Ci neupuphôn leunakèë Droëneuh ngön ''all:'' keu mita ban dum asoë (rôh cit ôn peugah haba, tèmplat, ngön nyang la’én (nnl)), atawa neunguy ruweuëng nan nyang neumeuh’eut sibagoë neu’away.",
-'search-nonefound' => 'Hana hase nyang paih lagee atra neulakee',
+'nonefound' => "'''Teuneurang''': Ladôm ruweuëng nan mantöng nyang geumita.
+Neubaci puphôn neulakèë droëneuh ngön ''all:'' keu jak mita ban dum asoë (rôh lam nyan laman marit, seunaleuëk, ngön nyang la’én nibak nyan), atawa neungui ruweuëng nan nyang neumeuh’eut sibagoë neuawai.",
+'search-nonefound' => 'Hana hasé nyang paih lagèë neulakèë',
'powersearch' => 'Mita lanjut',
'powersearch-legend' => 'Mita lanjut',
'powersearch-ns' => 'Mita bak ruweuëng nan:',
# Recent changes
'nchanges' => '$1 {{PLURAL:$1|neuubah}}',
+'enhancedrc-since-last-visit' => '$1 {{PLURAL:$1|yôh seunaweuë seuneulheuëh kön}}',
'recentchanges' => 'Neuubah barô',
'recentchanges-legend' => 'Peuniléh neuubah barô',
'recentchanges-summary' => "Di yup nyoë nakeuh neuubah barô nyang na bak Wikipèdia nyoë.
-Ceunatat: (bida) = neuubah, (riwayat) = riwayat teumuléh, '''B''' = ôn barô, '''u''' = neuandam ubeut, '''b''' = neuandam bot, (± ''bit'') = jumeulah asoë meutamah/meukureuëng, → = neuandam beunagi, ← = mohtasa otomatis.
+
+
+Hareutoë: (bida) = neuubah, (riwayat) = riwayat teumuléh, '''B''' = laman barô, '''u''' = neuandam ubeut, '''b''' = neuandam bot, (± ''bit'') = jumeulah asoë meutamah/meukureuëng, → = neuandam beunagi, ← = mohtasa otomatis.
----",
+'recentchanges-noresult' => 'Hana neuubah lam lheuëng watèë nyoë nyang paih ngön syarat',
'recentchanges-feed-description' => 'Seutot neuubah barô lam wiki bak umpeuën nyoë.',
'recentchanges-label-newpage' => 'Neuandam nyoe jipeugot on baro',
'recentchanges-label-minor' => 'Nyoe neuandam ubeut',
'recentchanges-label-unpatrolled' => 'Neuandam nyoe goh lom geukalon',
'rcnote' => "Di yup nyoë nakeuh {{PLURAL:$1|nakeuh '''1''' neu’ubah barô |nakeuh '''$1''' neu’ubah barô}} lam {{PLURAL:$2|'''1''' uroë|'''$2''' uroë}} nyoë, trôk ‘an $5, $4.",
'rcnotefrom' => 'Di yup nyoë nakeuh neuubah yôh <strong>$2</strong> (geupeudeuh trôh ‘an <strong>$1</strong> neuubah).',
-'rclistfrom' => 'Peuleumah neuubah paléng barô yôh $1 kön',
+'rclistfrom' => 'Peudeuih neuubah barô yôh $1 kön',
'rcshowhideminor' => '$1 andam bacut',
'rcshowhidebots' => '$1 bot',
'rcshowhideliu' => '$1 ureuëng nguy tamong',
'rcshowhideanons' => '$1 ureuëng nguy hana nan',
'rcshowhidepatr' => '$1 andam teurunda',
'rcshowhidemine' => '$1 atra lôn andam',
-'rclinks' => 'Peuleumah $1 neuubah paléng barô lam $2 uroë nyoë<br />$3',
+'rclinks' => 'Peudeuih $1 neuubah barô lam $2 uroë nyoë<br />$3',
'diff' => 'bida',
'hist' => 'riwayat',
'hide' => 'Peusom',
'filehist-datetime' => 'Uroë buleuën/Watèë',
'filehist-thumb' => 'Beuntuk ubeut',
'filehist-thumbtext' => 'Beuntuk ubeut keu seunalén tiëp $1',
-'filehist-user' => 'Ureuëng nguy',
+'filehist-user' => 'Ureuëng ngui',
'filehist-dimensions' => 'Dimènsi',
'filehist-filesize' => 'Rayek beureukah',
'filehist-comment' => "Seuneu'ôt",
-'imagelinks' => 'Neunguy beureukaih',
+'imagelinks' => 'Seuneungui beureukaih',
'linkstoimage' => 'Ôn di yup nyoë na {{PLURAL:$1|hubông|$1 hubông}} u beureukah nyoë:',
-'nolinkstoimage' => 'Hana ôn nyang na hubông u beureukah nyoë.',
+'nolinkstoimage' => 'Hana laman nyang na meupawôt u beureukaih nyoë.',
'sharedupload' => 'Beureukah nyoë dari $1 ngön kadang geunguy lé buët-buët la’én.',
'sharedupload-desc-here' => "Beureukaih nyoe nejih nibak $1 ngon kadang geunguy le proyek-proyek la'en.
Teuneurang bak [$2 on teuneurangjih] geupeuleumah di yup nyoe.",
'move' => 'Peupinah',
'movethispage' => 'Peupinah ôn nyoë',
'pager-newer-n' => '{{PLURAL:$1|1 leubèh barô |$1 leubèh barô}}',
-'pager-older-n' => '{{PLURAL:$1|1 leubèh trép|$1 leubèh trép}}',
+'pager-older-n' => '{{PLURAL:$1|1 leubèh awai|$1 leubèh awai}}',
# Book sources
'booksources' => 'Nè kitab',
'booksources-go' => 'Mita',
# Special:Log
-'specialloguserlabel' => 'Ureuëng nguy:',
-'speciallogtitlelabel' => 'Nan:',
+'specialloguserlabel' => 'Ureuëng ngui:',
+'speciallogtitlelabel' => 'Sasaran (nan atawa ureuëng ngui):',
'log' => 'Log',
'all-logs-page' => 'Ban dum log umom',
# Special:LinkSearch
'linksearch' => 'Mita seuneumat luwa',
'linksearch-ok' => 'Mita',
-'linksearch-line' => '$1 meusambat nibak $2',
+'linksearch-line' => '$1 meupawôt nibak $2',
# Special:ListGroupRights
'listgrouprights-members' => '(dapeuta anggèëta)',
'actioncomplete' => 'Seuleusoë',
'actionfailed' => 'Hana meuhase',
'deletedtext' => '"$1" ka geusampôh. Eu $2 keu log paléng barô bak ôn nyang ka geusampôh.',
-'dellogpage' => 'Log seunampoh',
+'dellogpage' => 'Log seunampôh',
'deletecomment' => 'Choë:',
'deleteotherreason' => 'Nyang la’én/choë la’én:',
'deletereasonotherlist' => 'Choë la’én',
'protect-default' => 'Peuidin ban dum ureuëng nguy',
'protect-fallback' => 'Peureulèë hak peuhah "$1"',
'protect-level-autoconfirmed' => 'Theun ureuëng nguy barô ngön hana teudapeuta',
-'protect-level-sysop' => 'Ureuëng urôh mantöng',
+'protect-level-sysop' => 'Peuidin ureuëng urôh mantöng',
'protect-summary-cascade' => 'riti',
'protect-expiring' => 'maté tanggay $1 (UTC)',
'protect-cascade' => 'Peulindông ban mandum ôn nyang rôh lam ôn nyoë (lindông meuturôt).',
'mycontris' => 'Beuneuri',
'contribsub2' => 'Keu {{GENDER:$3|$1}} ($2)',
'uctop' => '(jinoë)',
-'month' => 'Yôh buleuën (ngön yôh goh lom nyan)',
-'year' => 'Yôh thôn (ngön yôh goh lom nyan)',
+'month' => 'Mula phôn buleuën (ngön sigohlomjih)',
+'year' => 'Mula phôn thôn (ngön sigohlomjih)',
'sp-contributions-newbies' => 'Peudeuh beuneuri atra ureuëng ban dapeuta mantöng',
'sp-contributions-newbies-sub' => 'Keu ureuëng nguy barô',
'whatlinkshere' => 'Peunawôt balék',
'whatlinkshere-title' => 'Ôn nyang na neuhubông u $1',
'whatlinkshere-page' => 'Ôn:',
-'linkshere' => "Ôn-ôn nyoë meuhubông u '''[[:$1]]''':",
+'linkshere' => "Laman-laman nyoë meupawôt u '''[[:$1]]''':",
'nolinkshere' => "Hana halaman nyang teukaw'et u '''[[:$1]]'''.",
'isredirect' => 'ôn peupinah',
'istemplate' => 'ngön seunaleuëk',
'isimage' => 'hubông beureukaih',
'whatlinkshere-prev' => '$1 {{PLURAL:$1|sigohlomjih|sigohlomjih}}',
'whatlinkshere-next' => '$1 {{PLURAL:$1|lheuëh nyan|lheuëh nyan}}',
-'whatlinkshere-links' => '← hubông',
+'whatlinkshere-links' => '← peunawôt',
'whatlinkshere-hideredirs' => '$1 peuninah',
'whatlinkshere-hidetrans' => '$1 transklusi',
-'whatlinkshere-hidelinks' => '$1 hubông',
+'whatlinkshere-hidelinks' => '$1 peunawôt',
'whatlinkshere-hideimages' => '$1 seuneumat beureukaih',
'whatlinkshere-filters' => 'Saréng',
'ipblocklist-submit' => 'Mita',
'blocklink' => 'theun',
'unblocklink' => 'peugadöh theun',
-'change-blocklink' => 'ubah theun',
+'change-blocklink' => 'gantoë theun',
'contribslink' => 'beuneuri',
'blocklogpage' => 'Log peutheun',
'blocklogentry' => 'theun [[$1]] ngön watèë maté tanggay $2 $3',
# Tooltip help for the actions
'tooltip-pt-userpage' => 'Ôn ureuëng nguy Droëneuh',
'tooltip-pt-mytalk' => 'Ôn marit Droëneuh',
-'tooltip-pt-preferences' => 'Atô',
-'tooltip-pt-watchlist' => 'Dapeuta ôn nyang lônkalön',
+'tooltip-pt-preferences' => 'Geunalak',
+'tooltip-pt-watchlist' => 'Dapeuta laman nyang lônkalön',
'tooltip-pt-mycontris' => 'Dapeuta beuneuri Droëneuh',
'tooltip-pt-login' => 'Droëneuh geupadan keu tamong log, bah pih nyan hana geupeuwajéb.',
'tooltip-pt-logout' => 'Teubiët',
'tooltip-ca-talk' => 'Marit ôn asoë',
-'tooltip-ca-edit' => 'Droëneuh jeuët neuandam ôn nyoë. Neunguy tumbôy eu dilèë yôh goh neukeubah.',
+'tooltip-ca-edit' => 'Droëneuh jeuët neuandam laman nyoë. Neungui tumbôi eu dilèë sigoh neukeubah.',
'tooltip-ca-addsection' => 'Puphôn beunagi barô',
'tooltip-ca-viewsource' => 'Ôn nyoë geupeulindông.
Droëneuh jeuët neu’eu nèjih.',
-'tooltip-ca-history' => 'Seunalén away nibak ôn nyoë',
+'tooltip-ca-history' => 'Seunalén awai nibak ôn nyoë',
'tooltip-ca-protect' => 'Peulindông ôn nyoë',
'tooltip-ca-delete' => 'Sampôh ôn nyoë',
'tooltip-ca-move' => 'Peupinah ôn nyoë',
'tooltip-p-logo' => 'Saweuë ôn keuë',
'tooltip-n-mainpage' => 'Jak u ôn keuë',
'tooltip-n-mainpage-description' => 'Saweuë ôn keuë',
-'tooltip-n-portal' => 'Bhaih buët, peuë nyang jeuët neupubuët, pat keu mita sipeuë hay',
+'tooltip-n-portal' => 'Bhaih buët, peuë nyang jeuët neupubuët, pat keu mita sipeuë hai',
'tooltip-n-currentevents' => 'Mita haba barô',
-'tooltip-n-recentchanges' => 'Dapeuta neuubah baro lam wiki.',
+'tooltip-n-recentchanges' => 'Dapeuta neuubah barô lam wiki.',
'tooltip-n-randompage' => 'Peuleumah ôn beurangkari',
'tooltip-n-help' => 'Bak mita bantu.',
-'tooltip-t-whatlinkshere' => 'Dapeuta ban dum ôn wiki nyang meuhubông keunoë',
-'tooltip-t-recentchangeslinked' => 'Neuubah barô ôn nyang na seuneumat u ôn nyoë',
+'tooltip-t-whatlinkshere' => 'Dapeuta ban dum laman wiki nyang mupawôt keunoë',
+'tooltip-t-recentchangeslinked' => 'Neuubah barô lam laman nyang meupawôt nibak laman nyoë',
'tooltip-feed-rss' => 'Umpeuën RSS keu ôn nyoë',
-'tooltip-feed-atom' => 'Umpeuën Atom keu ôn nyoë',
+'tooltip-feed-atom' => 'Umpeuën Atom keu laman nyoë',
'tooltip-t-contributions' => 'Eu dapeuta nyang ka geutuléh lé ureuëng nguy nyoë',
'tooltip-t-emailuser' => "Peu'ét surat-e keu ureuëng nguy nyoë",
'tooltip-t-upload' => 'Peutamong beureukaih',
'tooltip-t-specialpages' => 'Dapeuta ban dum ôn kusuih',
-'tooltip-t-print' => 'Seunalén rakam ôn nyoë',
-'tooltip-t-permalink' => 'Seuneumat teutap keu geunantoë ôn nyoë',
+'tooltip-t-print' => 'Seunalén rakam laman nyoë',
+'tooltip-t-permalink' => 'Peunawôt teutap keu geunantoë laman nyoë',
'tooltip-ca-nstab-main' => 'Eu ôn asoë',
'tooltip-ca-nstab-user' => 'Eu ôn ureuëng nguy',
'tooltip-ca-nstab-special' => 'Nyoë nakeuh ôn kusuih nyang h’an jeuët geu’andam.',
'pageinfo-toolboxlink' => 'Teuneurang laman',
# Browsing diffs
-'previousdiff' => '← Bida away',
+'previousdiff' => '← Bida awai',
'nextdiff' => 'Geunantoë lheuëh nyan →',
# Media information
'namespacesall' => 'ban dum',
'monthsall' => 'ban dum',
+# Auto-summaries
+'autosumm-new' => "Geupeugöt laman ngön asoë '$1'",
+
+# Live preview
+'livepreview-loading' => 'Pumasoë...',
+'livepreview-ready' => 'Pumasoë... Ka lheuëh!',
+'livepreview-failed' => 'Peudeuih hasé langsông hana meuhasé!
+Neuci peudeuih hasé biasa.',
+'livepreview-error' => 'H\'an jitém teusambat: $1 "$2"
+Neuci peudeuih hasé biasa.',
+
# Watchlist editing tools
'watchlisttools-view' => "Peudeuh neuubah meukaw'èt",
'watchlisttools-edit' => 'Peudeuh ngön andam dapeuta keunalön',
'gotaccount' => 'Igwa ka na tabi nin panindog? $1.',
'gotaccountlink' => 'Maglaog',
'userlogin-resetlink' => 'Nakalingaw ka sa panlaog mong detalye?',
-'userlogin-resetpassword-link' => 'Pakibaguha an saimong sekretong panlaog',
+'userlogin-resetpassword-link' => 'Nalingawan mo an saimong pasa-taramon?',
'helplogin-url' => 'Help:Paglalaog',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Tabang sa paglalaog]]',
'userlogin-loggedin' => 'Ika nakalaog na tabi bilang si {{GENDER:$1|$1}}.
'mailerror' => 'Salâ an pagpadará kan koreo: $1',
'acct_creation_throttle_hit' => 'Mga bisita kaining wiki na ginagamit an saimong IP address nagmukna nin {{PLURAL:$1|1 panindog|$1 mga panindog}} sa nakaaging aldaw, na iyo ngani an maximum na pinagtutugot sa laog kan peryodong panahon.
Bilang resulta, an mga bisita na naggagamit kaining IP address dae nguna makakamukna nin mga panindog.',
-'emailauthenticated' => 'An saimong e-koreo awtentikado kan $2 sa $3.',
-'emailnotauthenticated' => 'An saimong e-surat dae pa tabi pinagpatunayan.
-Mayong e-surat an ipapadara para sa arinman kan minasunod na estima.',
+'emailauthenticated' => 'An saimong e-surat na estada pinagkumpirma kan $2 mga alas $3.',
+'emailnotauthenticated' => 'An saimong e-surat na estada dae pa tabi pinagkumpirma.
+Mayo tabing e-surat na ipagpapadara para sa arinman kan mga minasunod na mga estima.',
'noemailprefs' => 'Magkaag nin sarong e-koreong address sa saimong mga kabotan para gumana ining mga estima.',
'emailconfirmlink' => 'Kompirmaron tabî an saimong e-koreong address',
'invalidemailaddress' => 'An e-koreo dae akseptado habang ini minapahiling na igwa nin imbalidong panugmad.
'gotaccount' => "Имате ли вече сметка? '''$1'''.",
'gotaccountlink' => 'Влизане',
'userlogin-resetlink' => 'Забравени данни за влизане в системата?',
-'userlogin-resetpassword-link' => 'Ð\92Ñ\8aзÑ\81Ñ\82ановÑ\8fване на паÑ\80олаÑ\82а',
+'userlogin-resetpassword-link' => 'Ð\97абÑ\80авена паÑ\80ола?',
'helplogin-url' => 'Help:Влизане',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Помощ за влизане]] в системата',
'userlogin-loggedin' => 'Вече сте влезли в системата като {{GENDER:$1|$1}}.
'acct_creation_throttle_hit' => 'През последното денонощие, през този IP-адрес посетители на това уики са създали {{PLURAL:$1|1 сметка |$1 сметки}}, което е максималният допустим брой за този период.
В резултат, към момента не могат да създават повече потребителски сметки през този IP-адрес.',
'emailauthenticated' => 'Адресът на електронната ви поща беше потвърден на $2 в $3.',
-'emailnotauthenticated' => 'Адресът на електронната ви поща <strong>не е потвърден</strong>. Няма да получавате писма за никоя от следните възможности.',
+'emailnotauthenticated' => 'Адресът на електронната ви поща все още не е потвърден.
+Няма да получавате писма за никоя от следните възможности.',
'noemailprefs' => 'За да работят тези функционалности, трябва да посочите адрес на електронна поща в своите настройки.',
'emailconfirmlink' => 'Потвърждаване на адреса за електронна поща',
'invalidemailaddress' => 'Въведеният адрес не може да бъде приет, тъй като не съответства на формата на адрес за електронна поща. Въведете коректен адрес или оставете полето празно.',
Можете да пренебрегнете това съобщение, ако сметката е създадена по грешка.',
'usernamehasherror' => 'Потребителското име не може да съдържа хеш символи',
'login-throttled' => 'Направили сте твърде много опити да въведете паролата за тази сметка.
-Ð\98зÑ\87акайÑ\82е извеÑ\81Ñ\82но вÑ\80еме преди да опитате отново.',
+Ð\9dеобÑ\85одимо е да изÑ\87акаÑ\82е $1 преди да опитате отново.',
'login-abort-generic' => 'Влизането беше неуспешно - Прекратено',
'loginlanguagelabel' => 'Език: $1',
'suspicious-userlogout' => 'Заявката ви за излизане от системата беше отхвърлена, тъй като изглежда е била изпратена погрешка от браузъра или кеширащото прокси.',
'logentry-newusers-create' => 'Потребителската сметка $1 беше {{GENDER:$2|създадена}}',
'logentry-newusers-create2' => '$1 {{GENDER:$2|създаде}} потребителска сметка $3',
'logentry-newusers-byemail' => '$1 {{GENDER:$2|създаде}} потребителската сметка $3, като паролата за нея беше изпратена по е-поща',
-'logentry-newusers-autocreate' => 'Сметката $1 беше създадена автоматично',
-'logentry-rights-rights' => '$1 промени потребителската група на $3 от $4 на $5',
-'logentry-rights-rights-legacy' => '$1 промени потребителската група на $3',
+'logentry-newusers-autocreate' => 'Сметката $1 беше {{GENDER:$2|създадена}} автоматично',
+'logentry-rights-rights' => '$1 {{GENDER:$2|промени}} потребителската група на $3 от $4 на $5',
+'logentry-rights-rights-legacy' => '$1 {{GENDER:$2|промени}} потребителската група на $3',
'logentry-rights-autopromote' => '
$1 е автоматично повишен от $4 до $5',
'rightsnone' => '(никакви)',
'gotaccount' => "আপনার কি ইতিমধ্যে একটি অ্যাকাউন্ট তৈরি করা আছে? '''$1''' করুন।",
'gotaccountlink' => 'প্রবেশ',
'userlogin-resetlink' => 'আপনার লগইনের বিস্তারিত তথ্যাদি ভুলে গেছেন?',
-'userlogin-resetpassword-link' => 'শবà§\8dদà¦\9aাবি পà§\81নরায় ধারà§\8dয à¦\95রà§\81ন',
+'userlogin-resetpassword-link' => 'শবà§\8dদà¦\9aাবি à¦à§\81লà§\87 à¦\97à§\87à¦\9bà§\87ন?',
'helplogin-url' => 'Help:প্রবেশ',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|লগইন সংক্রান্ত সাহায্য]]',
'userlogin-loggedin' => 'আপনি বর্তমানে {{GENDER:$1|$1}} হিসাবে লগইন আছেন।
'passwordsent' => 'একটি নতুন শব্দচাবি "$1" ব্যবহারকারীর ই-মেইল ঠিকানায় পাঠানো হয়েছে। দয়াকরে তা পাওয়ার পর আবার লগ-ইন করুন।',
'blocked-mailpassword' => 'আপনার আইপি ঠিকানাটি থেকে সম্পাদনা করতে বাধা আছে, তাই এই ঠিকানার অপব্যবহার করে শব্দচাবি ফেরত আনতে দেয়া যাবে না।',
'eauthentsent' => 'মনোনীত ই-মেইল ঠিকানায় একটি নিশ্চিতকরণ ই-মেইল পাঠানো হয়েছে।
-à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà¦\9fিতà§\87 à¦\85নà§\8dয যà§\87 à¦\95à§\8bন à¦\87-মà§\87à¦\87ল পাঠানà§\8bর à¦\86à¦\97à§\87 à¦\86পনাà¦\95à§\87 à¦\8fà¦\87 à¦\87-মà§\87à¦\87লà§\87র নিরà§\8dদà§\87শà¦\97à§\81লি à¦\85নà§\81সরণ à¦\95রতà§\87 হবà§\87, যাতà§\87 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà¦\9fি যà§\87 à¦\86সলà§\87à¦\87 à¦\86পনার, তা নিশà§\8dà¦\9aিত হয়।',
+à¦\90 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà¦\9fà§\87 à¦\85নà§\8dয à¦\95à§\8bন à¦\87-মà§\87à¦\87ল পাঠানà§\8bর à¦\86à¦\97à§\87 à¦\86পনাà¦\95à§\87 à¦\87-মà§\87à¦\87লà§\87র নিরà§\8dদà§\87শà¦\97à§\81লি à¦\85নà§\81সরণ à¦\95রতà§\87 হবà§\87, যাতà§\87 à¦\85à§\8dযাà¦\95াà¦\89নà§\8dà¦\9fà¦\9fি যà§\87 à¦\86সলà§\87à¦\87 à¦\86পনার, তা নিশà§\8dà¦\9aিত হয়।',
'throttled-mailpassword' => 'বিগত {{PLURAL:$1|ঘন্টার|$1 ঘন্টার}} মধ্যে ইতিমধ্যেই একবার শব্দচাবি বদলের তথ্য পাঠানো হয়েছে। অপব্যবহার রোধে প্রতি {{PLURAL:$1|ঘন্টায়|$1 ঘন্টায়}} কেবল একবার শব্দচাবি বদলের তথ্য পাঠানো যাবে।',
'mailerror' => 'ইমেইল পাঠাতে সমস্যা: $1',
'acct_creation_throttle_hit' => 'এই উইকির দর্শক আপনার IP থেকে বিগত সময়ে {{PLURAL:$1|1 টি অ্যাকাউন্ট|$1 গুলো অ্যাকাউন্ট}} তৈরি করেছেন, যা এই সময়ের জন্য সর্বোচ্চ অনুমোদনকৃত।
ফলে, এই IP থেকে দর্শক এই সময়ে নতুন অ্যাকাউন্ট তৈরি করতে পারবেন না।',
-'emailauthenticated' => 'আপনার ই-মেইল ঠিকানাটি $2 তারিখের $3 এ নিশ্চিত করা হয়েছে।',
-'emailnotauthenticated' => 'আপনার ই-মেইলের ঠিকানা <strong>এখনও যাচাই করা হয়নি</strong>। নিচের বৈশিষ্ট্যগুলোর (features) জন্য কোনো ই-মেইল পাঠানো হবে না।',
+'emailauthenticated' => 'আপনার ইমেইল ঠিকানাটি $2 তারিখের $3 এ নিশ্চিত করা হয়েছে।',
+'emailnotauthenticated' => 'আপনার ই-মেইলের ঠিকানা এখনও যাচাই করা হয়নি।
+নিচের বৈশিষ্ট্যগুলোর (features) জন্য কোনো ই-মেইল পাঠানো হবে না।',
'noemailprefs' => 'এই বৈশিষ্টটি কাজ করাতে হলে একটি ই-মেইল ঠিকানা নির্ধারণ করতে হবে।',
'emailconfirmlink' => 'আপনার ই-মেইলের ঠিকানা নিশ্চিত করুন',
'invalidemailaddress' => 'এই ই-মেইল ঠিকানাটি গ্রহণযোগ্য নয়, কারণ সম্ভবত এটি সঠিক ফরম্যাটে লেখা হয়নি। অনুগ্রহ করে সঠিক ফরম্যাটে লেখা ই-মেইল ঠিকানা দিন, অথবা ক্ষেত্রটি খালি রাখুন।',
* ভুল ব্যক্তিগত তথ্য
*: ''বাসার ঠিকানা এবং ফোন নম্বর, সোসাল সিকিউরিটি নম্বর, ইত্যাদি।''",
'revdelete-legend' => 'দৃষ্টিপাত সীমাবদ্ধ করো',
-'revdelete-hide-text' => 'সà¦\82শà§\8bধিত লà§\87à¦\96া à¦\86ড়াল à¦\95রà§\8b',
+'revdelete-hide-text' => 'সà¦\82সà§\8dà¦\95রণà§\87র লà§\87à¦\96া',
'revdelete-hide-image' => 'ফাইলের বিষয়বস্তু আড়াল করো',
'revdelete-hide-name' => 'কাজ এবং লক্ষ্য আড়াল করো',
-'revdelete-hide-comment' => 'সম্পাদনা সারাংশ আড়াল করো',
-'revdelete-hide-user' => 'সম্পাদকে ব্যবহারকারীর নাম/আইপি আড়াল করো',
+'revdelete-hide-comment' => 'সম্পাদনা সারাংশ',
+'revdelete-hide-user' => 'সম্পাদকে ব্যবহারকারীর নাম/আইপি',
'revdelete-hide-restricted' => 'প্রশাসকবৃন্দ এবং অন্যদের ক্ষেত্রে এই ডাটা রোধ করো',
'revdelete-radio-same' => 'পরিবর্তন নয়',
-'revdelete-radio-set' => 'হà§\8dযাà¦\81',
-'revdelete-radio-unset' => 'না',
+'revdelete-radio-set' => 'দà§\83শà§\8dযমান',
+'revdelete-radio-unset' => 'লà§\81à¦\95ানà§\8b',
'revdelete-suppress' => 'সব প্রশাসক ও অন্যান্যদের কাছ থেকে উপাত্ত লুকিয়ে রাখা হোক।',
'revdelete-unsuppress' => 'সংশোধন পুনঃস্থাপনের উপর সীমাবদ্ধতা দূর করো',
'revdelete-log' => 'কারণ:',
'spam_reverting' => '$1-এর প্রতি কোন সংযোগ নেই, এমন সর্বশেষ সংস্করণে ফেরত নেওয়া হচ্ছে।',
'spam_blanking' => '$1-এর প্রতি সংযোগ অন্তর্ভুক্ত আছে এমন সমস্ত সংশোধন খালি করা হচ্ছে',
'spam_deleting' => '$1-এর প্রতি সংযোগ অন্তর্ভুক্ত আছে এমন সমস্ত সংশোধন অপসারণ করা হচ্ছে',
-'simpleantispam-label' => "এন্টি-স্প্যাম যাচাই।
+'simpleantispam-label' => "এন্টি স্প্যাম যাচাই।
এটা পূরণ করবেন '''না'''!",
# Info page
# Special:Redirect
'redirect' => 'ফাইল, ব্যবহারকরী, অথবা রিভিশন আইডি দ্বারা পুনঃনির্দেশ করা হয়েছে',
'redirect-legend' => 'একটি ফাইল অথবা পাতায় পুনঃনির্দেশ করা হয়েছে',
-'redirect-summary' => 'এই বিশেষ পাতাটি পুনঃনির্দেশিত হয়েছে একটি ফাইলে (ফাইলের নাম), একটি পাতা (রিভিশন আইডি), অথবা একটি ব্যবহারকরী পাতায় (সংখ্যায় লেখা ব্যবহারকারী আইডি)।',
+'redirect-summary' => 'এই বিশেষ পাতাটি পুনঃনির্দেশিত হয়েছে একটি ফাইলে (ফাইলের নাম), একটি পাতা (রিভিশন আইডি), অথবা একটি ব্যবহারকরী পাতায় (সংখ্যায় লেখা ব্যবহারকারী আইডি)। ব্যবহার: [[{{#Special:Redirect}}/file/Example.jpg]], [[{{#Special:Redirect}}/revision/328429]], or [[{{#Special:Redirect}}/user/101]]।',
'redirect-submit' => 'যাও',
'redirect-lookup' => 'দেখুন:',
'redirect-value' => 'মান:',
'gotaccount' => "已經有賬戶了?'''$1'''。",
'gotaccountlink' => '躒底',
'userlogin-resetlink' => '躒底其資料𣍐記咯?',
-'userlogin-resetpassword-link' => '重置汝其密碼',
+'userlogin-resetpassword-link' => '密码𣍐記?',
'helplogin-url' => 'Help: 躒底',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|幫助躒底]]',
'createacct-join' => '敆下底輸底汝其信息。',
# Human-readable timestamps
'hours-ago' => '$1 {{PLURAL:$1|сахьат}} хьалха',
+'minutes-ago' => '$1 {{PLURAL:$1|минут}} хьалха',
'yesterday-at' => 'селхана $1 даьлча',
# Bad image list
'gotaccount' => "Už jste registrováni? '''$1'''.",
'gotaccountlink' => 'Přihlaste se',
'userlogin-resetlink' => 'Zapomněli jste přihlašovací údaje?',
-'userlogin-resetpassword-link' => 'Obnovit heslo',
+'userlogin-resetpassword-link' => 'Zapomněli jste heslo?',
'helplogin-url' => 'Help:Přihlášení',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Nápověda k přihlašování]]',
'userlogin-loggedin' => 'Již jste {{GENDER:$1|přihlášen|přihlášena}} jako $1.
Kvůli prevenci zneužívání lze heslo zaslat jen jednou za $1 {{PLURAL:$1|hodinu|hodiny|hodin}}.',
'mailerror' => 'Chyba při zasílání e-mailu: $1',
'acct_creation_throttle_hit' => 'Uživatelé přicházející z vaší IP adresy už dnes vytvořili $1 {{PLURAL:$1|účet|účty|účtů}}, což je dovolené maximum. Proto v tuto chvíli není dovoleno z této IP adresy další účty zakládat.',
-'emailauthenticated' => 'Vaše e-mailová adresa byla ověřena dne $2 v $3.',
-'emailnotauthenticated' => 'Vaše e-mailová adresa dosud nebyla ověřena a e-mailové funkce do té doby nejsou dostupné.',
+'emailauthenticated' => 'Vaše e-mailová adresa byla ověřena $2 v $3.',
+'emailnotauthenticated' => 'Vaše e-mailová adresa dosud nebyla ověřena.
+U následujících funkcí nebudou zasílány žádné e-maily.',
'noemailprefs' => 'Pro zprovoznění následujících možností musíte zadat svou e-mailovou adresu.',
'emailconfirmlink' => 'Podvrďte svou e-mailovou adresu',
'invalidemailaddress' => 'Zadaná e-mailová adresa nemůže být přijata, neboť nemá správný formát. Zadejte platnou e-mailovou adresu nebo obsah tohoto pole vymažte.',
'gotaccount' => 'Oes cyfrif gennych eisoes? $1.',
'gotaccountlink' => 'Mewngofnodi',
'userlogin-resetlink' => 'Ydych chi wedi anghofio eich manylion mewngofnodi?',
-'userlogin-resetpassword-link' => 'Ailosod eich cyfrinair',
+'userlogin-resetpassword-link' => 'Wedi anghofio eich cyfrinair?',
'helplogin-url' => 'Help:Mewngofnodi',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Cymorth i fewngofnodi]]',
'userlogin-loggedin' => 'Rydych eisoes wedi mewngofnodi wrth yr enw {{GENDER:$1|$1}}.
'acct_creation_throttle_hit' => "Mae ymwelwyr sy'n defnyddio'ch cyfeiriad IP wedi creu $1 {{PLURAL:$1|cyfrif|cyfrif|gyfrif|chyfrif|chyfrif|cyfrif}} yn ystod y diwrnod diwethaf, sef y mwyafswm a ganiateir mewn diwrnod.
Felly ni chaiff defnyddwyr sy'n defnyddio'r cyfeiriad IP hwn greu rhagor o gyfrifon ar hyn o bryd.",
'emailauthenticated' => 'Cadarnhawyd eich cyfeiriad e-bost am $3 ar $2.',
-'emailnotauthenticated' => "Nid yw eich cyfeiriad e-bost wedi'i ddilysu eto. Ni fydd unrhyw negeseuon e-bost yn cael eu hanfon atoch ar gyfer y nodweddion canlynol.",
+'emailnotauthenticated' => "Nid yw eich cyfeiriad e-bost wedi'i gadarnhau eto. Ni fydd unrhyw negeseuon e-bost yn cael eu hanfon atoch ar gyfer y nodweddion canlynol.",
'noemailprefs' => "Mae'n rhaid i chi gynnig cyfeiriad e-bost er mwyn i'r nodweddion hyn weithio.",
'emailconfirmlink' => 'Cadarnhewch eich cyfeiriad e-bost',
'invalidemailaddress' => 'Ni allwn dderbyn y cyfeiriad e-bost gan fod ganddo fformat annilys. Mewnbynnwch cyfeiriad dilys neu gwagiwch y maes hwnnw, os gwelwch yn dda.',
Besucher, die diese IP-Adresse verwenden, können momentan keine Benutzerkonten mehr erstellen.',
'emailauthenticated' => 'Deine E-Mail-Adresse wurde am $2 um $3 Uhr bestätigt.',
-'emailnotauthenticated' => 'Deine E-Mail-Adresse ist noch nicht bestätigt. Die folgenden E-Mail-Funktionen stehen erst nach erfolgreicher Bestätigung zur Verfügung.',
+'emailnotauthenticated' => 'Deine E-Mail-Adresse ist noch nicht bestätigt.
+Die folgenden E-Mail-Funktionen stehen erst nach erfolgreicher Bestätigung zur Verfügung.',
'noemailprefs' => 'Gib eine E-Mail-Adresse in den Einstellungen an, damit die nachfolgenden Funktionen zur Verfügung stehen.',
'emailconfirmlink' => 'E-Mail-Adresse bestätigen (authentifizieren).',
'invalidemailaddress' => 'Die E-Mail-Adresse wird nicht akzeptiert, weil sie ein ungültiges Format (eventuell ungültige Zeichen) zu haben scheint. Bitte gib eine korrekte Adresse ein oder leere das Feld.',
* @ingroup Language
* @file
*
+ * @author AivoK
* @author Avjoska
* @author Cylly1512
* @author Geitost
'gotaccount' => "Kui sul on juba konto, '''$1'''.",
'gotaccountlink' => 'logi sisse',
'userlogin-resetlink' => 'Kas oled unustanud oma sisselogimisandmed?',
-'userlogin-resetpassword-link' => 'Lähtesta oma parool',
+'userlogin-resetpassword-link' => 'Unustasid parooli?',
'helplogin-url' => 'Help:Sisselogimine',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Sisselogimisabi]]',
'userlogin-loggedin' => 'Oled juba sisse logitud nimega {{GENDER:$1|$1}}.
اگر میخواهید متن را در یک پروندهٔ متنی کپی کنید و برای آینده ذخیرهاش کنید.
مدیری که آن را قفل کرده این توضیح را ارائه کردهاست: $1",
-'protectedpagewarning' => "'''هشدار: این صفحه قفل شده است تا فقط کاربران با امتیاز مدیر بتوانند ویرایشش کنند.'''
-آخرین موارد سیاهه در زیر آمده است:",
+'protectedpagewarning' => "'''هشدار: این صفحه قفل شدهاست تا فقط کاربران با دسترسی مدیریت بتوانند ویرایشش کنند.'''
+آخرین موارد سیاهه در زیر آمدهاست:",
'semiprotectedpagewarning' => "'''توجه:''' این صفحه قفل شدهاست تا تنها کاربران ثبتنامکرده قادر به ویرایش آن باشند.
آخرین موارد سیاهه در زیر آمدهاست:",
'cascadeprotectedwarning' => "'''هشدار:''' این صفحه به علت قرارگرفتن در {{PLURAL:$1|صفحهٔ|صفحههای}} آبشاری-محافظتشدهٔ زیر قفل شدهاست تا فقط مدیران بتوانند ویرایشش کنند.",
'gotaccount' => "Hevur tú longu eina kontu? '''$1'''.",
'gotaccountlink' => 'Rita inn',
'userlogin-resetlink' => 'Hevur tú gloymt tínar logg inn upplýsingar',
-'userlogin-resetpassword-link' => 'Nullstilla títt loyniorð',
+'userlogin-resetpassword-link' => 'Hevur tú gloymt títt loyniorð?',
'helplogin-url' => 'Help:Innritan',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Hjálp til innritan]]',
+'userlogin-loggedin' => 'Tú ert longu innritað/ur sum {{GENDER:$1|$1}}.
+Nýt formularin niðanfyri fyri at rita inn sum ein annar brúkari.',
+'userlogin-createanother' => 'Stovna eina aðra kontu',
'createacct-join' => 'Skrivað tínar upplýsingar niðanfyri.',
'createacct-another-join' => 'Skriva upplýsingarnar fyri tað nýggju kontuna niðanfyri.',
'createacct-emailrequired' => 'Teldupost adressa',
sum er skrásett fyri "$1".
Vinarliga rita inn eftir at tú hevur fingið hana.',
'blocked-mailpassword' => 'Tín IP adressa er stongd fyri at gera rættingar á síðum, og tí er tað ikki loyvt at brúka funkuna fyri endurskapan av loyniorði, hetta fyri at forða fyri misnýtslu.',
-'eauthentsent' => '↓ Ein váttanar t-postur er sendur til givna t-post bústaðin.
-Áðrenn aðrir teldupostar verða sendir til kontuna, mást tú fylgja leiðbeiningunum í t-postinum, fyri at vátta at kontoin veruliga er tín.',
+'eauthentsent' => 'Ein váttanar teldupostur er sendur til givna teldupost bústaðin.
+Áðrenn nakað annað teldubræv verður sent til kontuna, mást tú fylgja leiðbeiningunum í teldupostinum, fyri at vátta at kontoin veruliga er tín.',
'throttled-mailpassword' => 'Ein teldupostur har loyniorðið verður nullstillað er longu sendur fyri bert {{PLURAL:$1|tíma|$1 tímum}} síðan.
Fyri at fyribyrja misnýtslu, verður bert ein teldupostur við nullstillaðum loyniorði sendur fyri pr. {{PLURAL:$1|tíma|$1 tímar}}.',
'mailerror' => 'Villa tá t-postur var sendur: $1',
'acct_creation_throttle_hit' => 'Vitjandi á hesi wiki, sum nýta tína IP addressu, hava stovnað {{PLURAL:$1|1 kontu|$1 kontur}} seinastu dagarnar, sum er mest loyvda hetta tíðarskeið.
Sum eitt úrslit av hesum, kunnu vitjandi sum brúka hesa IP adressuna ikki stovna fleiri kontur í løtuni.',
-'emailauthenticated' => 'Tín t-post adressa varð váttað hin $2 kl. $3.',
-'emailnotauthenticated' => 'Tín t-post adressa er enn ikki komin í gildi. Ongin t-postur
-verður sendur fyri nakað av fylgjandi hentleikum.',
+'emailauthenticated' => 'Tín teldupost adressa varð váttað hin $2 kl. $3.',
+'emailnotauthenticated' => 'Tín teldupost adressa er enn ikki váttað. Ongin teldupostur
+verður sendur fyri nakran av fylgjandi hentleikum.',
'noemailprefs' => 'Skriva eina t-post adressu, so hesar funktiónir fara at virka.',
'emailconfirmlink' => 'Vátta tína t-post adressu',
'invalidemailaddress' => 'T-post bústaðurin kann ikki verða góðtikin, tí hann sær út til at hava ógyldugt format.
'logdelete-selected' => "'''{{PLURAL:$1|Útvald logghending|Útvaldar logghendingar}}:'''",
'revdelete-confirm' => 'Vinarliga vátta, at tú ætlar at gera hetta, at tú skilir avleiðingarnar, og at tú ger hetta í samsvari við [[{{MediaWiki:Policy-url}}|mannagongdirnar]].',
'revdelete-legend' => 'Set avmarkinga fyri sjónligheit',
-'revdelete-hide-text' => 'Goym burtur tekstin á hesi versjónini',
+'revdelete-hide-text' => 'Versjónstekstur',
'revdelete-hide-image' => 'Fjal fílu innihald',
'revdelete-hide-name' => 'Fjal handling og mál',
-'revdelete-hide-comment' => 'Fjal rættingar frágreiðing',
-'revdelete-hide-user' => 'Fjal brúkaranavn/IP adressu hjá tí sum rættar',
+'revdelete-hide-comment' => 'Samandráttur um rættingar',
+'revdelete-hide-user' => 'Brúkaranavn/IP adressa hjá tí sum rættar',
'revdelete-hide-restricted' => 'Síggj burtur frá data frá administratorum líka væl sum frá øðrum',
'revdelete-radio-same' => '(ikki broyta)',
-'revdelete-radio-set' => 'Ja',
-'revdelete-radio-unset' => 'Nei',
+'revdelete-radio-set' => 'Sjónligt',
+'revdelete-radio-unset' => 'Fjalt',
'revdelete-suppress' => 'Síggj burtur frá data frá administratorum líka væl sum frá øðrum',
'revdelete-unsuppress' => 'Tak burtur avmarkingar á endurskaptum versjónum',
'revdelete-log' => 'Orsøk:',
'gotaccount' => "Vous avez déjà un compte ? '''$1'''.",
'gotaccountlink' => 'Connectez-vous',
'userlogin-resetlink' => 'Vous avez oublié vos détails de connexion ?',
-'userlogin-resetpassword-link' => 'Réinitialiser le mot de passe',
+'userlogin-resetpassword-link' => 'Mot de passe oublié ?',
'helplogin-url' => 'Help:Connexion',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Aide à la connexion]]',
'userlogin-loggedin' => 'Vous êtes déjà connecté en tant que {{GENDER:$1|$1}}.
'mailerror' => "Erreur lors de l'envoi du courriel : $1",
'acct_creation_throttle_hit' => "Quelqu'un utilisant votre adresse IP a créé {{PLURAL:$1|un compte|$1 comptes}} au cours des dernières 24 heures, ce qui constitue la limite autorisée dans cet intervalle de temps.
Par conséquent, la création de compte a été temporairement désactivée pour cette adresse IP.",
-'emailauthenticated' => 'Votre adresse de courriel a été authentifiée le $2 à $3.',
-'emailnotauthenticated' => "Votre adresse de courriel n'est <strong>pas encore authentifiée</strong>. Aucun courriel ne sera envoyé pour chacune des fonctions suivantes.",
+'emailauthenticated' => 'Votre adresse de courriel a été confirmée le $2 à $3.',
+'emailnotauthenticated' => "Votre adresse de courriel n'est pas encore confirmée. Aucun courriel ne sera envoyé pour chacune des fonctions suivantes.",
'noemailprefs' => 'Indiquez une adresse de courriel dans vos préférences pour utiliser ces fonctions.',
'emailconfirmlink' => 'Confirmez votre adresse de courriel',
'invalidemailaddress' => 'Cette adresse courriel ne peut pas être acceptée car elle semble avoir un format incorrect.
'blanknamespace' => '(Mukhel)',
# Contributions
-'contributions' => '{{GENDER:$1|Vapuddpi}}borovpam',
+'contributions' => '{{GENDER:$1|Vapuddpi}} borovpam',
'contributions-title' => '$1 hea vapuddpean kelelim borovpam',
'mycontris' => 'Borovpam',
'contribsub2' => '{{GENDER:$3|$1}} hacheo ($2)',
'tooltip-t-whatlinkshere' => 'Hanga zoddlelea sogllea wiki pananchi volleri',
'tooltip-t-recentchangeslinked' => 'Hea panak zoddlelea panachim halinchim bodolpam',
'tooltip-feed-atom' => 'Hea panak Atom purovnni',
-'tooltip-t-contributions' => 'Hea vapuddpeachea borovpanchi iadi',
+'tooltip-t-contributions' => 'Hea vapuddpeachea borovpanchi suchi',
'tooltip-t-emailuser' => 'Hea vapuddpeak email patthoi',
'tooltip-t-upload' => 'Faili upload kor',
'tooltip-t-specialpages' => 'Kherit pananchi volleri',
'gotaccount' => 'כבר נרשמתם? $1.',
'gotaccountlink' => 'כניסה לחשבון',
'userlogin-resetlink' => 'שכחת את פרטי הכניסה?',
-'userlogin-resetpassword-link' => '×\90×\99פ×\95ס ×\94ס×\99ס×\9e×\94',
+'userlogin-resetpassword-link' => 'ש×\9b×\97ת ×\90ת ×\94ס×\99ס×\9e×\94?',
'helplogin-url' => 'Help:כניסה לחשבון',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|עזרה בכניסה לחשבון]]',
'userlogin-loggedin' => 'אתם כבר מחוברים לחשבון {{GENDER:$1|$1}}.
לפיכך, מבקרים דרך כתובת ה־IP הזו לא יכולים ליצור חשבונות נוספים ברגע זה.',
'emailauthenticated' => 'כתובת הדוא"ל שלך אומתה ב־$3, $2.',
'emailnotauthenticated' => 'כתובת הדוא"ל שלכם עדיין לא אומתה.
-×\9c×\90 ×\99×\99ש×\9c×\97 ×\90×\9c×\99×\9b×\9d ×\93×\95×\90"×\9c ×¢×\91×\95ר ×\90×£ ×\90×\97ת ×\9e×\94×\90פשר×\95×\99ות הבאות.',
+×\9c×\90 ×\99×\99ש×\9c×\97 ×\90×\9c×\99×\9b×\9d ×\93×\95×\90"×\9c ×¢×\91×\95ר ×\90×£ ×\90×\97ת ×\9e×\94ת×\9b×\95× ות הבאות.',
'noemailprefs' => 'אנא ציינו כתובת דוא"ל בהעדפות שלכם כדי שתכונות אלה יעבדו.',
'emailconfirmlink' => 'אישור כתובת הדוא"ל שלך',
'invalidemailaddress' => 'כתובת הדוא"ל אינה מתקבלת כיוון שנראה שהיא בפורמט לא נכון.
'gotaccount' => 'Hai già un accesso? $1.',
'gotaccountlink' => 'Entra',
'userlogin-resetlink' => 'Hai dimenticato i tuoi dati di accesso?',
-'userlogin-resetpassword-link' => 'Reimposta la tua password',
+'userlogin-resetpassword-link' => 'Hai dimenticato la password?',
'helplogin-url' => 'Help:Login',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Aiuto con il login]]',
'userlogin-loggedin' => 'Sei già connesso come {{GENDER:$1|$1}}.
'gotaccount' => 'アカウントを既に持っている場合、$1。',
'gotaccountlink' => 'ログインしてください',
'userlogin-resetlink' => 'ログイン情報をお忘れですか?',
-'userlogin-resetpassword-link' => 'パスワードを再設定',
+'userlogin-resetpassword-link' => 'パスワードをお忘れですか?',
'helplogin-url' => 'Help:ログイン',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|ログインのヘルプ]]',
'userlogin-loggedin' => '{{GENDER:$1|$1}} として既にログインしています。
'mailerror' => 'メールを送信する際にエラーが発生しました: $1',
'acct_creation_throttle_hit' => 'あなたと同じ IP アドレスでこのウィキに訪れた人が、最近 24 時間で {{PLURAL:$1|$1 アカウント}}を作成しており、これはこの期間で作成が許可されている最大数です。
そのため、現在この IP アドレスではアカウントをこれ以上作成できません。',
-'emailauthenticated' => 'メールアドレスは$2 $3に認証済みです。',
-'emailnotauthenticated' => 'メールアドレスが認証されていません。
-認証されるまで、以下のいかなる機能でもメールは送信されません。',
+'emailauthenticated' => 'メールアドレスは$2 $3に確認済みです。',
+'emailnotauthenticated' => 'メールアドレスが確認されていません。
+確認されるまで、以下のいかなる機能でもメールは送信されません。',
'noemailprefs' => 'これらの機能を有効にするには、個人設定でメールアドレスを登録してください。',
'emailconfirmlink' => 'あなたのメールアドレスを確認',
'invalidemailaddress' => '入力されたメールアドレスが正しい形式に従っていないため、受け付けられません。
'gotaccount' => '계정이 이미 있다면, $1.',
'gotaccountlink' => '로그인하세요',
'userlogin-resetlink' => '사용자 이름이나 비밀번호를 잊으셨나요?',
-'userlogin-resetpassword-link' => 'ë\82´ ë¹\84ë°\80ë²\88í\98¸ ì\9e¬ì\84¤ì \95',
+'userlogin-resetpassword-link' => 'ë¹\84ë°\80ë²\88í\98¸ë¥¼ ì\9e\8aì\9c¼ì\85¨ë\82\98ì\9a\94?',
'helplogin-url' => 'Help:로그인',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|로그인에 관한 도움말]]',
'userlogin-loggedin' => '이미 $1로 로그인되어 있습니다. 아래의 양식으로 다른 계정으로 로그인하세요.',
'mailerror' => '메일 보내기 오류: $1',
'acct_creation_throttle_hit' => '당신의 IP 주소를 이용한 방문자가 이전에 이미 {{PLURAL:$1|계정 $1개}}를 만들어, 계정 만들기 한도를 초과하였습니다.
따라서 지금은 이 IP 주소로는 더 이상 계정을 만들 수 없습니다.',
-'emailauthenticated' => '이메일 주소는 $2 $3에 인증되었습니다.',
+'emailauthenticated' => '이메일 주소는 $2 에 $3 에서 인증되었습니다.',
'emailnotauthenticated' => '이메일 주소를 인증하지 않았습니다.
이메일 확인 절차를 거치지 않으면 다음 이메일 기능을 사용할 수 없습니다.',
'noemailprefs' => '이 기능을 사용하기 위해서는 사용자 환경 설정에서 이메일 주소를 설정해야 합니다.',
# Contributions
'contributions' => '{{GENDER:$1|사용자}} 기여',
'contributions-title' => '$1 사용자의 기여 목록',
-'mycontris' => '기여 목록',
+'mycontris' => '기여',
'contribsub2' => '{{GENDER:$3|$1}}($2)의 기여',
'nocontribs' => '지정한 조건과 일치하는 바뀜을 찾을 수 없습니다.',
'uctop' => '(최신)',
'tooltip-pt-anontalk' => '현재 사용하는 IP 주소에 대한 토론 문서',
'tooltip-pt-preferences' => '사용자 환경 설정',
'tooltip-pt-watchlist' => '주시문서에 대한 바뀜 목록',
-'tooltip-pt-mycontris' => '내 기여 목록',
+'tooltip-pt-mycontris' => '내 기여의 목록',
'tooltip-pt-login' => '꼭 로그인해야 하는 것은 아니지만, 로그인을 권장합니다.',
'tooltip-pt-anonlogin' => '꼭 필요한 것은 아니지만, 로그인을 하면 편리한 점이 많습니다.',
'tooltip-pt-logout' => '로그아웃',
# General errors
'error' => 'Йоҥылыш',
+'databaseerror-error' => 'Йоҥылыш: $1',
'missing-article' => 'Тыгай текст дене возымо лаштык базыште муалтын огыл, "$1" $2.
Кунам тый тоштемше кылвер почеш шӧрымӧ вашталтымаш лаштыкыш (але эртымгорно лаштыкыш) куснет, тыге лийын кертеш.
'virus-unknownscanner' => 'палыдыме антивирус:',
# Login and logout pages
+'welcomeuser' => 'Пагален ӱжына, $1!',
'yourname' => 'Пайдаланышын лӱмжӧ:',
'yourpassword' => 'Шолыпмут:',
+'createacct-yourpassword-ph' => 'Шолыпмутым пурто',
'yourpasswordagain' => 'Шолыпмутым угыч пуртымаш:',
+'createacct-yourpasswordagain' => 'Шолыпмутым пеҥгыдемде',
+'createacct-yourpasswordagain-ph' => 'Шолыпмутым угыч пурто',
'remembermypassword' => 'Тиде компьютерыште мыйым шарнаш (эн шуко $1 {{PLURAL:$1|кечылан|кечылан}})',
'yourdomainname' => 'Тендан домен:',
'login' => 'Шке денет палымым ыште',
'gotaccount' => "Тый регистрацийым эртенат? '''$1'''.",
'gotaccountlink' => 'Шке денет палымым ыште',
'userlogin-resetlink' => 'Лӱмдам але шолыпмутдам монденда?',
+'userlogin-resetpassword-link' => 'Шолыпмутым монденат?',
'createaccountmail' => 'Кӱчык жаплан чокым ыштыме шолыпмутым мылам e-mail дене колташ',
+'createacct-benefit-heading' => '{{SITENAME}} тендан гаяк еҥ-влак дене ыштен шындалтын.',
'nosuchuser' => '"$1" лӱман пайдаланыше уке.
Пайдаланышын лӱмыштӧ йӱкпале-влакын кугытшо тӱрыс лийшаш.
Лӱмым чын возымым терге але [[Special:UserLogin/signup|регистрацийым эрте]].',
'gotaccount' => "Веќе имате корисничка сметка? '''$1'''.",
'gotaccountlink' => 'Најавете се',
'userlogin-resetlink' => 'Си ги заборавивте податоците за најава?',
-'userlogin-resetpassword-link' => 'Смени лозинка',
+'userlogin-resetpassword-link' => 'Ð\88а забоÑ\80авивÑ\82е лозинкаÑ\82а?',
'helplogin-url' => 'Help:Најава',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Помош со најавата]]',
'userlogin-loggedin' => 'Веќе сте најавени како {{GENDER:$1|$1}}.
'mailerror' => 'Грешка при испраќање на е-поштата: $1',
'acct_creation_throttle_hit' => 'Корисници на ова вики користејќи ја вашата IP-адреса создале {{PLURAL:$1|1 корисничка сметка|$1 кориснички сметки}} во последниве денови, при што е достигнат максималниот број на кориснички сметки предвиден и овозможен за овој период.
Како резултат на ова, посетителите кои ја користат оваа IP-адреса во моментов нема да можат да создаваат нови сметки.',
-'emailauthenticated' => 'Ð\92аÑ\88аÑ\82а е-поÑ\88Ñ\82енÑ\81ка адÑ\80еÑ\81а е поÑ\82вÑ\80дена на $2 во $3 Ñ\87.',
+'emailauthenticated' => 'Вашата е-пошта адреса е потврдена на $2 во $3 ч.',
'emailnotauthenticated' => 'Вашата е-поштенска адреса сè уште не е потврдена.
Нема да биде испратена е-пошта во ниту еден од следниве случаи.',
'noemailprefs' => 'Наведете е-поштенска адреса за да функционираат следниве својства.',
(сүүлчийн) = өмнөх засвартай харьцуулах, Б = бага зэргийн засвар',
'history-fieldset-title' => 'Түүх сөхөе',
'history-show-deleted' => 'Зөвхөн устгагдсаныг',
-'histfirst' => 'Эхний',
-'histlast' => 'Сүүлийн',
+'histfirst' => 'хамгийн эхэнд',
+'histlast' => 'хамгийн шинэ',
'historysize' => '($1 байт)',
'historyempty' => '(хоосон байна)',
'listfiles_search_for' => 'Зургийн нэрээр хайх:',
'imgfile' => 'файл',
'listfiles' => 'Файлын жагсаалт',
+'listfiles_thumb' => 'товч агуулга',
'listfiles_date' => 'Огноо',
'listfiles_name' => 'Нэр',
'listfiles_user' => 'Хэрэглэгч',
'mycontris' => 'Оруулсан хувь нэмэр',
'contribsub2' => 'Хэрэглэгч: $1 ($2)',
'nocontribs' => 'Энэ шалгуурт тохирох өөрчилсөн зүйлүүд олдсонгүй.',
-'uctop' => 'ï¼\88дÑ\8dÑ\8dд)',
+'uctop' => 'ï¼\88одооÑ\85)',
'month' => 'Дараах сараас (өмнөх засварууд нь ч орно):',
'year' => 'Дараах жилээс (өмнөх засварууд нь ч орно):',
'gotaccount' => 'Ha-lo già un sò cont? $1.',
'gotaccountlink' => "Ch'a rintra ant ël sistema",
'userlogin-resetlink' => "A l'ha dësmentià ij sò detaj për intré ant ël sistema?",
-'userlogin-resetpassword-link' => 'Riamposté la ciav',
+'userlogin-resetpassword-link' => 'Ciav dësmentià?',
'helplogin-url' => 'Help:Conession',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Agiut con la conession]]',
'userlogin-loggedin' => "A l'é già rintrà an ël sistema tanme {{GENDER:$1|$1}}.
'mailerror' => 'Eror ën mandand via un mëssagi ëd pòsta eletrònica: $1',
'acct_creation_throttle_hit' => "Dij visitador ëd costa wiki, an dovrand soa adrëssa IP a l'han creà {{PLURAL:$1|1 cont|$1 cont}} ant l'ùltim di, che a l'é tut lòn che as peul fesse ant cost temp.
Ëd conseguensa, ij visitador che a deuvro costa adrëssa IP a peulo pì nen fé dij cont al moment.",
-'emailauthenticated' => "Soa adrëssa ëd pòsta eletrònica a l'é stàita autenticà ël $2 a $3.",
-'emailnotauthenticated' => "Soa adrëssa ëd pòsta eletrònica a l'é pa ancó stàita autenticà.
+'emailauthenticated' => "Soa adrëssa ëd pòsta eletrònica a l'é stàita confirmà ël $2 a $3.",
+'emailnotauthenticated' => "Soa adrëssa ëd pòsta eletrònica a l'é pa ancó stàita confirmà.
Për qualsëssìa ëd coste funsion a sarà mandà gnun mëssagi.",
'noemailprefs' => "Che a specìfica n'adrëssa ëd pòsta eletrònica se a veul dovré coste funsion-sì.",
'emailconfirmlink' => 'Che a conferma soa adrëssa ëd pòsta eletrònica',
'qbmyoptions' => 'Heading in the Cologne Blue skin user menu containing links to user (talk) page, preferences, watchlist, etc.
{{Identical|My pages}}',
'qbspecialpages' => '{{Identical|Special page}}',
-'faq' => "FAQ is short for ''frequently asked questions''.",
+'faq' => "FAQ is short for ''frequently asked questions''.
+{{Identical|FAQ}}",
'faqpage' => '{{doc-important|Do not translate <code>Project:</code> part.}}
"FAQ" is short for "frequently asked questions".
See example: [[Special:UserLogin]]
-userlogin-resetpassword-link may have to be shorter than the old {{msg-mw|userlogin-resetlink}}',
+userlogin-resetpassword-link may have to be shorter than the old {{msg-mw|userlogin-resetlink}}.
+{{Identical|Forgot your password}}',
'helplogin-url' => '{{doc-important|Do not translate the namespace name <code>Help</code>.}}
Used as name of the page that provides information about logging into the wiki.
* {{msg-mw|prefs-help-email-others|help}}
* {{msg-mw|prefs-changeemail|link title}}',
'prefs-email' => 'Used as section name in [[Special:Preferences]].',
-'prefs-rendering' => 'Title of tab in [[Special:Preferences]].',
+'prefs-rendering' => 'Title of tab in [[Special:Preferences]].
+{{Identical|Appearance}}',
'saveprefs' => 'Button for saving changes in the preferences page.
See also:
* @author Александр Сигачёв
* @author Гусейн
* @author ОйЛ
+ * @author Сай
* @author Умар
* @author Чаховіч Уладзіслаў
* @author לערי ריינהארט
'gotaccount' => "Вы уже зарегистрированы? '''$1'''.",
'gotaccountlink' => 'Представьтесь',
'userlogin-resetlink' => 'Забыли данные для входа?',
-'userlogin-resetpassword-link' => 'Сброс пароля',
+'userlogin-resetpassword-link' => 'Сбросить ваш пароль?',
'helplogin-url' => 'Help:Представление системе',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Помощь со входом в систему]]',
'userlogin-loggedin' => 'Вы уже вошли как {{GENDER:$1|$1}}.
'mailerror' => 'Ошибка при отправке почты: $1',
'acct_creation_throttle_hit' => 'За сутки с вашего IP-адреса {{PLURAL:$1|была создана $1 учётная запись участника|было создано $1 учётных записей участников|было создано $1 учётных записей участников}}, что является пределом для данного отрезка времени.
Таким образом, пользователи, обладающие данным IP-адресом, в данный момент больше не могут создавать новых учётных записей.',
-'emailauthenticated' => 'Ваш почтовый адрес подтверждён $2 в $3.',
-'emailnotauthenticated' => 'Ваш адрес электронной почты ещё не был подтверждён, функции вики-движка по работе с эл. почтой отключены.',
+'emailauthenticated' => 'Ваш адрес электронной почты подтверждён $2 в $3.',
+'emailnotauthenticated' => 'Ваш адрес электронной почты ещё не был подтверждён.
+Письма не будут отправляться ни для одной из следующий функций.',
'noemailprefs' => 'Адрес электронной почты не был указан, функции вики-движка по работе с эл. почтой отключены.',
'emailconfirmlink' => 'Подтвердить ваш адрес электронной почты',
'invalidemailaddress' => 'Адрес электронной почты не может быть принят, так как он не соответствует формату.
'gotaccount' => 'Račun že imate? $1.',
'gotaccountlink' => 'Prijavite se',
'userlogin-resetlink' => 'Ste pozabili svoje prijavne podatke?',
-'userlogin-resetpassword-link' => 'Ponastavite svoje geslo',
+'userlogin-resetpassword-link' => 'Ste pozabili svoje geslo?',
'helplogin-url' => 'Help:Prijava',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Pomoč pri prijavi]]',
'userlogin-loggedin' => 'Prijavljeni ste že kot {{GENDER:$1|$1}}.
# Special:PasswordReset
'passwordreset' => 'Ponastavitev gesla',
-'passwordreset-text-one' => 'Izpolnite obrazec, da ponastavite svoje geslo.',
-'passwordreset-text-many' => 'Izpolnite {{PLURAL:$1|polje|enega od polj}}, da ponastavite svoje geslo.',
+'passwordreset-text-one' => 'Da ponastavite svoje geslo, izpolnite naslednji obrazec.',
+'passwordreset-text-many' => '{{PLURAL:$1|Da ponastavite svoje geslo, izpolnite eno od polj.}}',
'passwordreset-legend' => 'Ponastavitev gesla',
'passwordreset-disabled' => 'Ponastavljanje gesla je na tem wikiju onemogočeno.',
'passwordreset-emaildisabled' => 'Na tem wikiju so možnosti e-pošte onemogočene.',
'tags-active-header' => 'Активна?',
'tags-hitcount-header' => 'Означене измене',
'tags-active-yes' => 'Да',
+'tags-active-no' => 'Не',
'tags-edit' => 'уреди',
'tags-hitcount' => '$1 {{PLURAL:$1|измена|измене|измена}}',
'tags-active-header' => 'Aktivna?',
'tags-hitcount-header' => 'Označene izmene',
'tags-active-yes' => 'Da',
+'tags-active-no' => 'Ne',
'tags-edit' => 'uredi',
'tags-hitcount' => '$1 {{PLURAL:$1|izmena|izmene|izmena}}',
'logentry-delete-delete' => '$1 je {{GENDER:$2|obrisao|obrisala}} stranicu $3',
'logentry-delete-restore' => '$1 je {{GENDER:$2|vratio|vratila}} stranicu $3',
'logentry-delete-event' => '$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|događaja|$5 daogađaja}} u dnevniku na $3: $4',
-'logentry-delete-revision' => '$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|izmene|$5 izmjena}} na stranici $3: $4',
+'logentry-delete-revision' => '$1 je {{GENDER:$2|promenio|promenila}} vidljivost {{PLURAL:$5|izmene|$5 izmena}} na stranici $3: $4',
'logentry-delete-event-legacy' => '$1 je {{GENDER:$2|promenio|promenila}} vidljivost događaja u dnevniku na $3',
'logentry-delete-revision-legacy' => '$1 je {{GENDER:$2|promenio|promenila}} vidljivost izmena na stranici $3',
'logentry-suppress-delete' => '$1 je {{GENDER:$2|potisnuo|potisnula}} stranicu $3',
# User preference toggles
'tog-underline' => 'లంకె క్రీగీత:',
'tog-justify' => 'పేరాలను ఇరు పక్కలా సమానంగా సర్దు',
-'tog-hideminor' => 'à°\87à°\9fà±\80వలి మారà±\8dà°ªà±\81లలà±\8b à°\9aà°¿à°¨à±\8dà°¨ మారà±\8dà°ªà±\81లనà±\81 దాà°\9aà°¿à°ªà±\86à°\9fà±\8dà°\9fà±\81',
-'tog-hidepatrolled' => 'à°\87à°\9fà±\80వలి మారà±\8dà°ªà±\81లలà±\8b నిà°\98à°¾ à°\89à°¨à±\8dà°¨ మారà±\8dà°ªà±\81లనà±\81 దాà°\9aà°¿à°ªà±\86à°\9fà±\8dà°\9fà±\81',
-'tog-newpageshidepatrolled' => 'à°\95à±\8aà°¤à±\8dà°¤ à°ªà±\87à°\9cà±\80à°² à°\9cాబితా à°¨à±\81à°\82à°\9aà°¿ నిà°\98à°¾ à°\89à°¨à±\8dà°¨ à°ªà±\87à°\9cà±\80లనà±\81 దాà°\9aà°¿à°ªà±\86à°\9fà±\8dà°\9fà±\81',
+'tog-hideminor' => 'ఇటీవలి మార్పులలో చిన్న మార్పులను దాచు',
+'tog-hidepatrolled' => 'ఇటీవలి మార్పులలో నిఘా ఉన్న మార్పులను దాచు',
+'tog-newpageshidepatrolled' => 'కొత్త పేజీల జాబితా నుంచి నిఘా ఉన్న పేజీలను దాచు',
'tog-extendwatchlist' => 'కేవలం ఇటీవలి మార్పులే కాక, మార్పులన్నీ చూపించటానికి నా వీక్షణా జాబితాను పెద్దది చేయి',
'tog-usenewrc' => 'ఇటీవలి మార్పులు మరియు విక్షణ జాబితాలలో మార్పులను పేజీ వారిగా చూపించు (జావాస్క్రిప్టు అవసరం)',
-'tog-numberheadings' => 'à°¶à±\80à°°à±\8dà°·à°¿à°\95à°²à°\95à±\81 à°\86à°\9fà±\8bమాà°\9fà°¿à°\95à±\8dâ\80\8cà°\97à°¾ వరà±\81à°¸ à°¸à°\82à°\96à±\8dయలà±\81 à°ªà±\86à°\9fà±\8dà°\9fు',
+'tog-numberheadings' => 'à°¶à±\80à°°à±\8dà°·à°¿à°\95à°²à°\95à±\81 à°\85à°ªà±\8dà°°à°®à±\87à°¯à°\82à°\97à°¾ వరà±\81à°¸ à°¸à°\82à°\96à±\8dయలà±\81 à°\9aà±\87à°°à±\8dà°\9aు',
'tog-showtoolbar' => 'దిద్దుబాట్లు చేసేటప్పుడు, అందుకు సహాయపడే పరికరాలపెట్టెను చూపించు (జావాస్క్రిప్టు)',
'tog-editondblclick' => 'డబుల్ క్లిక్కు చేసినప్పుడు పేజీని మార్చు (జావాస్క్రిప్టు)',
-'tog-editsection' => '[మారà±\8dà°\9aà±\81] లిà°\82à°\95à±\81 à°¦à±\8dవారా విà°à°¾à°\97à°\82 మారà±\8dà°ªà±\81 à°\95ావాలి',
+'tog-editsection' => '[మారà±\8dà°\9aà±\81] లిà°\82à°\95à±\81 à°¦à±\8dవారా విà°à°¾à°\97à°\82 మారà±\8dà°ªà±\81 à°\9aà±\87తనà°\82',
'tog-editsectiononrightclick' => 'విభాగం పేరు మీద కుడి క్లిక్కుతో విభాగం మార్పు కావాలి (జావాస్క్రిప్టు)',
'tog-showtoc' => 'విషయసూచిక చూపించు (3 కంటే ఎక్కువ శీర్షికలున్న పేజీలకు)',
'tog-rememberpassword' => 'ఈ విహారిణిలో నా ప్రవేశాన్ని గుర్తుంచుకో (గరిష్ఠంగా $1 {{PLURAL:$1|రోజు|రోజుల}}కి)',
'tog-watchcreations' => 'నేను సృష్టించే పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు',
'tog-watchdefault' => 'నేను మార్చే పేజీలను మరియు దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు',
-'tog-watchmoves' => 'నేను తరలించిన పేజీలను దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు',
-'tog-watchdeletion' => 'నేను తొలగించిన పేజీలను దస్త్రాలను నా వీక్షణ జాబితాకు చేర్చు',
+'tog-watchmoves' => 'à°¨à±\87à°¨à±\81 తరలిà°\82à°\9aà°¿à°¨ à°ªà±\87à°\9cà±\80లనà±\81 మరియà±\81 దసà±\8dà°¤à±\8dరాలనà±\81 నా à°µà±\80à°\95à±\8dà°·à°£ à°\9cాబితాà°\95à±\81 à°\9aà±\87à°°à±\8dà°\9aà±\81',
+'tog-watchdeletion' => 'à°¨à±\87à°¨à±\81 à°¤à±\8aà°²à°\97à°¿à°\82à°\9aà°¿à°¨ à°ªà±\87à°\9cà±\80లనà±\81 మరియà±\81 దసà±\8dà°¤à±\8dరాలనà±\81 నా à°µà±\80à°\95à±\8dà°·à°£ à°\9cాబితాà°\95à±\81 à°\9aà±\87à°°à±\8dà°\9aà±\81',
'tog-minordefault' => 'ప్రత్యేకంగా తెలుపనంతవరకూ నా మార్పులను చిన్న మార్పులుగా గుర్తించు',
-'tog-previewontop' => 'à°µà±\8dయాసà°\82 మారà±\8dà°ªà±\81à°² తరà±\81వాత à°\8eలావà±\81à°\82à°\9fà±\81à°\82à°¦à±\8b మారà±\8dà°ªà±\81à°²â\80\8c బాà°\95à±\8dà°¸à±\81à°\95à±\81 పైన చూపు',
-'tog-previewonfirst' => 'దిదà±\8dదిబాà°\9fà±\8dà°²à±\81 à°\9aà±\87సిన à°µà±\8dయాసానà±\8dని à°à°¦à±\8dరపరిà°\9aà±\87 à°®à±\81à°\82à°¦à±\81 à°\8eలా à°µà±\81à°\82à°\9fà±\81à°\82à°¦à±\8b à°\92à°\95సారి చూపించు',
-'tog-nocache' => 'విహారిణిలో పుటల కాషింగుని అచేతనంచేయి',
-'tog-enotifwatchlistpages' => 'నా à°µà±\80à°\95à±\8dషణాà°\9cాబితా à°²à±\8bని à°ªà±\87à°\9cà±\80 à°²à±\87దా దసà±\8dà°¤à±\8dà°°à°\82 మారినపà±\81à°¡à±\81 నాà°\95à±\81 à°\88-à°®à±\86యిలà±\81 à°ªà°\82పిà°\82à°\9aà±\81',
-'tog-enotifusertalkpages' => 'నా à°\9aà°°à±\8dà°\9aà°¾ à°ªà±\87à°\9cà±\80à°²à±\8b మారà±\8dà°ªà±\81à°²à±\81 à°\9cà°°à°¿à°\97ినపà±\81à°¡à±\81 నాà°\95à±\81 à°\88-à°®à±\86యిలà±\81 à°ªà°\82పిà°\82à°\9aà±\81',
-'tog-enotifminoredits' => 'à°ªà±\87à°\9cà±\80à°²à±\81 మరియà±\81 దసà±\8dà°¤à±\8dరాలà°\95à±\81 à°\9cà°°à°¿à°\97à±\87 à°\9aà°¿à°¨à±\8dà°¨ మారà±\8dà°ªà±\81à°²à°\95à±\81 à°\95à±\82à°¡à°¾ నాà°\95à±\81 à°\88-à°®à±\86యిలà±\81à°¨à±\81 à°ªà°\82పిà°\82à°\9aà±\81',
+'tog-previewontop' => 'à°µà±\8dయాసà°\82 మారà±\8dà°ªà±\81à°² à°®à±\81à°¨à±\81à°\9aà±\82à°ªà±\81 సవరిà°\82à°\9aà±\81 à°ªà±\86à°\9fà±\8dà°\9fà±\86 పైన చూపు',
+'tog-previewonfirst' => 'à°®à±\8aà°¦à°\9fà°¿ దిదà±\8dà°¦à±\81బాà°\9fà±\81 à°\9aà±\87సినపà±\81à°¡à±\81 à°µà±\8dయాసపà±\81 à°®à±\81à°¨à±\81à°\9aà±\82à°ªà±\81 చూపించు',
+'tog-nocache' => 'విహారిణిలో పుటల స్థానికనకలును(కాషింగు) అచేతనం',
+'tog-enotifwatchlistpages' => 'నా వీక్షణాజాబితా లోని పేజీ లేదా దస్త్రం మారినపుడు నాకు ఈ-మెయిలు పంపు',
+'tog-enotifusertalkpages' => 'నా చర్చా పేజీలో మార్పులు జరిగినపుడు నాకు ఈ-మెయిలు పంపు',
+'tog-enotifminoredits' => 'పేజీలు మరియు దస్త్రాలకు జరిగే చిన్న మార్పులకు కూడా నాకు ఈ-మెయిలును పంపు',
'tog-enotifrevealaddr' => 'గమనింపు మెయిళ్ళలో నా ఈ-మెయిలు చిరునామాను చూపించు',
-'tog-shownumberswatching' => 'à°µà±\80à°\95à±\8dà°·à°\95à±\81à°² à°¸à°\82à°\96à±\8dయనà±\81 à°\9aà±\82పిà°\82à°\9aà±\81',
+'tog-shownumberswatching' => 'వీక్షకుల సంఖ్యను చూపు',
'tog-oldsig' => 'ప్రస్తుత సంతకం:',
'tog-fancysig' => 'సంతకాన్ని వికీపాఠ్యంగా తీసుకో (ఆటోమెటిక్ లింకు లేకుండా)',
'tog-uselivepreview' => 'రాస్తున్నదానిని ఎప్పటికప్పుడు సరిచూడండి (జావాస్క్రిప్టు) (పరీక్షాదశలో ఉంది)',
'gotaccount' => "Ви вже зареєстровані? '''$1'''.",
'gotaccountlink' => 'Увійдіть',
'userlogin-resetlink' => 'Забули дані, потрібні для входу?',
-'userlogin-resetpassword-link' => 'СкинÑ\83Ñ\82и паÑ\80олÑ\8c',
+'userlogin-resetpassword-link' => 'Ð\97абÑ\83ли паÑ\80олÑ\8c?',
'helplogin-url' => 'Help:Вхід до системи',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Допомога в реєстрації]]',
'userlogin-loggedin' => 'Ви вже увійшли як {{GENDER:$1|$1}}.
'mailerror' => 'Помилка при відправці пошти: $1',
'acct_creation_throttle_hit' => 'Відвідувачі з вашої IP-адреси вже створили $1 {{PLURAL:$1|обліковий запис|облікових записи|облікових записів}} за останню добу, що є максимумом для цього відрізка часу.
Таким чином, користувачі з цієї IP-адреси не можуть на цей момент створювати нових облікових записів.',
-'emailauthenticated' => 'Ð\90дÑ\80еÑ\81Ñ\83 ваÑ\88оÑ\97 елекÑ\82Ñ\80онноÑ\97 поÑ\88Ñ\82и пÑ\96дÑ\82веÑ\80джено $2 о $3.',
-'emailnotauthenticated' => 'Адресу вашої електронної пошти <strong>ще не підтверджено</strong>, функції вікі-двигуна роботи з ел. поштою відключені.',
+'emailauthenticated' => 'Ð\92аÑ\88Ñ\83 адÑ\80еÑ\81Ñ\83 елекÑ\82Ñ\80онноÑ\97 поÑ\88Ñ\82и бÑ\83ло пÑ\96дÑ\82веÑ\80джено на $2 о $3.',
+'emailnotauthenticated' => 'Адресу вашої електронної пошти ще не підтверджено. Жодна лист не буде надіслано для будь-якої з наступних функцій.',
'noemailprefs' => 'Адресу електронної пошти не вказано, функції вікі роботи з ел. поштою відключені.',
'emailconfirmlink' => 'Підтвердити адресу вашої електронної пошти',
'invalidemailaddress' => 'Уведена адреса не може бути прийнята, бо вона не відповідає формату адрес електронної пошти.
'gotaccount' => "Đã mở tài khoản rồi? '''$1'''.",
'gotaccountlink' => 'Đăng nhập',
'userlogin-resetlink' => 'Quên mất thông tin đăng nhập?',
-'userlogin-resetpassword-link' => 'Đặt lại mật khẩu của bạn',
+'userlogin-resetpassword-link' => 'Quên mật khẩu?',
'helplogin-url' => 'Help:Đăng nhập',
'userlogin-helplink' => '[[{{MediaWiki:helplogin-url}}|Trợ giúp đăng nhập]]',
'userlogin-loggedin' => 'Bạn đã đăng nhập với tên {{GENDER:$1}}$1.
'revdelete-hide-restricted' => 'Ẩn giấu thông tin khỏi các Quản lý lẫn thành viên khác',
'revdelete-radio-same' => '(không đổi)',
'revdelete-radio-set' => 'Có',
-'revdelete-radio-unset' => 'Không',
+'revdelete-radio-unset' => 'Ẩn',
'revdelete-suppress' => 'Che dữ liệu đối với bảo quản viên cũng như các thành viên khác',
'revdelete-unsuppress' => 'Bỏ các hạn chế trên các phiên bản được phục hồi',
'revdelete-log' => 'Lý do:',
* @author O
* @author Reedy
* @author Wu-chinese.com
+ * @author Xiaomingyan
* @author Yfdyh000
* @author 十弌
*/
# Book sources
'booksources' => '书源',
-'booksources-search-legend' => '搜索网络书源',
+'booksources-search-legend' => '搜索图书来源',
'booksources-go' => '去',
# Special:Log
'customjsprotected' => '您没有权限编辑此JavaScript页面,因为它包含另一位用户的个人设置。',
'mycustomcssprotected' => '您没有权限编辑这个 CSS 页面。',
'mycustomjsprotected' => '您没有权限编辑这个 JavaScript 页面。',
-'myprivateinfoprotected' => '您没有权限来编辑您的私人信息。',
+'myprivateinfoprotected' => '你没有权限编辑你的私人信息。',
'mypreferencesprotected' => '您没有权限来编辑您的个人设置。',
'ns-specialprotected' => '特殊页面不可编辑。',
'titleprotected' => '此标题已被[[User:$1|$1]]保护以防止创建。理由是“$2”。',
'content-failed-to-parse' => '未能将 $2 内容转换为 $1:$3',
'invalid-content-data' => '无效的内容数据',
'content-not-allowed-here' => '[[$2]]页面上不允许“$1”内容',
-'editwarning-warning' => '离开这个页面会令您遗失之前的所有更改。若您已经登入,您可在您参数设置的“编辑”节中关闭此警告。',
+'editwarning-warning' => '离开本页面可能导致你失去任何你已经作出的更改。如果你处于登录状态,你可以在你的设置的“编辑”部分停用该警告。',
# Content models
-'content-model-wikitext' => 'wiki语法',
+'content-model-wikitext' => 'wiki文本',
'content-model-text' => '纯文本',
'content-model-javascript' => 'JavaScript',
'content-model-css' => 'CSS',
'yourrealname' => '真实姓名:',
'yourlanguage' => '语言:',
'yourvariant' => '内容语言变种:',
-'prefs-help-variant' => '您希望用于显示本站内容的语种或拼写语系。',
+'prefs-help-variant' => '你希望用于显示该wiki的内容页面的语言变种或正字法。',
'yournick' => '新签名:',
'prefs-help-signature' => '讨论页面上的评论应该使用“<nowiki>~~~~</nowiki>”签名,它会自动转换为你的签名及时间戳。',
'badsig' => '错误的原始签名。请检查HTML标签。',
'right-bot' => '被视为自动过程',
'right-nominornewtalk' => '不使小编辑在讨论页面引发新信息提示',
'right-apihighlimits' => '在API查询中使用更高的限制',
-'right-writeapi' => '使用书写API',
+'right-writeapi' => '使用写入API',
'right-delete' => '删除页面',
'right-bigdelete' => '删除有大型历史的页面',
'right-deletelogentry' => '删除和恢复特定的日志项目',
'right-editusercssjs' => '编辑其他用户的CSS和JavaScript文件',
'right-editusercss' => '编辑其他用户的CSS文件',
'right-edituserjs' => '编辑其他用户的JavaScript文件',
-'right-editmyusercss' => '编辑您自己的用户 CSS 文件',
-'right-editmyuserjs' => '编辑您自己的用户 JavaScript 文件',
+'right-editmyusercss' => '编辑你自己的用户CSS文件',
+'right-editmyuserjs' => '编辑你自己的用户JavaScript文件',
'right-viewmywatchlist' => '查看你的监视列表',
'right-editmywatchlist' => '编辑您的监视列表。请注意即使没有这种权利,某些操作仍将添加页面。',
-'right-viewmyprivateinfo' => '查看您自己的私人数据 (如电子邮件地址、 真实姓名)',
-'right-editmyprivateinfo' => '编辑您自己的私人数据 (如电子邮件地址、 真实姓名)',
+'right-viewmyprivateinfo' => '查看你自己的私人数据(如电子邮件地址、真实姓名)',
+'right-editmyprivateinfo' => '编辑你自己的私人数据(如电子邮件地址、真实姓名)',
'right-editmyoptions' => '编辑您的个人设置',
'right-rollback' => '快速回退最后编辑特定页面的用户的编辑',
'right-markbotedits' => '标记回退编辑为机器人编辑',
'action-reupload' => '覆盖本文件',
'action-reupload-shared' => '覆盖共享文件库的本文件',
'action-upload_by_url' => '从URL上传本文件',
-'action-writeapi' => '使用书写API',
+'action-writeapi' => '使用写入API',
'action-delete' => '删除本页',
'action-deleterevision' => '删除本版本',
'action-deletedhistory' => '查看本页面被删除的历史',
'action-editmywatchlist' => '编辑你的监视列表',
'action-viewmywatchlist' => '查看你的监视列表',
'action-viewmyprivateinfo' => '查看您的私人信息',
-'action-editmyprivateinfo' => '编辑您的私人信息',
+'action-editmyprivateinfo' => '编辑你的私人信息',
# Recent changes
'nchanges' => '$1个更改',
'upload_source_file' => '(您计算机上的一个文件)',
# Special:ListFiles
-'listfiles-summary' => '本特殊页面显示所有上传的文件。',
+'listfiles-summary' => '本特殊页面展示所有上传的文件。',
'listfiles_search_for' => '按媒体名称搜索:',
'imgfile' => '文件',
'listfiles' => '文件列表',
'randompage-nopages' => '在以下{{PLURAL:$2|名字空间}}中没有页面:$1。',
# Random page in category
-'randomincategory' => '分类中的随机页面',
+'randomincategory' => '分类中随机页面',
'randomincategory-invalidcategory' => '“$1”不是一个有效的分类名称。',
'randomincategory-nopages' => '[[:Category:$1]]中没有页面。',
-'randomincategory-selectcategory' => '从分类获取随机页面:$1 $2。',
-'randomincategory-selectcategory-submit' => 'æ\98¾ç¤º',
+'randomincategory-selectcategory' => '获取随机页面从分类:$1 $2。',
+'randomincategory-selectcategory-submit' => 'æ\8f\90交',
# Random redirect
'randomredirect' => '随机重定向',
'statistics-users' => '注册[[Special:ListUsers|用户]]',
'statistics-users-active' => '活跃用户',
'statistics-users-active-desc' => '在前$1天中操作过的用户',
-'statistics-mostpopular' => 'æµ\8fè§\88æ\9c\80å¤\9aç\9a\84页面',
+'statistics-mostpopular' => 'æ\9c\80å¤\9aæ\9f¥ç\9c\8b页面',
'pageswithprop' => '有页面属性的页面',
'pageswithprop-legend' => '有页面属性的页面',
'withoutinterwiki-legend' => '前缀',
'withoutinterwiki-submit' => '显示',
-'fewestrevisions' => '版本最少页面',
+'fewestrevisions' => '有最少版本的页面',
# Miscellaneous special pages
'nbytes' => '$1字节',
'mostlinked' => '最多链接页面',
'mostlinkedcategories' => '最多链接分类',
'mostlinkedtemplates' => '最多链接模板',
-'mostcategories' => 'æ\9c\80å¤\9aå\88\86ç±»页面',
+'mostcategories' => 'æ\9c\89æ\9c\80å¤\9aå\88\86ç±»ç\9a\84页面',
'mostimages' => '最多链接文件',
-'mostinterwikis' => 'æ\9c\80å¤\9aè·¨è¯è¨\80é\93¾æ\8e¥页面',
-'mostrevisions' => 'æ\9c\80å¤\9aç\89\88æ\9c¬页面',
+'mostinterwikis' => 'æ\9c\89æ\9c\80å¤\9aè·¨wikiç\9a\84页面',
+'mostrevisions' => 'æ\9c\89æ\9c\80å¤\9aç\89\88æ\9c¬ç\9a\84页面',
'prefixindex' => '所有有前缀的页面',
'prefixindex-namespace' => '所有有前缀的页面($1名字空间)',
'prefixindex-strip' => '在列表中除去前缀',
'querypage-disabled' => '本特殊页面因性能问题而停用。',
# Book sources
-'booksources' => '网络书源',
+'booksources' => '图书来源',
'booksources-search-legend' => '搜索图书来源',
'booksources-isbn' => 'ISBN:',
'booksources-go' => '提交',
-'booksources-text' => '以ä¸\8bæ\98¯ä¸\80äº\9bç½\91ç»\9c书åº\97ç\9a\84é\93¾æ\8e¥å\88\97表ï¼\8cå\85¶ä¸å\8f¯è\83½æ\9c\89æ\82¨è¦\81æ\89¾ç\9a\84书ç±\8d的更多信息:',
+'booksources-text' => 'ä¸\8bé\9d¢æ\98¯é\94\80å\94®æ\96°ä¹¦å\92\8cäº\8cæ\89\8b书ç\9a\84å\85¶ä»\96ç½\91ç«\99ç\9a\84é\93¾æ\8e¥ç\9a\84å\88\97表ï¼\8cä¹\9få\8f¯è\83½æ\9c\89å\85³äº\8eä½ æ£å\9c¨å¯»æ\89¾ç\9a\84å\9b¾ä¹¦的更多信息:',
'booksources-invalid-isbn' => '提供的ISBN号码并不正确,请检查原始复制来源号码是否有误。',
# Special:Log
# Special:ListGroupRights
'listgrouprights' => '用户组权限',
-'listgrouprights-summary' => '以下面是一个在这个维基中所定义出来的用户权限列表,以及它们的访问权。
-更多有关个别权限的细节可以在[[{{MediaWiki:Listgrouprights-helppage}}|这里]]找到。',
+'listgrouprights-summary' => '以下是在本wiki定义的用户组及它们的相关访问权限的列表。可能有关于单个权限的[[{{MediaWiki:Listgrouprights-helppage}}|附加信息]]。',
'listgrouprights-key' => '说明:
* <span class="listgrouprights-granted">被授予的权限</span>
* <span class="listgrouprights-revoked">被取消的权限</span>',
'specialpages-group-changes' => '最近更改与日志',
'specialpages-group-media' => '媒体文件报告与上传',
'specialpages-group-users' => '用户与权限',
-'specialpages-group-highuse' => '高度使用页面',
+'specialpages-group-highuse' => '高使用页面',
'specialpages-group-pages' => '页面列表',
'specialpages-group-pagetools' => '页面工具',
'specialpages-group-wiki' => '数据与工具',
// Delete all the corresponding thumbnails...
$dir = $tempRepo->getZonePath( 'thumb' );
- $iterator = $tempRepo->getBackend()->getFileList( array( 'dir' => $dir ) );
+ $iterator = $tempRepo->getBackend()->getFileList( array( 'dir' => $dir, 'adviseStat' => 1 ) );
$this->output( "Deleting old thumbnails...\n" );
$i = 0;
foreach ( $iterator as $file ) {
--- /dev/null
+<?php
+/**
+ * Convenience maintenance script wrapper, useful for scripts
+ * or extensions located outside of standard locations.
+ *
+ * To use, give the maintenance script as a relative or full path.
+ *
+ * Example usage:
+ *
+ * If your pwd is mediawiki base folder:
+ * php maintenance/runScript.php extensions/Wikibase/lib/maintenance/dispatchChanges.php
+ *
+ * If your pwd is maintenance folder:
+ * php runScript.php ../extensions/Wikibase/lib/maintenance/dispatchChanges.php
+ *
+ * Or full path:
+ * php /var/www/mediawiki/maintenance/runScript.php maintenance/runJobs.php
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ * @file
+ * @ingroup Maintenance
+ */
+$IP = getenv( 'MW_INSTALL_PATH' );
+
+if ( $IP === false ) {
+ $IP = dirname( __DIR__ );
+
+ putenv( "MW_INSTALL_PATH=$IP" );
+}
+
+require_once "$IP/maintenance/Maintenance.php";
+
+if ( !isset( $argv[1] ) ) {
+ fwrite( STDERR, "This script requires a maintainance script as an argument.\n"
+ . "Usage: runScript.php extensions/Wikibase/lib/maintenance/dispatchChanges\n" );
+ exit( 1 );
+}
+
+$scriptFilename = $argv[1];
+array_shift( $argv );
+
+$scriptFile = realpath( $scriptFilename );
+
+if ( !$scriptFile ) {
+ fwrite( STDERR, "The MediaWiki script file \"{$scriptFilename}\" does not exist.\n" );
+ exit( 1 );
+}
+
+require_once $scriptFile;
*/
addCSS: function ( text ) {
var s = mw.loader.addStyleTag( text );
- return s.sheet || s;
+ return s.sheet || s.styleSheet || s;
},
/**
msg = 'Use jQuery instead';
// Ignored dummy values
-mw.log.deprecate( win, 'doneOnloadHook', undefined );
-mw.log.deprecate( win, 'onloadFuncts', [] );
-mw.log.deprecate( win, 'runOnloadHook', $.noop );
-mw.log.deprecate( win, 'changeText', $.noop );
-mw.log.deprecate( win, 'killEvt', $.noop );
-mw.log.deprecate( win, 'addHandler', $.noop );
-mw.log.deprecate( win, 'hookEvent', $.noop );
-mw.log.deprecate( win, 'addClickHandler', $.noop );
-mw.log.deprecate( win, 'removeHandler', $.noop );
-mw.log.deprecate( win, 'getElementsByClassName', function () { return []; } );
-mw.log.deprecate( win, 'getInnerText', function () { return ''; } );
+mw.log.deprecate( win, 'doneOnloadHook', undefined, msg );
+mw.log.deprecate( win, 'onloadFuncts', [], msg );
+mw.log.deprecate( win, 'runOnloadHook', $.noop, msg );
+mw.log.deprecate( win, 'changeText', $.noop, msg );
+mw.log.deprecate( win, 'killEvt', $.noop, msg );
+mw.log.deprecate( win, 'addHandler', $.noop, msg );
+mw.log.deprecate( win, 'hookEvent', $.noop, msg );
+mw.log.deprecate( win, 'addClickHandler', $.noop, msg );
+mw.log.deprecate( win, 'removeHandler', $.noop, msg );
+mw.log.deprecate( win, 'getElementsByClassName', function () { return []; }, msg );
+mw.log.deprecate( win, 'getInnerText', function () { return ''; }, msg );
// Run a function after the window onload event is fired
mw.log.deprecate( win, 'addOnloadHook', function ( hookFunct ) {
// run immediately instead of queueing.
hookFunct();
}
-} );
+}, msg );
$( win ).on( 'load', function () {
var i, functs;
mw.log.deprecate( win, 'tooltipAccessKeyRegexp', /\[(alt-)?(.)\]$/, msg );
mw.log.deprecate( win, 'updateTooltipAccessKeys', mw.util.updateTooltipAccessKeys, msg );
mw.log.deprecate( win, 'addPortletLink', mw.util.addPortletLink, msg );
-mw.log.deprecate( win, 'appendCSS', mw.util.addCSS );
+mw.log.deprecate( win, 'appendCSS', mw.util.addCSS, msg );
/**
* Wikipage import methods
$this->object->add( 'string1', 'string one' );
$this->object->add( 'string2', 'string two' );
$this->object->add( 'integer', 0 );
+ $this->object->add( 'float', 0.0 );
$this->object->add( 'intnull', 0, FormOptions::INTNULL );
}
private function assertGuessInt( $data ) {
$this->guess( FormOptions::INT, $data );
}
+ private function assertGuessFloat( $data ) {
+ $this->guess( FormOptions::FLOAT, $data );
+ }
private function assertGuessString( $data ) {
$this->guess( FormOptions::STRING, $data );
}
$this->assertGuessInt( 5 );
$this->assertGuessInt( 0x0F );
+ $this->assertGuessFloat( 0.0 );
+ $this->assertGuessFloat( 1.5 );
+ $this->assertGuessFloat( 1e3 );
+
$this->assertGuessString( 'true' );
$this->assertGuessString( 'false' );
$this->assertGuessString( '5' );
$this->assertGuessString( '0' );
+ $this->assertGuessString( '1.5' );
}
/**
*/
class FakeDatabaseMysqlBase extends DatabaseMysqlBase {
// From DatabaseBase
+ function __construct() {}
protected function closeConnection() {}
protected function doQuery( $sql ) {}
/**
* Test the CDB reader/writer
- * @covers CdbWriter_PHP
- * @covers CdbWriter_DBA
+ * @covers CdbWriterPHP
+ * @covers CdbWriterDBA
*/
class CdbTest extends MediaWikiTestCase {
$phpcdbfile = $this->getNewTempFile();
$dbacdbfile = $this->getNewTempFile();
- $w1 = new CdbWriter_PHP( $phpcdbfile );
- $w2 = new CdbWriter_DBA( $dbacdbfile );
+ $w1 = new CdbWriterPHP( $phpcdbfile );
+ $w2 = new CdbWriterDBA( $dbacdbfile );
$data = array();
for ( $i = 0; $i < 1000; $i++ ) {
'same hash'
);
- $r1 = new CdbReader_PHP( $phpcdbfile );
- $r2 = new CdbReader_DBA( $dbacdbfile );
+ $r1 = new CdbReaderPHP( $phpcdbfile );
+ $r2 = new CdbReaderDBA( $dbacdbfile );
foreach ( $data as $key => $value ) {
if ( $key === '' ) {