* QUnit.newMwEnvironment now supports passing a custom setup and/or teardown function.
Arguments signature has changed. First arguments is now an options object of which
'config' can be a property. Previously 'config' itself was the first and only argument.
+* New getCreator and getOldestRevision methods added to WikiPage class
=== Bug fixes in 1.20 ===
* (bug 30245) Use the correct way to construct a log page title.
* Include body text only; none of the image extras
*/
public function render() {
- $this->getContext()->setArticleBodyOnly( true );
+ $this->getContext()->getOutput()->setArticleBodyOnly( true );
parent::view();
}
$this->mRestrictions['edit'] = explode( ',', trim( $temp[0] ) );
$this->mRestrictions['move'] = explode( ',', trim( $temp[0] ) );
} else {
- $this->mRestrictions[$temp[0]] = explode( ',', trim( $temp[1] ) );
+ $restriction = trim( $temp[1] );
+ if( $restriction != '' ) { //some old entries are empty
+ $this->mRestrictions[$temp[0]] = explode( ',', $restriction );
+ }
}
}
$module->profileOut();
if ( !$this->mInternalMode ) {
+ //append Debug information
+ MWDebug::appendDebugInfoToApiResult( $this->getContext(), $this->getResult() );
+
// Print result data
$this->printResult( false );
}
}
}
+ // add user name, if needed
+ if ( $this->fld_user ) {
+ $this->addTables( 'user' );
+ $this->addJoinConds( array( 'user' => Revision::userJoinCond() ) );
+ $this->addFields( Revision::selectUserFields() );
+ }
+
// Bug 24166 - API error when using rvprop=tags
$this->addTables( 'revision' );
* to explicitly call MWDebug::init() to enabled them.
*
* @todo Profiler support
+ *
+ * @since 1.19
*/
class MWDebug {
/**
* Enabled the debugger and load resource module.
* This is called by Setup.php when $wgDebugToolbar is true.
+ *
+ * @since 1.19
*/
public static function init() {
self::$enabled = true;
* Add ResourceLoader modules to the OutputPage object if debugging is
* enabled.
*
+ * @since 1.19
* @param $out OutputPage
*/
public static function addModules( OutputPage $out ) {
*
* @todo Add support for passing objects
*
+ * @since 1.19
* @param $str string
*/
public static function log( $str ) {
/**
* Returns internal log array
+ * @since 1.19
* @return array
*/
public static function getLog() {
/**
* Clears internal log array and deprecation tracking
+ * @since 1.19
*/
public static function clearLog() {
self::$log = array();
/**
* Adds a warning entry to the log
*
+ * @since 1.19
* @param $msg
* @param int $callerOffset
* @return mixed
/**
* Adds a depreciation entry to the log, along with a backtrace
*
+ * @since 1.19
* @param $function
* @param $version
* @param $component
* This is a method to pass messages from wfDebug to the pretty debugger.
* Do NOT use this method, use MWDebug::log or wfDebug()
*
+ * @since 1.19
* @param $str string
*/
public static function debugMsg( $str ) {
/**
* Begins profiling on a database query
*
+ * @since 1.19
* @param $sql string
* @param $function string
* @param $isMaster bool
/**
* Calculates how long a query took.
*
+ * @since 1.19
* @param $id int
*/
public static function queryTime( $id ) {
/**
* Returns the HTML to add to the page for the toolbar
*
+ * @since 1.19
* @param $context IContextSource
* @return string
*/
return '';
}
- global $wgVersion, $wgRequestTime;
MWDebug::log( 'MWDebug output complete' );
+ $debugInfo = self::getDebugInfo( $context );
+
+ // Cannot use OutputPage::addJsConfigVars because those are already outputted
+ // by the time this method is called.
+ $html = Html::inlineScript(
+ ResourceLoader::makeLoaderConditionalScript(
+ ResourceLoader::makeConfigSetScript( array( 'debugInfo' => $debugInfo ) )
+ )
+ );
+
+ return $html;
+ }
+
+ /**
+ * Append the debug info to given ApiResult
+ *
+ * @param $context IContextSource
+ * @param $result ApiResult
+ */
+ public static function appendDebugInfoToApiResult( IContextSource $context, ApiResult $result ) {
+ if ( !self::$enabled ) {
+ return;
+ }
+
+ MWDebug::log( 'MWDebug output complete' );
+ $debugInfo = self::getDebugInfo( $context );
+
+ $result->setIndexedTagName( $debugInfo, 'debuginfo' );
+ $result->setIndexedTagName( $debugInfo['log'], 'line' );
+ foreach( $debugInfo['debugLog'] as $index => $debugLogText ) {
+ $vals = array();
+ ApiResult::setContent( $vals, $debugLogText );
+ $debugInfo['debugLog'][$index] = $vals; //replace
+ }
+ $result->setIndexedTagName( $debugInfo['debugLog'], 'msg' );
+ $result->setIndexedTagName( $debugInfo['queries'], 'query' );
+ $result->setIndexedTagName( $debugInfo['includes'], 'queries' );
+ $result->addValue( array(), 'debuginfo', $debugInfo );
+ }
+
+ /**
+ * Returns the HTML to add to the page for the toolbar
+ *
+ * @param $context IContextSource
+ * @return array
+ */
+ public static function getDebugInfo( IContextSource $context ) {
+ if ( !self::$enabled ) {
+ return array();
+ }
+
+ global $wgVersion, $wgRequestTime;
$request = $context->getRequest();
- $debugInfo = array(
+ return array(
'mwVersion' => $wgVersion,
'phpVersion' => PHP_VERSION,
'gitRevision' => GitInfo::headSHA1(),
'memoryPeak' => $context->getLanguage()->formatSize( memory_get_peak_usage() ),
'includes' => self::getFilesIncluded( $context ),
);
-
- // Cannot use OutputPage::addJsConfigVars because those are already outputted
- // by the time this method is called.
- $html = Html::inlineScript(
- ResourceLoader::makeLoaderConditionalScript(
- ResourceLoader::makeConfigSetScript( array( 'debugInfo' => $debugInfo ) )
- )
- );
-
- return $html;
}
}
return "mwstore://{$this->name}";
}
+ /**
+ * Get the file journal object for this backend
+ *
+ * @return FileJournal
+ */
+ final public function getJournal() {
+ return $this->fileJournal;
+ }
+
/**
* Check if a given path is a "mwstore://" path.
* This does not do any further validation or any existence checks.
return $this->backends[$name]['instance'];
}
+ /**
+ * Get the config array for a backend object with a given name
+ *
+ * @param $name string
+ * @return Array
+ * @throws MWException
+ */
+ public function config( $name ) {
+ if ( !isset( $this->backends[$name] ) ) {
+ throw new MWException( "No backend defined with the name `$name`." );
+ }
+ $class = $this->backends[$name]['class'];
+ return array( 'class' => $class ) + $this->backends[$name]['config'];
+ }
+
/**
* Get an appropriate backend object from a storage path
*
* FileBackendStore class, but with these additional settings:
* 'class' : The name of the backend class
* 'isMultiMaster' : This must be set for one backend.
+ * 'template: : If given a backend name, this will use
+ * the config of that backend as a template.
+ * Values specified here take precedence.
* 'syncChecks' : Integer bitfield of internal backend sync checks to perform.
* Possible bits include self::CHECK_SIZE and self::CHECK_TIME.
* The checks are done before allowing any file operations.
// Construct backends here rather than via registration
// to keep these backends hidden from outside the proxy.
foreach ( $config['backends'] as $index => $config ) {
+ if ( isset( $config['template'] ) ) {
+ // Config is just a modified version of a registered backend's.
+ // This should only be used when that config is used only be this backend.
+ $config = $config + FileBackendGroup::singleton()->config( $config['template'] );
+ }
$name = $config['name'];
if ( isset( $namesUsed[$name] ) ) { // don't break FileOp predicates
throw new MWException( "Two or more backends defined with the name $name." );
$contInfo = array(); // (resolved container name => cache value)
// Get all cache entries for these container cache keys...
- $values = $this->memCache->getBatch( array_keys( $contNames ) );
+ $values = $this->memCache->getMulti( array_keys( $contNames ) );
foreach ( $values as $cacheKey => $val ) {
$contInfo[$contNames[$cacheKey]] = $val;
}
}
}
// Get all cache entries for these container cache keys...
- $values = $this->memCache->getBatch( array_keys( $pathNames ) );
+ $values = $this->memCache->getMulti( array_keys( $pathNames ) );
foreach ( $values as $cacheKey => $val ) {
if ( is_array( $val ) ) {
$this->trimCache(); // limit memory
protected $auth; // Swift authentication handler
protected $authTTL; // integer seconds
protected $swiftAnonUser; // string; username to handle unauthenticated requests
+ protected $swiftUseCDN; // boolean; whether CloudFiles CDN is enabled
protected $maxContCacheSize = 300; // integer; max containers with entries
/** @var CF_Connection */
* swiftKey : Swift authentication key for the above user
* swiftAuthTTL : Swift authentication TTL (seconds)
* swiftAnonUser : Swift user used for end-user requests (account:username)
+ * swiftUseCDN : Whether a Cloud Files Content Delivery Network is set up
* shardViaHashLevels : Map of container names to sharding config with:
* 'base' : base of hash characters, 16 or 36
* 'levels' : the number of hash levels (and digits)
$this->shardViaHashLevels = isset( $config['shardViaHashLevels'] )
? $config['shardViaHashLevels']
: '';
+ $this->swiftUseCDN = isset( $config['swiftUseCDN'] )
+ ? $config['swiftUseCDN']
+ : false;
// Cache container info to mask latency
$this->memCache = wfGetMainCache();
}
if ( !empty( $params['async'] ) ) { // deferred
$handle = $obj->write_async( $params['content'] );
$status->value = new SwiftFileOpHandle( $this, $params, 'Create', $handle );
+ $status->value->affectedObjects[] = $obj;
} else { // actually write the object in Swift
$obj->write( $params['content'] );
+ $this->purgeCDNCache( array( $obj ) );
}
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
} catch ( BadContentTypeException $e ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} catch ( CloudFilesException $e ) { // some other exception?
$handle = $obj->write_async( $fp, filesize( $params['src'] ), true );
$status->value = new SwiftFileOpHandle( $this, $params, 'Store', $handle );
$status->value->resourcesToClose[] = $fp;
+ $status->value->affectedObjects[] = $obj;
}
} else { // actually write the object in Swift
$obj->load_from_filename( $params['src'], true ); // calls $obj->write()
+ $this->purgeCDNCache( array( $obj ) );
}
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
} catch ( BadContentTypeException $e ) {
$status->fatal( 'backend-fail-contenttype', $params['dst'] );
} catch ( IOException $e ) {
// (b) Actually copy the file to the destination
try {
+ $dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
if ( !empty( $params['async'] ) ) { // deferred
$handle = $sContObj->copy_object_to_async( $srcRel, $dContObj, $dstRel );
$status->value = new SwiftFileOpHandle( $this, $params, 'Copy', $handle );
+ $status->value->affectedObjects[] = $dstObj;
} else { // actually write the object in Swift
$sContObj->copy_object_to( $srcRel, $dContObj, $dstRel );
+ $this->purgeCDNCache( array( $dstObj ) );
}
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
} catch ( NoSuchObjectException $e ) { // source object does not exist
$status->fatal( 'backend-fail-copy', $params['src'], $params['dst'] );
} catch ( CloudFilesException $e ) { // some other exception?
// (b) Actually move the file to the destination
try {
+ $srcObj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD
+ $dstObj = new CF_Object( $dContObj, $dstRel, false, false ); // skip HEAD
if ( !empty( $params['async'] ) ) { // deferred
$handle = $sContObj->move_object_to_async( $srcRel, $dContObj, $dstRel );
$status->value = new SwiftFileOpHandle( $this, $params, 'Move', $handle );
+ $status->value->affectedObjects[] = $srcObj;
+ $status->value->affectedObjects[] = $dstObj;
} else { // actually write the object in Swift
$sContObj->move_object_to( $srcRel, $dContObj, $dstRel );
+ $this->purgeCDNCache( array( $srcObj, $dstObj ) );
}
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
} catch ( NoSuchObjectException $e ) { // source object does not exist
$status->fatal( 'backend-fail-move', $params['src'], $params['dst'] );
} catch ( CloudFilesException $e ) { // some other exception?
try {
$sContObj = $this->getContainer( $srcCont );
+ $srcObj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD
if ( !empty( $params['async'] ) ) { // deferred
$handle = $sContObj->delete_object_async( $srcRel );
$status->value = new SwiftFileOpHandle( $this, $params, 'Delete', $handle );
+ $status->value->affectedObjects[] = $srcObj;
} else { // actually write the object in Swift
$sContObj->delete_object( $srcRel );
+ $this->purgeCDNCache( array( $srcObj ) );
}
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
} catch ( NoSuchContainerException $e ) {
$status->fatal( 'backend-fail-delete', $params['src'] );
} catch ( NoSuchObjectException $e ) {
// (b) Create container as needed
try {
$contObj = $this->createContainer( $fullCont );
+ // Make container public to end-users...
if ( $this->swiftAnonUser != '' ) {
- // Make container public to end-users...
$status->merge( $this->setContainerAccess(
$contObj,
array( $this->auth->username, $this->swiftAnonUser ), // read
array( $this->auth->username ) // write
) );
}
+ if ( $this->swiftUseCDN ) { // Rackspace style CDN
+ $contObj->make_public();
+ }
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
return $status;
protected function doSecureInternal( $fullCont, $dir, array $params ) {
$status = Status::newGood();
- if ( $this->swiftAnonUser != '' ) {
- // Restrict container from end-users...
- try {
- // doPrepareInternal() should have been called,
- // so the Swift container should already exist...
- $contObj = $this->getContainer( $fullCont ); // normally a cache hit
- // NoSuchContainerException not thrown: container must exist
- if ( !isset( $contObj->mw_wasSecured ) ) {
- $status->merge( $this->setContainerAccess(
- $contObj,
- array( $this->auth->username ), // read
- array( $this->auth->username ) // write
- ) );
- // @TODO: when php-cloudfiles supports container
- // metadata, we can make use of that to avoid RTTs
- $contObj->mw_wasSecured = true; // avoid useless RTTs
- }
- } catch ( CloudFilesException $e ) { // some other exception?
- $this->handleException( $e, $status, __METHOD__, $params );
+ // Restrict container from end-users...
+ try {
+ // doPrepareInternal() should have been called,
+ // so the Swift container should already exist...
+ $contObj = $this->getContainer( $fullCont ); // normally a cache hit
+ // NoSuchContainerException not thrown: container must exist
+
+ // Make container private to end-users...
+ if ( $this->swiftAnonUser != '' && !isset( $contObj->mw_wasSecured ) ) {
+ $status->merge( $this->setContainerAccess(
+ $contObj,
+ array( $this->auth->username ), // read
+ array( $this->auth->username ) // write
+ ) );
+ // @TODO: when php-cloudfiles supports container
+ // metadata, we can make use of that to avoid RTTs
+ $contObj->mw_wasSecured = true; // avoid useless RTTs
+ }
+ if ( $this->swiftUseCDN && $contObj->is_public() ) { // Rackspace style CDN
+ $contObj->make_private();
}
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
+ } catch ( CloudFilesException $e ) { // some other exception?
+ $this->handleException( $e, $status, __METHOD__, $params );
}
return $status;
$status = Status::newGood();
$scopeLockS = $this->getScopedFileLocks( array( $path ), LockManager::LOCK_UW, $status );
if ( $status->isOK() ) {
- $tmpFile = $this->getLocalCopy( array( 'src' => $path, 'latest' => 1 ) );
+ # Do not stat the file in getLocalCopy() to avoid infinite loops
+ $tmpFile = $this->getLocalCopy( array( 'src' => $path, 'latest' => 1, 'nostat' => 1 ) );
if ( $tmpFile ) {
$hash = $tmpFile->getSha1Base36();
if ( $hash !== false ) {
$data = false;
try {
$sContObj = $this->getContainer( $srcCont );
- $obj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD request
+ $obj = new CF_Object( $sContObj, $srcRel, false, false ); // skip HEAD
$data = $obj->read( $this->headersFromParams( $params ) );
} catch ( NoSuchContainerException $e ) {
} catch ( CloudFilesException $e ) { // some other exception?
try {
$output = fopen( 'php://output', 'wb' );
- $obj = new CF_Object( $cont, $srcRel, false, false ); // skip HEAD request
+ $obj = new CF_Object( $cont, $srcRel, false, false ); // skip HEAD
$obj->stream( $output, $this->headersFromParams( $params ) );
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status, __METHOD__, $params );
return null;
}
- if ( !$this->fileExists( $params ) ) {
+ # Check the recursion guard to avoid loops when filling metadata
+ if ( empty( $params['nostat'] ) && !$this->fileExists( $params ) ) {
return null;
}
try { // catch exceptions; update status
$function = '_getResponse' . $fileOpHandles[$index]->call;
$this->$function( $cfOp, $status, $fileOpHandles[$index]->params );
+ $this->purgeCDNCache( $fileOpHandles[$index]->affectedObjects );
} catch ( CloudFilesException $e ) { // some other exception?
$this->handleException( $e, $status,
__CLASS__ . ":$function", $fileOpHandles[$index]->params );
return $req->execute(); // should return 204
}
+ /**
+ * Purge the CDN cache of affected objects if CDN caching is enabled
+ *
+ * @param $objects Array List of CF_Object items
+ * @return void
+ */
+ public function purgeCDNCache( array $objects ) {
+ if ( $this->swiftUseCDN ) { // Rackspace style CDN
+ foreach ( $objects as $object ) {
+ try {
+ $object->purge_from_cdn();
+ } catch ( CDNNotEnabledException $e ) {
+ // CDN not enabled; nothing to see here
+ } catch ( CloudFilesException $e ) {
+ $this->handleException( $e, null, __METHOD__,
+ array( 'cont' => $object->container->name, 'obj' => $object->name ) );
+ }
+ }
+ }
+ }
+
/**
* Get a connection to the Swift proxy
*
class SwiftFileOpHandle extends FileBackendStoreOpHandle {
/** @var CF_Async_Op */
public $cfOp;
+ /** @var Array */
+ public $affectedObjects = array();
public function __construct( $backend, array $params, $call, CF_Async_Op $cfOp ) {
$this->backend = $backend;
* Construct a new instance from configuration.
* $config includes:
* 'wiki' : wiki name to use for LoadBalancer
- *
+ *
* @param $config Array
*/
protected function __construct( array $config ) {
/**
* @see FileJournal::logChangeBatch()
- * @return Status
+ * @return Status
*/
protected function doLogChangeBatch( array $entries, $batchId ) {
$status = Status::newGood();
- $dbw = $this->getMasterDB();
- if ( !$dbw ) {
+ try {
+ $dbw = $this->getMasterDB();
+ } catch ( DBError $e ) {
$status->fatal( 'filejournal-fail-dbconnect', $this->backend );
return $status;
}
+
$now = wfTimestamp( TS_UNIX );
$data = array();
return $status;
}
+ /**
+ * @see FileJournal::doGetChangeEntries()
+ * @return Array
+ * @throws DBError
+ */
+ protected function doGetChangeEntries( $start, $limit ) {
+ $dbw = $this->getMasterDB();
+
+ $res = $dbw->select( 'filejournal', '*',
+ array(
+ 'fj_backend' => $this->backend,
+ 'fj_id >= ' . $dbw->addQuotes( (int)$start ) ), // $start may be 0
+ __METHOD__,
+ array_merge( array( 'ORDER BY' => 'fj_id ASC' ),
+ $limit ? array( 'LIMIT' => $limit ) : array() )
+ );
+
+ $entries = array();
+ foreach ( $res as $row ) {
+ $item = array();
+ foreach ( (array)$row as $key => $value ) {
+ $item[substr( $key, 3 )] = $value; // "fj_op" => "op"
+ }
+ $entries[] = $item;
+ }
+
+ return $entries;
+ }
+
/**
* @see FileJournal::purgeOldLogs()
* @return Status
+ * @throws DBError
*/
protected function doPurgeOldLogs() {
$status = Status::newGood();
}
$dbw = $this->getMasterDB();
- if ( !$dbw ) {
- $status->fatal( 'filejournal-fail-dbconnect', $this->backend );
- return $status;
- }
$dbCutoff = $dbw->timestamp( time() - 86400 * $this->ttlDays );
- try {
- $dbw->begin();
- $dbw->delete( 'filejournal',
- array( 'fj_timestamp < ' . $dbw->addQuotes( $dbCutoff ) ),
- __METHOD__
- );
- $dbw->commit();
- } catch ( DBError $e ) {
- $status->fatal( 'filejournal-fail-dbquery', $this->backend );
- return $status;
- }
+ $dbw->begin();
+ $dbw->delete( 'filejournal',
+ array( 'fj_timestamp < ' . $dbw->addQuotes( $dbCutoff ) ),
+ __METHOD__
+ );
+ $dbw->commit();
return $status;
}
/**
* Get a master connection to the logging DB
- *
- * @return DatabaseBase|null
+ *
+ * @return DatabaseBase
+ * @throws DBError
*/
protected function getMasterDB() {
- try {
- $lb = wfGetLBFactory()->newMainLB();
- return $lb->getConnection( DB_MASTER, array(), $this->wiki );
- } catch ( DBConnectionError $e ) {
- return null;
- }
+ $lb = wfGetLBFactory()->newMainLB();
+ return $lb->getConnection( DB_MASTER, array(), $this->wiki );
}
}
* Construct a new instance from configuration.
* $config includes:
* 'ttlDays' : days to keep log entries around (false means "forever")
- *
+ *
* @param $config Array
*/
protected function __construct( array $config ) {
/**
* Create an appropriate FileJournal object from config
- *
+ *
* @param $config Array
* @param $backend string A registered file backend name
* @return FileJournal
/**
* Get a statistically unique ID string
- *
+ *
* @return string <9 char TS_MW timestamp in base 36><22 random base 36 chars>
*/
final public function getTimestampedUUID() {
* path : The storage path of the file
* newSha1 : The final base 36 SHA-1 of the file
* Note that 'false' should be used as the SHA-1 for non-existing files.
- *
+ *
* @param $entries Array List of file operations (each an array of parameters)
* @param $batchId string UUID string that identifies the operation batch
* @return Status
/**
* @see FileJournal::logChangeBatch()
- *
+ *
* @param $entries Array List of file operations (each an array of parameters)
* @param $batchId string UUID string that identifies the operation batch
* @return Status
*/
abstract protected function doLogChangeBatch( array $entries, $batchId );
+ /**
+ * Get an array of file change log entries.
+ * A starting change ID and/or limit can be specified.
+ *
+ * The result as a list of associative arrays, each having:
+ * id : unique, monotonic, ID for this change
+ * batch_uuid : UUID for an operation batch
+ * backend : the backend name
+ * op : primitive operation (create,update,delete)
+ * path : affected storage path
+ * path_sha1 : base 36 sha1 of the affected storage path
+ * timestamp : TS_MW timestamp of the batch change
+
+ * Also, $next is updated to the ID of the next entry.
+ *
+ * @param $start integer Starting change ID or null
+ * @param $limit integer Maximum number of items to return
+ * @param &$next string
+ * @return Array
+ */
+ final public function getChangeEntries( $start = null, $limit = 0, &$next = null ) {
+ $entries = $this->doGetChangeEntries( $start, $limit ? $limit + 1 : 0 );
+ if ( $limit && count( $entries ) > $limit ) {
+ $last = array_pop( $entries ); // remove the extra entry
+ $next = $last['id']; // update for next call
+ } else {
+ $next = null; // end of list
+ }
+ return $entries;
+ }
+
+ /**
+ * @see FileJournal::getChangeEntries()
+ * @return Array
+ */
+ abstract protected function doGetChangeEntries( $start, $limit );
+
/**
* Purge any old log entries
- *
- * @return Status
+ *
+ * @return Status
*/
final public function purgeOldLogs() {
return $this->doPurgeOldLogs();
class NullFileJournal extends FileJournal {
/**
* @see FileJournal::logChangeBatch()
- * @return Status
+ * @return Status
*/
protected function doLogChangeBatch( array $entries, $batchId ) {
return Status::newGood();
}
+ /**
+ * @see FileJournal::doGetChangeEntries()
+ * @return Array
+ */
+ protected function doGetChangeEntries( $start, $limit ) {
+ return array();
+ }
+
/**
* @see FileJournal::purgeOldLogs()
* @return Status
* @param $keys Array List of strings
* @return Array
*/
- public function getBatch( array $keys ) {
+ public function getMulti( array $keys ) {
$res = array();
foreach ( $keys as $key ) {
$res[$key] = $this->get( $key );
* @param $keys Array
* @return Array
*/
- public function getBatch( array $keys ) {
- $this->debugLog( 'getBatch(' . implode( ', ', $keys ) . ')' );
+ public function getMulti( array $keys ) {
+ $this->debugLog( 'getMulti(' . implode( ', ', $keys ) . ')' );
$callback = array( $this, 'encodeKey' );
$result = $this->client->getMulti( array_map( $callback, $keys ) );
return $this->checkResult( false, $result );
* @param $keys Array
* @return Array
*/
- public function getBatch( array $keys ) {
+ public function getMulti( array $keys ) {
$callback = array( $this, 'encodeKey' );
return $this->client->get_multi( array_map( $callback, $keys ) );
}
}
public function get( $key ) {
- $values = $this->getBatch( array( $key ) );
+ $values = $this->getMulti( array( $key ) );
return $values[$key];
}
- public function getBatch( array $keys ) {
+ public function getMulti( array $keys ) {
$values = array(); // array of (key => value)
$keysByTableName = array();
}
// Generate output
+ $isRaw = false;
foreach ( $modules as $name => $module ) {
/**
* @var $module ResourceLoaderModule
$missing[] = $name;
unset( $modules[$name] );
}
+ $isRaw |= $module->isRaw();
wfProfileOut( __METHOD__ . '-' . $name );
}
// Update module states
- if ( $context->shouldIncludeScripts() ) {
+ if ( $context->shouldIncludeScripts() && !$context->getRaw() && !$isRaw ) {
// Set the state of modules loaded as only scripts to ready
- if ( count( $modules ) && $context->getOnly() === 'scripts'
- && !isset( $modules['startup'] ) )
- {
+ if ( count( $modules ) && $context->getOnly() === 'scripts' ) {
$out .= self::makeLoaderStateScript(
array_fill_keys( array_keys( $modules ), 'ready' ) );
}
protected $only;
protected $version;
protected $hash;
+ protected $raw;
/* Methods */
$this->debug = $request->getFuzzyBool( 'debug', $wgResourceLoaderDebug );
$this->only = $request->getVal( 'only' );
$this->version = $request->getVal( 'version' );
+ $this->raw = $request->getFuzzyBool( 'raw' );
$skinnames = Skin::getSkinNames();
// If no skin is specified, or we don't recognize the skin, use the default skin
return $this->version;
}
+ /**
+ * @return bool
+ */
+ public function getRaw() {
+ return $this->raw;
+ }
+
/**
* @return bool
*/
protected $position = 'bottom';
/** Boolean: Link to raw files in debug mode */
protected $debugRaw = true;
+ /** Boolean: Whether mw.loader.state() call should be omitted */
+ protected $raw = false;
/**
* Array: Cache for mtime
* @par Usage:
break;
// Single booleans
case 'debugRaw':
+ case 'raw':
$this->{$member} = (bool) $option;
break;
}
return $this->dependencies;
}
+ /**
+ * @return bool
+ */
+ public function isRaw() {
+ return $this->raw;
+ }
+
/**
* Get the last modified timestamp of this module.
*
return 'bottom';
}
+ /**
+ * Whether this module's JS expects to work without the client-side ResourceLoader module.
+ * Returning true from this function will prevent mw.loader.state() call from being
+ * appended to the bottom of the script.
+ *
+ * @return bool
+ */
+ public function isRaw() {
+ return false;
+ }
+
/**
* Get the loader JS for this module, if set.
*
/* Methods */
+ /**
+ * @return bool
+ */
+ public function isRaw() {
+ return true;
+ }
+
/**
* @param $context ResourceLoaderContext
* @return string
* @return stringthe real path if it was a virtual URL
*/
function getRealPath( $srcPath ) {
+ wfProfileIn( __METHOD__ );
$repo = RepoGroup::singleton()->getLocalRepo();
if ( $repo->isVirtualUrl( $srcPath ) ) {
// @TODO: just make uploads work with storage paths
// UploadFromStash loads files via virtuals URLs
$tmpFile = $repo->getLocalCopy( $srcPath );
$tmpFile->bind( $this ); // keep alive with $thumb
+ wfProfileOut( __METHOD__ );
return $tmpFile->getPath();
}
+ wfProfileOut( __METHOD__ );
return $srcPath;
}
* @return mixed self::OK or else an array with error information
*/
public function verifyUpload() {
+ wfProfileIn( __METHOD__ );
+
/**
* If there was no filename or a zero size given, give up quick.
*/
if( $this->isEmptyFile() ) {
+ wfProfileOut( __METHOD__ );
return array( 'status' => self::EMPTY_FILE );
}
*/
$maxSize = self::getMaxUploadSize( $this->getSourceType() );
if( $this->mFileSize > $maxSize ) {
+ wfProfileOut( __METHOD__ );
return array(
'status' => self::FILE_TOO_LARGE,
'max' => $maxSize,
*/
$verification = $this->verifyFile();
if( $verification !== true ) {
+ wfProfileOut( __METHOD__ );
return array(
'status' => self::VERIFICATION_ERROR,
'details' => $verification
*/
$result = $this->validateName();
if( $result !== true ) {
+ wfProfileOut( __METHOD__ );
return $result;
}
$error = '';
if( !wfRunHooks( 'UploadVerification',
- array( $this->mDestName, $this->mTempPath, &$error ) ) ) {
+ array( $this->mDestName, $this->mTempPath, &$error ) ) )
+ {
+ wfProfileOut( __METHOD__ );
return array( 'status' => self::HOOK_ABORTED, 'error' => $error );
}
+ wfProfileOut( __METHOD__ );
return array( 'status' => self::OK );
}
*/
protected function verifyMimeType( $mime ) {
global $wgVerifyMimeType;
+ wfProfileIn( __METHOD__ );
if ( $wgVerifyMimeType ) {
wfDebug ( "\n\nmime: <$mime> extension: <{$this->mFinalExtension}>\n\n");
global $wgMimeTypeBlacklist;
if ( $this->checkFileExtension( $mime, $wgMimeTypeBlacklist ) ) {
+ wfProfileOut( __METHOD__ );
return array( 'filetype-badmime', $mime );
}
# XXX: Missing extension will be caught by validateName() via getTitle()
if ( $this->mFinalExtension != '' && !$this->verifyExtension( $mime, $this->mFinalExtension ) ) {
+ wfProfileOut( __METHOD__ );
return array( 'filetype-mime-mismatch', $this->mFinalExtension, $mime );
}
$ieTypes = $magic->getIEMimeTypes( $this->mTempPath, $chunk, $extMime );
foreach ( $ieTypes as $ieType ) {
if ( $this->checkFileExtension( $ieType, $wgMimeTypeBlacklist ) ) {
+ wfProfileOut( __METHOD__ );
return array( 'filetype-bad-ie-mime', $ieType );
}
}
}
+ wfProfileOut( __METHOD__ );
return true;
}
*/
protected function verifyFile() {
global $wgAllowJavaUploads, $wgDisableUploadScriptChecks;
+ wfProfileIn( __METHOD__ );
+
# get the title, even though we are doing nothing with it, because
# we need to populate mFinalExtension
$this->getTitle();
$mime = $this->mFileProps[ 'file-mime' ];
$status = $this->verifyMimeType( $mime );
if ( $status !== true ) {
+ wfProfileOut( __METHOD__ );
return $status;
}
# check for htmlish code and javascript
if ( !$wgDisableUploadScriptChecks ) {
if( self::detectScript( $this->mTempPath, $mime, $this->mFinalExtension ) ) {
+ wfProfileOut( __METHOD__ );
return array( 'uploadscripted' );
}
if( $this->mFinalExtension == 'svg' || $mime == 'image/svg+xml' ) {
if( $this->detectScriptInSvg( $this->mTempPath ) ) {
+ wfProfileOut( __METHOD__ );
return array( 'uploadscripted' );
}
}
$errors = $zipStatus->getErrorsArray();
$error = reset( $errors );
if ( $error[0] !== 'zip-wrong-format' ) {
+ wfProfileOut( __METHOD__ );
return $error;
}
}
if ( $this->mJavaDetected ) {
+ wfProfileOut( __METHOD__ );
return array( 'uploadjava' );
}
}
# Scan the uploaded file for viruses
$virus = $this->detectVirus( $this->mTempPath );
if ( $virus ) {
+ wfProfileOut( __METHOD__ );
return array( 'uploadvirus', $virus );
}
$handlerStatus = $handler->verifyUpload( $this->mTempPath );
if ( !$handlerStatus->isOK() ) {
$errors = $handlerStatus->getErrorsArray();
+ wfProfileOut( __METHOD__ );
return reset( $errors );
}
}
wfRunHooks( 'UploadVerifyFile', array( $this, $mime, &$status ) );
if ( $status !== true ) {
+ wfProfileOut( __METHOD__ );
return $status;
}
wfDebug( __METHOD__ . ": all clear; passing.\n" );
+ wfProfileOut( __METHOD__ );
return true;
}
*/
public function checkWarnings() {
global $wgLang;
+ wfProfileIn( __METHOD__ );
$warnings = array();
$warnings['duplicate-archive'] = $archivedImage->getName();
}
+ wfProfileOut( __METHOD__ );
return $warnings;
}
* @return Status indicating the whether the upload succeeded.
*/
public function performUpload( $comment, $pageText, $watch, $user ) {
+ wfProfileIn( __METHOD__ );
+
$status = $this->getLocalFile()->upload(
$this->mTempPath,
$comment,
if ( $watch ) {
$user->addWatch( $this->getLocalFile()->getTitle() );
}
-
wfRunHooks( 'UploadComplete', array( &$this ) );
}
+ wfProfileOut( __METHOD__ );
return $status;
}
*/
public function stashFile() {
// was stashSessionFile
+ wfProfileIn( __METHOD__ );
+
$stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash();
$file = $stash->stashFile( $this->mTempPath, $this->getSourceType() );
$this->mLocalFile = $file;
+
+ wfProfileOut( __METHOD__ );
return $file;
}
*/
public static function detectScript( $file, $mime, $extension ) {
global $wgAllowTitlesInSVG;
+ wfProfileIn( __METHOD__ );
# ugly hack: for text files, always look at the entire file.
# For binary field, just check the first K.
$chunk = strtolower( $chunk );
if( !$chunk ) {
+ wfProfileOut( __METHOD__ );
return false;
}
# check for HTML doctype
if ( preg_match( "/<!DOCTYPE *X?HTML/i", $chunk ) ) {
+ wfProfileOut( __METHOD__ );
return true;
}
foreach( $tags as $tag ) {
if( false !== strpos( $chunk, $tag ) ) {
wfDebug( __METHOD__ . ": found something that may make it be mistaken for html: $tag\n" );
+ wfProfileOut( __METHOD__ );
return true;
}
}
# look for script-types
if( preg_match( '!type\s*=\s*[\'"]?\s*(?:\w*/)?(?:ecma|java)!sim', $chunk ) ) {
wfDebug( __METHOD__ . ": found script types\n" );
+ wfProfileOut( __METHOD__ );
return true;
}
# look for html-style script-urls
if( preg_match( '!(?:href|src|data)\s*=\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) {
wfDebug( __METHOD__ . ": found html-style script urls\n" );
+ wfProfileOut( __METHOD__ );
return true;
}
# look for css-style script-urls
if( preg_match( '!url\s*\(\s*[\'"]?\s*(?:ecma|java)script:!sim', $chunk ) ) {
wfDebug( __METHOD__ . ": found css-style script urls\n" );
+ wfProfileOut( __METHOD__ );
return true;
}
wfDebug( __METHOD__ . ": no scripts found\n" );
+ wfProfileOut( __METHOD__ );
return false;
}
}
- # use handler attribute with remote / data / script
+ # use handler attribute with remote / data / script
if( $stripped == 'handler' && preg_match( '!(http|https|data|script):!sim', $value ) ) {
wfDebug( __METHOD__ . ": Found svg setting handler with remote/data/script '$attrib'='$value' in uploaded file.\n" );
return true;
*/
public static function detectVirus( $file ) {
global $wgAntivirus, $wgAntivirusSetup, $wgAntivirusRequired, $wgOut;
+ wfProfileIn( __METHOD__ );
if ( !$wgAntivirus ) {
wfDebug( __METHOD__ . ": virus scanner disabled\n" );
+ wfProfileOut( __METHOD__ );
return null;
}
wfDebug( __METHOD__ . ": unknown virus scanner: $wgAntivirus\n" );
$wgOut->wrapWikiMsg( "<div class=\"error\">\n$1\n</div>",
array( 'virus-badscanner', $wgAntivirus ) );
+ wfProfileOut( __METHOD__ );
return wfMsg( 'virus-unknownscanner' ) . " $wgAntivirus";
}
wfDebug( __METHOD__ . ": failed to scan $file (code $exitCode).\n" );
if ( $wgAntivirusRequired ) {
+ wfProfileOut( __METHOD__ );
return wfMsg( 'virus-scanfailed', array( $exitCode ) );
} else {
+ wfProfileOut( __METHOD__ );
return null;
}
} elseif ( $mappedCode === AV_SCAN_ABORTED ) {
# scan failed because filetype is unknown (probably imune)
wfDebug( __METHOD__ . ": unsupported file type $file (code $exitCode).\n" );
+ wfProfileOut( __METHOD__ );
return null;
} elseif ( $mappedCode === AV_NO_VIRUS ) {
# no virus found
wfDebug( __METHOD__ . ": file passed virus scan.\n" );
+ wfProfileOut( __METHOD__ );
return false;
} else {
$output = trim( $output );
}
wfDebug( __METHOD__ . ": FOUND VIRUS! scanner feedback: $output \n" );
+ wfProfileOut( __METHOD__ );
return $output;
}
}
--- /dev/null
+*.zip
+*.tar.gz
+*.tgz
-#!/usr/bin/python
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @author Philip
import tarfile as tf
def download( url, dest ):
if os.path.isfile( dest ):
- print( 'File %s up to date.' % dest )
+ print( 'File %s is up to date.' % dest )
return
global islinux
if islinux:
+ PHPArray( toSG ) \
+ '\n);'
- f = open( 'ZhConversion.php', 'wb', encoding = 'utf8' )
+ f = open( os.path.join( '..', 'ZhConversion.php' ), 'wb', encoding = 'utf8' )
print ('Writing ZhConversion.php ... ')
f.write( php )
f.close()
- #Remove temp files
- print ('Deleting temp files ... ')
+ # Remove temporary files
+ print ('Deleting temporary files ... ')
os.remove('EZ-Big.txt.in')
os.remove('phrase_lib.txt')
os.remove('tsi.src')
* @author Ouda
* @author Oxydo
* @author Rami.Awad
+ * @author Reedy
* @author Riadismet
* @author Samer
* @author Sami Lab
وفي هذه الحالات، يجب عليك نقل أو دمج محتويات الصفحة يدويا، إذا رغب في ذلك.",
'movearticle' => 'انقل الصفحة:',
-'moveuserpage-warning' => "'''تحذير: أنت على وشك نقل صفحة مستخدم. من فضلك لاحظ أن الصفحة وحدها سوف تنقل وأن المستخدم <u>لن</u> يعاد تسميته.'''",
+'moveuserpage-warning' => "'''تحذير: أنت على وشك نقل صفحة مستخدم. من فضلك لاحظ أن الصفحة وحدها سوف تنقل وأن المستخدم لن يعاد تسميته.'''",
'movenologin' => 'غير مسجل',
'movenologintext' => 'يجب أن تكون مستخدما مسجلا وأن تقوم [[Special:UserLogin|بالدخول]] لكي تنقل صفحة.',
'movenotallowed' => 'أنت لا تمتلك الصلاحية لنقل الصفحات.',
'api-error-verification-error' => 'Был файл боҙолған, йәки дөрөҫ булмаған ҡушымтаһы бар.',
# Durations
-'duration-seconds' => 'секунд',
+'duration-seconds' => '$1 {{PLURAL:$1|секунд|секунд}}',
'duration-minutes' => 'минут',
'duration-hours' => 'сәғәт',
'duration-days' => 'көн',
-'duration-weeks' => 'аҙна',
-'duration-years' => 'йыл',
-'duration-decades' => 'декада',
-'duration-centuries' => 'быуат',
-'duration-millennia' => 'меңйыллыҡ',
+'duration-weeks' => '$1 {{PLURAL:$1|аҙна|аҙналар|аҙна}}',
+'duration-years' => '$1 {{PLURAL:$1|йыл|йылдар}}',
+'duration-decades' => '$1 {{PLURAL:$1|ун көнлөк|ун көнлөктәр}}',
+'duration-centuries' => '$1 {{PLURAL:$1|быуат|быуаттар}}',
+'duration-millennia' => '$1 {{PLURAL:$1|меңйыллыҡ|меңйыллыҡтар}}',
);
'tog-hideminor' => 'Tagóon an mga saradít na paghirá sa nakakaági pa sanáng pagbabàgo',
'tog-hidepatrolled' => 'Tagóon an mga saradít na paghirá sa nakakaági pa sanáng pagbabàgo',
'tog-newpageshidepatrolled' => 'Tagóon an mga pigbabantayán na pahina sa lista nin mga bàgong pahina',
-'tog-extendwatchlist' => 'Palakbangón an lista kan pigbabantayan tangarig mahiling an gabos na angay na pagbabàgo',
-'tog-usenewrc' => 'Paorogón an kaaging pagbabàgo (JavaScript)',
+'tog-extendwatchlist' => 'Palakbangón an taytáy kan babantayan tanganing mahilíng an gabós na angay na pagbàgo',
+'tog-usenewrc' => 'Gamiton an pinauróg na mga nakaaging pagbàgo (kaipohan nin JavaScript)',
'tog-numberheadings' => 'Tolos na pagbílang sa mga pamayohán',
'tog-showtoolbar' => 'Ipahilíng an toolbar nin paghirá (JavaScript)',
'tog-editondblclick' => 'Hirahón sa dobleng paglagatík an mga pahina (JavaScript)',
'tog-editsection' => 'Togótan an paghirá kan seksyon sa paági kan mga takód na [hirá]',
'tog-editsectiononrightclick' => 'Togotan an paghirá kan seksyon sa pag-lagatik sa walá sa mga titulo nin seksyon (JavaScript)',
'tog-showtoc' => 'Ipahilíng an indise kan mga laog (para sa mga pahinang igwang sobra sa 3 pamayohan)',
-'tog-rememberpassword' => 'Giromdomón an mga paglaóg ko sa kompyuter na iní (for a maximum of $1 {{PLURAL:$1|day|days}})',
+'tog-rememberpassword' => 'Giromdomón an mga paglaóg ko sa panlibotlibot na iní (sa nakaaging $1 {{PLURAL:$1|aldaw|mga aldaw}})',
'tog-watchcreations' => 'Idúgang an mga pahinang ginigíbo ko sa pigbabantayan ko',
'tog-watchdefault' => 'Idúgang an mga pahinang pighíhirá ko sa pigbabantayan ko',
'tog-watchmoves' => 'Idúgang an mga pahinang piglilípat ko sa pigbabantayan ko',
'tog-minordefault' => 'Markahán an gabos na paghirá nin sadit na paghirá',
'tog-previewontop' => 'Ipahilíng an patànaw bàgo an kahon nin paghirá',
'tog-previewonfirst' => 'Ipahilíng an patànaw sa enot na paghirá',
-'tog-nocache' => 'Pogólon an pag-abang nin mga pahina',
+'tog-nocache' => 'Pugolon an pag-abáng nin mga pahina',
'tog-enotifwatchlistpages' => 'E-koreohan ako pag pigribayan an pahinang pigbabantayan ko',
'tog-enotifusertalkpages' => 'E-koreohan ako pag pigribáyan an pahina kan sakóng olay',
'tog-enotifminoredits' => 'E-koreohan man giraray ako para sa saradit na paghirá kan mga pahina',
'vector-view-view' => 'Basáhon',
'vector-view-viewsource' => 'Hilingón an ginikánan',
'actions' => 'Mga paghiro',
+'namespaces' => 'Liang-liang',
'errorpagetitle' => 'Salâ',
'returnto' => 'Magbwelta sa $1.',
'page-rss-feed' => '"$1" Hungit na RSS',
'page-atom-feed' => '"$1" Hungit na Atomo',
'feed-atom' => 'Atomo',
-'red-link-title' => '$1 (dai pa naisusurat)',
+'red-link-title' => '$1 (daí pa naisusurat)',
# Short words for each namespace, by default used in the namespace tab in monobook
'nstab-main' => 'Pahina',
'nextn' => 'sunód na {{PLURAL:$1|$1}}',
'viewprevnext' => 'Hilingón ($1 {{int:pipe-separator}} $2) ($3)',
'searchhelp-url' => 'Help:Mga laog',
+'searchprofile-everything' => 'Gabós',
+'searchprofile-articles-tooltip' => 'Hanapon sa $1',
'search-result-size' => '$1 ({{PLURAL:$2|1 tatarámon|$2 mga tatarámon}})',
'search-suggest' => 'Boót mo iyó: $1',
'search-interwiki-more' => '(dakol pa)',
'mostcategories' => 'Mga artikulong may pinaka dakol na kategorya',
'mostimages' => 'Pinakapigtatakodan na files',
'mostrevisions' => 'Mga artikulong may pinakadakol na pagpakarháy',
-'prefixindex' => 'Murô nin prefiho',
+'prefixindex' => 'Gabós na pahinang igwáng katakód',
'shortpages' => 'Haralìpot na pahina',
'longpages' => 'Mga halabang pahina',
'deadendpages' => 'Mga pahinang mayong luwasan',
# What links here
'whatlinkshere' => 'An nakatakód digdí',
-'whatlinkshere-title' => 'Mga pahinang nakatakod sa $1',
+'whatlinkshere-title' => 'Mga pahinang nakatakód sa $1',
'whatlinkshere-page' => 'Pahina:',
'linkshere' => "An mga minasunod na pahina nakatakod sa '''[[:$1]]''':",
'nolinkshere' => "Mayong pahinang nakatakod sa '''[[:$1]]'''.",
'ipblocklist-no-results' => 'Dai nabagat an hinagad na direccion nin IP o ngaran nin paragamit.',
'blocklink' => 'bagáton',
'unblocklink' => 'paagihon',
+'change-blocklink' => 'sanglián an pagbagat',
'contribslink' => 'mga ambág',
'autoblocker' => 'Enseguidang binagat an saimong direccion nin IP ta kaaaging ginamit ini ni "[[User:$1|$1]]". An rason nin pagbagat ni $1: "$2"',
'blocklogpage' => 'Usip nin pagbagat',
'tooltip-pt-anontalk' => 'Mga olay manonongod sa mga hira halî sa ip na ini',
'tooltip-pt-preferences' => 'Mga kabòtan ko',
'tooltip-pt-watchlist' => 'Lista nin mga pahina na pigbabantayan an mga pagbabàgo',
-'tooltip-pt-mycontris' => 'Lista kan mga kabòtan ko',
+'tooltip-pt-mycontris' => 'Taytáy kan mga kabòtan ko',
'tooltip-pt-login' => 'Pigaagda kang maglaog, alagad, bako man ining piriritan.',
'tooltip-pt-anonlogin' => 'Pig-aagda kang maglaog, alagad, bakô man ining piriritan.',
'tooltip-pt-logout' => 'Magluwas',
'tooltip-ca-talk' => 'Olay sa pahina nin laog',
'tooltip-ca-edit' => 'Pwede mong hirahón ining pahina. Gamiton tabi an patànaw na butones bago an pagtagama.',
-'tooltip-ca-addsection' => 'Magdugang nin komento sa orólay na ini.',
+'tooltip-ca-addsection' => 'Magdugang nin komento sa urulay na iní.',
'tooltip-ca-viewsource' => 'Sinagangán ining pahina. Mahihilíng mo an ginikanan.',
'tooltip-ca-history' => 'Mga nakaaging bersyon kaining pahina',
'tooltip-ca-protect' => 'Protektahán ining pahina',
'filedelete-archive-read-only' => 'An direktoryong archibo na "$1" dai nasusuratan kan webserver.',
# Browsing diffs
-'previousdiff' => '← Nakaáging kaibhán',
+'previousdiff' => '← Nakaaging kaibhán',
'nextdiff' => 'Kaibhán pa→',
# Media information
'sp-newimages-showfrom' => 'Hilingón an mga retratong nagpopoon sa $1',
# Bad image list
-'bad_image_list' => 'An pormato iyo an minasunod:
+'bad_image_list' => 'An husay iyó an minasunód:
-An mga nakalista sana (mga linyang nagpopoon sa *) an pigkokonsiderar.
-An enot na takod sa linya seguradong sarong takod sa sarong salang file.
-Ano man na takod sa parehong linyang ini pigkokonsiderar na eksepsyon, i.e. mga pahina na may file sa laog nin linya.',
+An mga nakataytáy saná (mga taytáy na nagpopoón sa *) iyó an kaayon.
+An inot na takód sa taytáy kaipohan na saróng takód sa saróng saláng file.
+Anó man na minasunód na takód sa ginikanan na taytáy iyó an kaayon sa mga paglain, i.e. mga pahina na may file na maluwás sa laog kan taytáy.',
# Metadata
'metadata' => 'Metadatos',
'intentionallyblankpage' => 'এই পাতাটি ইচ্ছা করে খালি রাখা হয়েছে',
# External image whitelist
-'external_image_whitelist' => ' #এই লাইন ঠিক যেমন আছে<প্রাক> তেমন রাখুন
+'external_image_whitelist' => ' #এই লাইন ঠিক যেমন আছে<প্রাক> তেমন রাখুন<pre>
#রেগুলার এক্সপ্রেশনের টুকরা নীচে (শুধুমাত্র অংশ / / মধ্যে যে যায়) বসান
#এইগুলি এক্সটার্নাল (hotlinked) ইমেজের URL-এর সাথে মেলানো হবে
#যেগুলি মিলবে, সেগুলি চিত্র হিসাবে প্রদর্শিত হবে, অন্যথায় শুধুমাত্র ইমেজ লিঙ্ক প্রদর্শিত হবে
#যে লাইনের প্রারম্ভে # আছে সেই লাইনগুলি মন্তব্যসমূহ হিসাবে ব্যবহার করা হয়
#এটি কেস-অসংবেদী
-#এই রেখার উপরের regex টুকরা বসান. এই লাইন ঠিক যেমন আছে তেমন রাখুন</ প্রাক>',
+#এই রেখার উপরের regex টুকরা বসান. এই লাইন ঠিক যেমন আছে তেমন রাখুন</pre>',
# Special:Tags
'tag-filter' => '[[Special:Tags|ট্যাগ]] ছাকনী:',
# Diffs
'history-title' => 'Historie verzí stránky „$1“',
+'difference-title' => 'Porovnání verzí stránky „$1“',
+'difference-title-multipage' => 'Porovnání stránek „$1“ a „$2“',
'difference-multipage' => '(Rozdíly mezi stránkami)',
'lineno' => 'Řádka $1:',
'compareselectedversions' => 'Porovnat vybrané verze',
* @author Purodha
* @author Raimond Spekking (Raymond) <raimond.spekking@gmail.com> since January 2007
* @author Red Baron
+ * @author Reedy
* @author Remember the dot
* @author Revolus
* @author Rillke
'gender-unknown' => 'Nicht angegeben',
'gender-male' => 'Männlich',
'gender-female' => 'Weiblich',
-'prefs-help-gender' => 'Optional: Wird unter anderem von der Software für die geschlechtsspezifische Anrede genutzt. Diese Information ist <u>öffentlich</u>.',
+'prefs-help-gender' => 'Optional: Wird unter anderem von der Software für die geschlechtsspezifische Anrede genutzt. Diese Information ist öffentlich.',
'email' => 'E-Mail',
'prefs-help-realname' => 'Optional. Damit kann dein bürgerlicher Name deinen Beiträgen zugeordnet werden.',
'prefs-help-email' => 'Die Angabe einer E-Mail-Adresse ist optional, ermöglicht aber die Zusendung eines Ersatzpasswortes, sofern du dein Passwort vergessen hast.',
'saveusergroups' => 'Gruppenzugehörigkeit ändern',
'userrights-groupsmember' => 'Mitglied von:',
'userrights-groupsmember-auto' => 'Automatisch Mitglied von:',
-'userrights-groups-help' => 'Du kannst die Gruppenzugehörigkeit dieses Benutzers ändern:
-* Ein markiertes Kästchen bedeutet, dass der Benutzer Mitglied dieser Gruppe ist.
-* Ein nichtmarkiertes Kästchen bedeutet, dass der Benutzer nicht Mitglied dieser Gruppe ist.
+'userrights-groups-help' => 'Du kannst die Gruppenzugehörigkeit {{GENDER:$1|dieses Benutzers|dieser Benutzerin}} ändern:
+* Ein markiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} Mitglied dieser Gruppe ist.
+* Ein nichtmarkiertes Kästchen bedeutet, dass {{GENDER:$1|der Benutzer|die Benutzerin}} nicht Mitglied dieser Gruppe ist.
* Ein * bedeutet, dass du das Benutzerrecht nach Erteilung nicht wieder zurücknehmen kannst (oder umgekehrt).',
'userrights-reason' => 'Grund:',
'userrights-no-interwiki' => 'Du hast nicht die erforderliche Berechtigung, um Benutzerrechte in anderen Wikis ändern zu können.',
'filehist-user' => 'Karber',
'filehist-dimensions' => 'Dimensiyoni',
'filehist-filesize' => 'Ebatê dosyayî',
-'filehist-comment' => 'Rexne',
+'filehist-comment' => 'Vatış',
'filehist-missing' => 'Dosya nieseno',
'imagelinks' => 'Gurenayışê dosya',
'linkstoimage' => 'Ena {{PLURAL:$1|pela|$1 pela}} gıreye ena dosya:',
# Diffs
'history-title' => 'Ιστορικό εκδόσεων για τη σελίδα "$1"',
+'difference-title' => 'Διαφορά μεταξύ των αναθεωρήσεων του "$1"',
+'difference-title-multipage' => 'Διαφορά μεταξύ των σελίδων "$1" και "$2"',
'difference-multipage' => '(Διαφορές μεταξύ των σελίδων)',
'lineno' => 'Γραμμή $1:',
'compareselectedversions' => 'Σύγκριση των εκδόσεων που έχουν επιλεγεί',
'proxyblocker-disabled' => 'Η λειτουργία αυτή έχει απενεργοποιηθεί.',
'proxyblockreason' => 'Η διεύθυνση IP σας έχει υποστεί φραγή γιατί είναι open proxy. Παρακαλούμε επικοινωνείστε με τον παροχέα υπηρεσιών Διαδικτύου που χρησιμοποιείτε ή με την τεχνική υποστήριξη, για να θέσετε υπ΄ όψη τους αυτό το σοβαρό θέμα ασφάλειας.',
'proxyblocksuccess' => 'Ολοκληρώθηκε!',
-'sorbsreason' => 'Η διεύθνυση IP σας έχει χαρακτηρισθεί ως open proxy στο DNSBL.',
+'sorbsreason' => 'Η διεύθυνση IP σας έχει χαρακτηρισθεί ως open proxy στο DNSBL.',
'sorbs_create_account_reason' => 'Η διεύθυνση IP σας έχει χαρακτηρισθεί open proxy στο DNSBL. Δεν μπορείτε να δημιουργήσετε λογαριασμό χρήστη.',
'cant-block-while-blocked' => 'Δεν μπορείτε να φράξετε άλλους χρήστες ενώ είστε φραγμένος/η.',
'cant-see-hidden-user' => 'Ο χρήστης που προσπαθείτε να αποκλείσετε έχει ήδη αποκλειστεί και αποκρυφτεί.
* @author Yumeki
* @author Zebulon84
* @author Zetud
+ * @author Zolo
* @author Горан Анђелковић
* @author לערי ריינהארט
*/
'userrights-groupsmember-auto' => 'Membre implicite de :',
'userrights-groups-help' => 'Vous pouvez modifier les groupes auxquels appartient cet utilisateur:
* Une case cochée signifie que l’utilisateur se trouve dans ce groupe.
-* Une case non cochée signifie qu’il ne s’y trouve pas.
+* Une case non cochée signifie qu’{{GENDER:$1|il|elle}} ne s’y trouve pas.
* Un astérisque (*) indique que vous ne pouvez pas retirer ce groupe une fois que vous l’avez ajouté, ou vice-versa.',
'userrights-reason' => 'Motif :',
'userrights-no-interwiki' => 'Vous n’avez pas la permission de modifier des droits d’utilisateurs sur d’autres wikis.',
'upload-curl-error28-text' => 'Le site a mis trop longtemps à répondre. Vérifiez que le site est en ligne, attendez un peu et réessayez. Vous pouvez aussi réessayer à une heure de moindre affluence.',
'license' => 'Licence',
-'license-header' => 'Publié sous licence(s)',
+'license-header' => "Conditions d'utilisation",
'nolicense' => 'Aucune licence sélectionnée',
'license-nopreview' => '(Prévisualisation non disponible)',
'upload_source_url' => ' (une URL valide et accessible publiquement)',
* @author Kaganer
* @author Klenje
* @author MF-Warburg
+ * @author Reedy
* @author Urhixidur
* @author לערי ריינהארט
*/
In chescj câs, tu varâs di movi o unî a man lis informazions contignudis te pagjine di discussion, se tu lu desideris.",
'movearticle' => 'Môf la vôs',
'movenologin' => 'No tu sês jentrât',
-'movenologintext' => 'Tu âs di jessi un utent regjistrât e <a href="{{localurl:Special:UserLogin}}">jentrât</a> par movi une pagjine.',
+'movenologintext' => 'Tu âs di jessi un utent regjistrât e [[Special:UserLogin|jentrât]] par movi une pagjine.',
'movenotallowed' => 'No tu âs i permès che a coventin par movi lis pagjinis.',
'newtitle' => 'Al gnûf titul',
'move-watch' => 'Ten di voli cheste pagjine',
* @author Kwekubo
* @author Moilleadóir
* @author Moydow
+ * @author Reedy
* @author Spacebirdy
* @author Stifle
* @author Tameamseo
Tabhair faoi deara '''nach''' n-athainmneofar an leathanach má tá leathanach ann cheana féin faoin teideal nua, ach amháin más folamh nó atreorú é nó mura bhfuil aon stair athraithe aige cheana.
Mar sin, is féidir leathanach a athainmniú ar ais chuig an teideal a raibh air roimhe má tá botún déanta agat, agus ní féidir leathanach atá ann cheana a fhorscríobh.
-<font color=\"red\">'''Rabhadh!'''</font>
+'''Rabhadh!'''
Is féidir gur dianbheart gan choinne é athrú a dhéanamh ar leathanach móréilimh;
cinntigh go dtuigeann tú na hiarmhairtí go léir roimh dul ar aghaigh.",
'movepagetalktext' => "Aistreofar an leathanach plé go huathoibríoch '''ach ní tharlófar sin''':
* @file
*
* @author Amire80
+ * @author Reedy
* @author Sapral Mikail
* @author Tagir
*/
#Укх # тамагIалгаца дIадувлаш дола мугIанаш, оалам мо лоархаш да.
#МугIанаш яздaтакха каьда да
-#Каст-каста оаламаш укх мугIа лакхе дIаязаде. Из мугI ший долаш тайпара дита<pre>',
+#Каст-каста оаламаш укх мугIа лакхе дIаязаде. Из мугI ший долаш тайпара дита</pre>',
# Special:Tags
'tag-filter' => '[[Special:Tags|Йоазоний]] цIенаярг:',
'columns' => 'Dálkar',
'searchresultshead' => 'Leit',
'resultsperpage' => 'Niðurstöður á síðu',
-'stub-threshold' => 'Þröskuldur fyrir sniði <a href="#" class="stub">stubbatengla</a> (bæt):',
+'stub-threshold' => 'Þröskuldur fyrir <a href="#" class="stub">stubbatengla</a> (bæt):',
'stub-threshold-disabled' => 'Óvirkt',
'recentchangesdays' => 'Fjöldi daga sem nýlegar breytingar ná yfir:',
'recentchangesdays-max' => '(hámark $1 {{PLURAL:$1|dag|daga}})',
'last' => 'aqır.',
'page_first' => 'birinshi',
'page_last' => "aqırg'ı",
-'histlegend' => "Tu'sindirme: salıstırajaq nusqaların'ızdı saylan' ha'mde <Enter> knopkasın yamasa to'mendegi knopkani basın'.<br />
+'histlegend' => "Tu'sindirme: salıstırajaq nusqaların'ızdı saylan' ha'mde Enter knopkasın yamasa to'mendegi knopkani basın'.<br />
Sha'rtli belgiler: (ha'z.) = ha'zirgi nusqasi menen parqı,
(aqır.) = aldıng'ı nusqasi menen parqı, k = kishi o'zgeris",
'history-fieldset-title' => 'Tariyxınan izlew',
Et künnt ussinn, wie ene InterWikiLink,
dat jeiht ävver nit.
Muss De repareere.',
-'perfcached' => 'Di Daate heh noh kumme usem Zweschespeicher (<l lang="en">cache</i>) un künnte nit mieh janz de allerneuste sin.
+'perfcached' => 'Di Daate heh noh kumme usem Zweschespeicher (cache) un künnte nit mieh janz de allerneuste sin.
{{PLURAL:$1|Bloß ein Antwoot es|Nit mieh wi $1 Antwoote sin|Kein Antwoot es}} doh faßjehallde un ze han.',
'perfcachedts' => 'De Daate heenoh kumme usem Zweschespeicher (Cache) un woodte aam $2 öm $3 opjenumme. Se künnte nit janz de allerneuste sin.
{{PLURAL:$4|Bloß ein Antwoot es|Nit mieh wi $4 Antwoote sind|Kein Antwoot es}} doh ze han.',
'updated' => '(Hate rojanekirin)',
'note' => "'''Nîşe:'''",
'previewnote' => "'''Ji bîr neke ku ev bi tenê çavdêriyek e, ev rûpel hîn nehatiye tomarkirin!'''",
+'continue-editing' => 'Guhertinê bidomîne',
'editing' => 'Biguherîne: "$1"',
'editingsection' => 'Tê guherandin: $1 (beş)',
'editingcomment' => '$1 (şîrove) tê guherandin.',
'revdelete-no-file' => 'De Fichier deen ugi war gëtt et net.',
'revdelete-show-file-confirm' => 'Sidd Dir sécher datt Dir déi geläschte Versioun vum Fichier "<nowiki>$1</nowiki>" vum $2 ëm $3 gesi wëllt?',
'revdelete-show-file-submit' => 'Jo',
-'revdelete-selected' => "'''{{PLURAL:$2|Gewielte Versioun|Gewielte Versioune}} vu(n) '''$1''' :'''",
+'revdelete-selected' => "'''{{PLURAL:$2|Gewielt Versioun|Gewielt Versioune}} vu(n) '''$1''' :'''",
'logdelete-selected' => "'''Ausgewielten {{PLURAL:$1|Evenement|Evenementer}} aus dem Logbuch:'''",
'revdelete-text' => "'''Geläschte Versiounen oder aner geläschte Bestanddeeler sinn net méi ëffentlech zougänglech, si stinn awer weiderhin an der Versiounsgeschicht vun der Säit.'''
Aner {{SITENAME}}-Administrateure kënnen de geläschten Inhalt oder aner geläschte Bestanddeeler weiderhi gesinn a restauréieren, et sief, et gouf festgeluecht, datt déi Limitatioune vum Accès och fir Administrateure gëllen.",
'revdelete-suppress' => 'Grond vum Läschen och fir Administrateure verstoppt',
'revdelete-unsuppress' => 'Limitatiounen fir restauréiert Versiounen ophiewen',
'revdelete-log' => 'Grond:',
-'revdelete-submit' => 'Op déi gewielte {{PLURAL:$1|Versioun|Versiounen}} uwenden',
+'revdelete-submit' => 'Op déi gewielt {{PLURAL:$1|Versioun|Versiounen}} uwenden',
'revdelete-success' => "'''Sichtbarkeet vun de Versioune gouf aktualiséiert.''''",
'revdelete-failure' => "'''Sichtbarkeet vun der Versioun konnt net aktualiséiert ginn:'''
$1",
'markaspatrolleddiff' => 'Als nogekuckt markéieren',
'markaspatrolledtext' => 'Dës Säit als nogekuckt markéieren',
'markedaspatrolled' => 'ass als nogekuckt markéiert',
-'markedaspatrolledtext' => 'Déi gewielte Versioun vu(n) [[:$1]] gouf als nogekuckt markéiert.',
+'markedaspatrolledtext' => 'Déi gewielt Versioun vu(n) [[:$1]] gouf als nogekuckt markéiert.',
'rcpatroldisabled' => 'Rezent Ännerungskontroll ausgeschalt.',
'rcpatroldisabledtext' => "D'Kontroll vun de leschten Ännerungen ass elo ausgeschalt.",
'markedaspatrollederror' => 'Kann net als "nogekuckt" markéiert ginn.',
'underline-always' => 'Ziah/ngei ngei',
'underline-never' => 'Ngai lo',
-'underline-default' => 'Browser duhdàn',
+'underline-default' => 'Rängpuifanna duhdàn',
# Font style option in Special:Preferences
'editfont-style' => 'Siamţhatna hmun hawrawp pian',
-'editfont-default' => 'Browser duhdàn',
+'editfont-default' => 'Rängpuifanna duhdàn',
'editfont-monospace' => 'Hawrawp inkar rualkhai',
'editfont-sansserif' => 'Sans-serif hawrawp',
'editfont-serif' => 'Serif hawrawp',
'january' => 'Pawlkut',
'february' => 'Ramtuk',
'march' => 'Vau',
-'april' => 'Ţau',
-'may_long' => 'Ţomir',
+'april' => 'Ṭau',
+'may_long' => 'Ṭomir',
'june' => 'Nikir',
'july' => 'Vawkhniahzawn',
-'august' => 'Thiţin',
+'august' => 'Thiṭin',
'september' => 'Mimkut',
'october' => 'Khuangchawi',
'november' => 'Sahmulphah',
'errorpagetitle' => 'Dik lo',
'returnto' => '$1 phekah kir leh rawh.',
'tagline' => '{{SITENAME}} aţangin',
-'help' => 'Ţanpuina',
+'help' => 'Ṭanpuina',
'search' => 'Zawnna',
'searchbutton' => 'Zawng rawh le',
'go' => 'Kal rawh le',
'sharedupload-desc-there' => 'Hë taksa hi $1-a mi a ni a, hna-hmachhawp dangin a hmang ve mai thei.
Hriattirna dang chu [$2 taksa sawifiahna phêk]-ah hian i en thei ang.',
'sharedupload-desc-here' => 'He taksa hi $1-a mi a ni a, hna-hmachhawp dangin an hmang ve mai thei.
-[Taksa sawifiahna phek $2]-a sawifiahna lang hetah hian kan rawh chhawp chhuak e.',
+[$2 Taksa sawifiahna phek]-a sawifiahna lang hetah hian kan rawh chhawp chhuak e.',
'sharedupload-desc-edit' => 'Hë taksa hi $1-a mi a ni a, hna-hmachhawp dangin a hmang vè mai thei.
Taksa sawifiahna hi i siamṭha duh a nih chuan [$2 taksa sawifiahna phêk] aṭang hian i siamṭha thei ang.',
+'sharedupload-desc-create' => 'Hë taksa hi $1-a mi a ni a, hna-hmachhawp dangin a hmang vè mai thei.
+Taksa sawifiahna hi i siamṭha duh a nih chuan [$2 taksa sawifiahna phêk] aṭang hian i siamṭha thei ang.',
'filepage-nofile' => 'He hmingpu taksa a awm lo',
'filepage-nofile-link' => 'He hming pu taksa hi a awm lo va, mahsé i [$1 hlangkai thei] ang.',
'uploadnewversion-linktext' => 'He taksa chhuah thar hi hlangkai rawh',
'filerevert' => '$1 tilêt rawh',
'filerevert-legend' => 'Taksa tilêt rawh',
+# MIME search
+'mimetype' => 'MIME chî:',
+'download' => 'hnuhthlâkna',
+
+# Unwatched pages
+'unwatchedpages' => 'Vèn loh phêkte',
+
+# List redirects
+'listredirects' => 'Hruailuhna phêkte',
+
+# Unused templates
+'unusedtemplates' => 'Siamsa hman lohte',
+'unusedtemplateswlh' => 'zawmna dang',
+
# Random page
'randompage' => 'Phêk kahpah',
+'randompage-nopages' => "{{PLURAL:$2|Hë hminghmunah hian|Hê'ng hminghmunahte hian}} phêk pakhat mah a awm lo: $1.",
+
+# Random redirect
+'randomredirect' => 'Hruailuhna kahpah',
+'randomredirect-nopages' => '"$1" hminghmunah hian hruailuhna phêk pakhat mah a awm lo.',
# Statistics
'statistics' => 'Lepsena',
+'statistics-header-pages' => 'Phêk lepsena',
+'statistics-header-edits' => 'Siamṭhatphung lepsena',
+'statistics-header-views' => 'Tlawhna lepsèna',
+'statistics-header-users' => 'Hmangtute chanchin kimchang',
+'statistics-header-hooks' => 'Chanchin dang',
+'statistics-articles' => 'Thuziakna phêkte',
'statistics-pages' => 'Phekte',
'statistics-pages-desc' => 'Hë wiki-a phêk awm zawng zawng, sawihona phêk, hruailuhna phêk ladt. tel vekin.',
'statistics-files' => 'Taksa hlankaite',
'shortpages' => 'Phêk täwite',
'longpages' => 'Phêk seite',
'deadendpages' => 'Phêk ralthümte',
+'deadendpagestext' => 'A hnuaia phêkte hian {{SITENAME}}-a phêk dang pakhat mah zawmpui an nei lo.',
'protectedpages' => 'Phêk vènhimte',
'protectedpages-indef' => 'Phêk vènhim kumhlunho chauh',
'protectedpagestext' => 'A hnuaia phêkte hi sawn emaw siam danglam theih loh tùra vènhim an ni',
'watchlist' => 'Ka ralvèn',
'mywatchlist' => 'Ka ralvèn',
'watchlistfor2' => '$1 tan $2',
-'nowatchlist' => 'I ràlvènah engmah i nei lo.',
-'watchlistanontext' => 'I ralvèn en tùrin emaw siamţha tùrin $1 rawh.',
+'nowatchlist' => 'Rálvèn i nei lo',
+'watchlistanontext' => 'I ralvèn en tùrin emaw siamṭha tùrin $1 rawh.',
'watchnologin' => 'I la lût lo',
'watchnologintext' => 'I ralvèn tidanglam tùrin i [[Special:UserLogin|inziahluh]] a ngai.',
'addwatch' => 'Ràlvèn zingah telh rawh',
'wlshowlast' => 'Darkar $1 kalta-a tihdanglam tilang rawh , ni $2 kalta-a tihdanglam tilang rawh, $3 tilang rawh',
'watchlist-options' => 'Ralvèn duhdàn',
+'enotif_anon_editor' => 'hmangtu hriat loh $1',
+
# Delete
+'deletepage' => 'Hë phêk hi paih rawh',
+'confirm' => 'Tihchianna',
+'excontent' => 'kentel: "$1"',
+'excontentauthor' => 'kentel: "$1" (kutthawhtu awm chhun "[[Special:Contributions/$2|$2]])',
'actioncomplete' => 'A zo ta',
'actionfailed' => 'A tlawlh',
'dellogpage' => 'Nuaibo chhinchhiahna',
* @author Bombola
* @author Dato deutschland
* @author Dawid Deutschland
+ * @author Erdemaslancan
* @author Ibero-kolxi
* @author Reedy
* @author The Evil IP address
# Vector skin
'vector-action-delete' => 'Jili',
+'vector-action-protect' => 'İçvi',
+'vector-view-create' => 'dokʼidi',
'vector-view-edit' => 'Doktiri',
+'variants' => "Variant'epe",
'errorpagetitle' => 'Çilata',
'returnto' => '$1 butʼkʼaşa goikti.',
'search-interwiki-more' => '(çkva)',
'search-mwsuggest-enabled' => 'okʼvandupete',
'search-mwsuggest-disabled' => 'okʼvandu varen',
+'searchall' => 'mteli',
'nonefound' => "'''Notʼi''': Xvala, namtini svacoxope maartani oqʼopinot igoren.
Ogoruşi dudis '''all:''' pʼrefiksi okʼatute doloçʼareli na ren iri şeyi (oğarğaluşi butʼkʼape, şablonepe, doçkva şeyepeti iqʼvasen) mgori varna pʼrefiksi oqʼopinot na igoren svacoxo ixmarit.",
'powersearch' => 'Mordineri ogoru',
'uploadlogpage' => 'Dosya oncğonu kʼayitʼepe',
'uploadedimage' => 'Siteşa na incğonen resimi: "[[$1]]"',
+'license-header' => 'Lisans',
+
# File description page
+'file-anchor-link' => 'Dosya',
'filehist' => 'Dosyaşi tarixi',
'filehist-help' => 'Dosyaşi tarixi oz*iru şeni Ndğa/Ora burme-muşis na renan tarixepes o3ʼkʼedi.',
'filehist-deleteall' => 'mteli jili',
'sp-contributions-newbies' => 'Xvala ağani maxmarepeşi meşvelape ko3ʼiri',
'sp-contributions-blocklog' => 'Bloğiş kʼayitʼi',
+'sp-contributions-talk' => 'Mesaji',
'sp-contributions-search' => 'Meşvelape mgori',
'sp-contributions-username' => 'IP varna maxmare:',
'sp-contributions-submit' => 'Mgori',
# Export
'export' => 'Butʼkʼa ikʼayitʼi',
+# Namespace 8 related
+'allmessagesname' => 'Coxo',
+
# Thumbnails
'thumbnail-more' => 'Didi qʼvi',
* @author Meno25
* @author Priyanka.rachna.jha
* @author Rajesh
+ * @author Reedy
* @author Umeshberma
* @author Vinitutpal
*/
अहाँ सार्वत्रिक विभव संकेतक गलत टंकण केने हएब, वा कोनो गलत लिंकक पाछाँ गेल हएब।
ई {{अन्तर्जाल}} प्रयोक्ता द्वारा प्रयुक्त तंत्रांशमे स्थित कोनो दोषक संकेत सेहो कऽ सकैए।',
'nosuchspecialpage' => 'एहेन कोनो विशेष पन्ना नै',
-'nospecialpagetext' => '<गाढ़> अहाँ एकटा अमान्य पन्नाक आग्रह केने छी। </गाढ़>
+'nospecialpagetext' => '<strong> अहाँ एकटा अमान्य पन्नाक आग्रह केने छी। </strong>
मान्य विशेष पन्नाक सूची एतए अछि [[Special:SpecialPages|{{int:specialpages}}]]।',
# General errors
'file-info' => 'संचिका आकार: $1, माइम प्रकार: $2',
'file-info-size' => '$1 × $2 चित्राणु, फाइल आकार: $3, माइम प्रकार: $4',
'file-info-size-pages' => '$1 × $2 चित्रकण, संचिका आकार : $3, माइम प्रकार: $4, $5 {{PLURAL:$5|पन्ना|पन्ना सभ}}',
-'file-nohires' => '<छोट>ऐसँ बेशी आनन्तर्य उपलब्ध नै अछि।</छोट>',
+'file-nohires' => 'ऐसँ बेशी आनन्तर्य उपलब्ध नै अछि।',
'svg-long-desc' => 'एस.वी.जी. फाइल, मामूली रूपमे $1 × $2 चित्रकण, फाइलक आकार: $3',
'show-big-image' => 'पूर्ण आनन्तर्य',
'show-big-image-preview' => 'ऐ पूर्वदृश्यक आकार: $1.',
# User preference toggles
'tog-underline' => 'Liân-kiat oē té-sûn:',
'tog-hideminor' => 'Am chòe-kīn ê sió kái-piàn',
-'tog-extendwatchlist' => 'Tián-khui kàm-sī-toaⁿ khoàⁿ só͘-ū ê kái-piàn, m̄-chí sī choè-kīn--ê',
-'tog-usenewrc' => 'Ēng ka-kiông pán khoàⁿ chòe-kīn ê kái-piàn (su-iàu JavaScript)',
+'tog-extendwatchlist' => 'Khok-chhiong kàm-sī-toaⁿ kàu hián-sī só͘-ū ê kái-piàn',
+'tog-usenewrc' => 'Ka-kiông pán ê chòe-kīn-ê-kái-piàn (su-iàu JavaScript)',
'tog-numberheadings' => 'Phiau-tê chū-tōng pian-hō',
'tog-showtoolbar' => 'Hián-sī pian-chi̍p ke-si-tiâu (su-iàu JavaScript)',
'tog-editondblclick' => 'Siang-ji̍h ia̍h-bīn to̍h ē-tàng pian-chi̍p (su-iàu JavaScript)',
'tog-editsection' => 'Ji̍h [siu-kái] chit-ê liân-kiat to̍h ē-tàng pian-chi̍p toāⁿ-lo̍h',
'tog-editsectiononrightclick' => 'Chiàⁿ-ji̍h (right click) toāⁿ-lo̍h (section) phiau-tê to̍h ē-tàng pian-chi̍p toāⁿ-lo̍h (su-iàu JavaScript)',
'tog-showtoc' => 'Hián-sī bo̍k-chhù (3-ê phiau-tê í-siōng ê ia̍h)',
-'tog-rememberpassword' => 'Kì tiâu bi̍t-bé, āu-chōa iōng ( $1 {{PLURAL:$1|day|kang}} lāi)',
+'tog-rememberpassword' => 'Kì tiâu bi̍t-bé, āu-chōa iōng (for a maximum of $1 {{PLURAL:$1|day|days}})',
'tog-watchcreations' => 'Kā goá khui ê ia̍h ka-ji̍p kàm-sī-toaⁿ lāi-té',
'tog-watchdefault' => 'Kā goá pian-chi̍p kòe ê ia̍h ka-ji̍p kàm-sī-toaⁿ lāi-té',
'tog-watchmoves' => 'Kā goá soá ê ia̍h ka-ji̍p kàm-sī-toaⁿ',
'tog-previewonfirst' => 'Thâu-pái pian-chi̍p seng khoàⁿ-māi',
'tog-nocache' => 'Koaiⁿ-tiāu ia̍h ê cache',
'tog-fancysig' => 'Chhiam-miâ mài chò liân-kiat',
-'tog-externaleditor' => 'Iōng gōa-pō· pian-chi̍p-khì (kan-na hō͘ ko-chhiú, he ài tī lí ê tiān-náu koh siat-tēng. [//www.mediawiki.org/wiki/Manual:External_editors Siông-chêng.])',
-'tog-externaldiff' => 'Iōng gōa-pō· diff (kan-na hō͘ ko-chhiú, he ài tī lí ê tiān-noá koh siat-tēng. [//www.mediawiki.org/wiki/Manual:External_editors Siông-chêng.])',
+'tog-externaleditor' => 'Iōng gōa-pō· pian-chi̍p-khì',
+'tog-externaldiff' => 'Iōng gōa-pō· diff',
'tog-forceeditsummary' => 'Pian-chi̍p khài-iàu bô thiⁿ ê sî-chūn, kā goá thê-chhéⁿ',
'tog-watchlisthideown' => 'Kàm-sī-toaⁿ bián hián-sī goá ê pian-chi̍p',
'tog-watchlisthidebots' => 'Kàm-sī-toaⁿ bián hián-sī ki-khì pian-chi̍p',
'dec' => '12g',
# Categories related messages
-'pagecategories' => '{{PLURAL:$1|Lūi-pia̍t|ê lūi-pia̍t}}',
+'pagecategories' => '{{PLURAL:$1|Lūi-pia̍t|Lūi-pia̍t}}',
'category_header' => 'Tī "$1" chit ê lūi-pia̍t ê bûn-chiuⁿ',
'subcategories' => 'Ē-lūi-pia̍t',
'category-media-header' => 'Tī lūi-pia̍t "$1" ê mûi-thé',
'create-this-page' => 'Khai-sí siá chit ia̍h',
'delete' => 'Thâi',
'deletethispage' => 'Thâi chit ia̍h',
-'undelete_short' => 'Kiù {{PLURAL:$1| ê siu-káit|$1 ê siu-kái}}',
+'undelete_short' => 'Kiù $1 ê siu-kái',
'viewdeleted_short' => 'Khoàⁿ {{PLURAL:$1|chi̍t-ê thâi tiàu--ê pian-chi̍p|$1 ê thâi tiàu--ê pian-chi̍p}}',
'protect' => 'Pó-hō·',
'protect_change' => 'kái-piàn',
'redirectedfrom' => '(Tùi $1 choán--lâi)',
'redirectpagesub' => 'Choán-ia̍h',
'lastmodifiedat' => 'Chit ia̍h tī $1, $2 ū kái--koè',
-'viewcount' => 'Pún-ia̍h kàu taⁿ ū {{PLURAL:$1| pái|$1 pái}} ê sú-iōng.',
+'viewcount' => 'Pún-ia̍h kàu taⁿ ū $1 pái access.',
'protectedpage' => 'Siū pó-hō͘ ê ia̍h',
'jumpto' => 'Thiàu khì:',
'jumptonavigation' => 'Se̍h chām',
'thisisdeleted' => 'Khoàⁿ a̍h-sī kiù $1?',
'viewdeleted' => 'Beh khoàⁿ $1?',
'restorelink' => '{{PLURAL:$1|chi̍t ê thâi-tiàu ê pian-chi̍p|$1 thâi-tiàu ê pian-chi̍p}}',
-'feedlinks' => 'Tēng khoàⁿ:',
+'feedlinks' => 'Chhī-liāu:',
'feed-invalid' => 'Bô-hāu ê tēng khoàⁿ lūi-hêng.',
'feed-unavailable' => 'Bô thê-kiong liân-ha̍p tēng khoàⁿ.',
'site-rss-feed' => '$1 ê RSS tēng khoàⁿ',
'unexpected' => 'Koài-koài ê pió-tat: "$1"="$2"。',
'formerror' => 'Chhò-gō·: bô-hoat-tō· kā pió sàng chhut khì.',
'badarticleerror' => 'Bē-tàng tiàm chit ia̍h chip-hêng chit ê tōng-chok.',
-'cannotdelete' => 'Bô-hoat-tō· kā "$1" hit ê ia̍h a̍h-sī iáⁿ-siōng thâi tiāu. (Khó-lêng pa̍t-lâng í-keng kā thâi tiāu ah.)',
+'cannotdelete' => 'Bô-hoat-tō· kā hit ê ia̍h a̍h-sī iáⁿ-siōng thâi tiāu. (Khó-lêng pa̍t-lâng í-keng kā thâi tiāu ah.)',
'badtitle' => 'M̄-chiâⁿ piau-tê',
'badtitletext' => 'Iau-kiû ê piau-tê sī bô-hāu ê, khang ê, a̍h-sī liân-kiat chhò-gō· ê inter-language/inter-wiki piau-tê.',
-'perfcached' => 'Ē-kha ê chu-liāu ùi khoài-chhú(cache) lâi--ê, só·-í khó-lêng m̄-sī siōng sin ê. Khoài-chhú lāi-té siōng chē khǹg {{PLURAL:$1| chi̍t tiâu|$1 tiâu}}.',
-'perfcachedts' => 'Ē-kha ê chu-liāu ùi khoài-chhú(cache) lâi--ê, tī $1 keng-sin--koè. Khoài-chhú lāi-té siōng chē khǹg {{PLURAL:$4| chi̍t tiâu |$4 tiâu}}.',
+'perfcached' => 'Ē-kha ê chu-liāu tùi lâi--ê, só·-í bī-pit oân-choân hoán-èng siōng sin ê chōng-hóng. A maximum of {{PLURAL:$1|one result is|$1 results are}} available in the cache.',
+'perfcachedts' => 'Ē-kha ê chu-liāu tùi lâi--ê, tī $1 keng-sin--koè. A maximum of {{PLURAL:$4|one result is|$4 results are}} available in the cache.',
'querypage-no-updates' => 'Chit-má bē-sái kái chit ia̍h.
Chia ê chu-liāu bē-tàng sui tiông-sin chéng-lí.',
'wrong_wfQuery_params' => 'Chhò-ngō͘ ê chham-sò͘ chhoân hō͘ wfQuery()<br />
'protectedpagetext' => 'Chit ia̍h hông só tiâu leh, bē pian-chi̍p tit.',
'viewsourcetext' => 'Lí ē-sái khoàⁿ ia̍h khó͘-pih chit ia̍h ê goân-sú loē-iông:',
'protectedinterface' => 'Chit ia̍h thê-kiong nńg-thé kài-bīn ēng ê bûn-jī. Ūi beh ī-hông lâng chau-that, só͘-í ū siū tio̍h pó-hō͘.',
-'editinginterface' => "'''Sè-jī:''' Lí tng teh siu-kái 1 bīn thê-kiong nńg-thé kài-bīn bûn-jī ê ia̍h.
-Jīn-hô kái-piàn to ē éng-hióng tio̍h kî-thaⁿ iōng-chiá ê sú-iōng kài-bīn.
-Nā ūi-tio̍h hoan-e̍k, chhiáⁿ khó-lū sú-iōng [//translatewiki.net/wiki/Main_Page?setlang=nan translatewiki.net], MediaWiki ê chāi-tē hoà sū-kang.",
+'editinginterface' => "'''Sè-jī:''' Lí tng teh siu-kái 1 bīn thê-kiong nńg-thé kài-bīn bûn-jī ê ia̍h. Jīn-hô kái-piàn to ē éng-hióng tio̍h kî-thaⁿ iōng-chiá ê sú-iōng kài-bīn.",
'sqlhidden' => '(Tshàng SQL tsa-sûn)',
'cascadeprotected' => 'Chit-ê ia̍h í-keng hông pó-hō͘ bē kái tit. In-ūi i tī ē-bīn {{PLURAL:$1|ê|ê}} liân-só pó-hō͘ lāi-té:
$2',
# Login and logout pages
'logouttext' => "'''Lí í-keng teng-chhut.'''
-Lí ē-sái mài kì-miâ kè-siok sú-iōng {{SITENAME}}, mā ē-sái iōng kāng-ê a̍h-sī pa̍t-ê sin-hūn [[Special:UserLogin|têng teng-ji̍p]].
+Lí ē-sái mài kì-miâ kè-siok sú-iōng {{SITENAME}}, mā ē-sái iōng kāng-ê a̍h-sī pa̍t-ê sin-hūn têng teng-ji̍p.
Chhiaⁿ chù-ì: ū-kóa ia̍h ū khó-lêng khoàⁿ-tio̍h bē-su lí iû-goân teng-ji̍p tiong; che chi-iàu piàⁿ tiāu lí ê browser ê cache chiū ē chèng-siông.",
'welcomecreation' => '==Hoan-gêng $1!==
-Í-keng khui hó lí ê kháu-chō. M̄-hó bē-kì-tit chhiâu lí tī [[Special:Preferences|{{SITENAME}} ê iōng-chiá siat-tēng]].',
+Í-keng khui hó lí ê kháu-chō. M̄-hó bē-kì-tit chhiâu lí ê iōng-chiá siat-tēng.',
'yourname' => 'Lí ê iōng-chiá miâ-chheng:',
'yourpassword' => 'Lí ê bi̍t-bé:',
'yourpasswordagain' => 'Têng phah bi̍t-bé:',
-'remembermypassword' => 'Kì tiâu góa ê bi̍t-bé (āu-chhiú teng-ji̍p iōng) (tī $1 {{PLURAL:$1|day|days}} kang lāi)',
+'remembermypassword' => 'Kì tiâu góa ê bi̍t-bé (āu-chhiú teng-ji̍p iōng) (for a maximum of $1 {{PLURAL:$1|day|days}})',
'login' => 'Teng-ji̍p',
'nav-login-createaccount' => 'Teng-ji̍p / khui sin kháu-chō',
'loginprompt' => 'Thiⁿ ē-kha ê chu-liāu thang khui sin hō·-thâu a̍h-sī teng-ji̍p {{SITENAME}}.',
'logout' => 'Teng-chhut',
'userlogout' => 'Teng-chhut',
'notloggedin' => 'Bô teng-ji̍p',
-'nologin' => "Bô poàⁿ ê kháu-chō? '''$1'''.",
+'nologin' => "Bô-thang teng-ji̍p? '''$1'''.",
'nologinlink' => 'Khui 1 ê kháu-chō',
'createaccount' => 'Khui sin kháu-chō',
'gotaccount' => "Í-keng ū kháu-chō? '''$1'''.",
'createaccounterror' => 'Bô hoat-tō͘ khui kháu-chō: $1',
'loginsuccesstitle' => 'Teng-ji̍p sêng-kong',
'loginsuccess' => 'Lí hiān-chhú-sî í-keng teng-ji̍p {{SITENAME}} chò "$1".',
-'nosuchuser' => 'Chia bô iōng-chiá hō-chò "$1". Miâ-jī ū hun toā-siá, sio-siá . Chhiáⁿ kiám-cha lí ê phèng-im, a̍h-sī [[Special:UserLogin/signup|khui sin káu-chō]].',
+'nosuchuser' => 'Chia bô iōng-chiá hō-chò "$1". Chhiáⁿ kiám-cha lí ê phèng-im, a̍h-sī iōng ē-kha ê pió lâi khui sin iōng-chiá ê kháu-chō.',
'nosuchusershort' => 'Bô "$1" chit ê iōng-chiá miâ.
Tùi khoàⁿ-māi, lí phah--ê.',
'nouserspecified' => 'Lí ài chí-tēng chi̍t ê iōng-chiá miâ.',
'noemail' => 'Kì-lo̍k bô iōng-chiá "$1" ê e-mail chū-chí.',
'passwordsent' => 'Ū kià sin bi̍t-bé khì "$1" chù-chheh ê e-mail chū-chí. Siu--tio̍h liáu-āu chhiáⁿ têng teng-ji̍p.',
'mailerror' => 'Kià phoe tú tio̍h chhò-gō·: $1',
-'acct_creation_throttle_hit' => 'Tī koè-khì 24 tiám-cheng lāi, ū chit ê iōng lí IP bāng-chí ê lâng í-keng khui {{PLURAL:$1|1 account|$1 kháu-chō}}. He sī hit ê sî-kan lāi thang chò ê.
-Tiō-sī kóng, tī chit-má iōng chit ê IP bāng-chí ê lâng bē-sái koh khui jīm-hô kháu-chō.',
-'emailauthenticated' => 'Lí ê e-mail chū-chí tī $2 $3 khak-jīn sêng-kong.',
+'acct_creation_throttle_hit' => 'Pháiⁿ-sè, lí taⁿ í-keng khui $1 ê kháu-chō ā. Bē-sái koh-chài khui.',
+'emailauthenticated' => 'Lí ê e-mail chū-chí tī $1 khak-jīn sêng-kong.',
'emailnotauthenticated' => 'Lí ê e-mail chū-chí iáu-bōe khak-jīn ū-hāu, só·-í ē--kha ê e-mail kong-lêng bē-ēng-tit.',
'noemailprefs' => 'Tī lí ê siat-piān chí-tēng chi̍t ê tiān-chú-phoe tē-chí thang hō͘ chia ê kong-lêng ē-tàng ēng.',
'emailconfirmlink' => 'Chhiáⁿ khak-jīn lí ê e-mail chū-chí ū-hāu',
'loginreqlink' => 'Teng-ji̍p',
'loginreqpagetext' => 'Lí ài $1 chiah thang khoàⁿ pat ia̍h.',
'accmailtitle' => 'Bi̍t-bé kià chhut khì ah.',
-'accmailtext' => "Hō͘ [[User talk:$1|$1]] ê chi̍t ê iōng loān-sò͘ sán-seng ê bi̍t-bé í-keng kìa khì $2.
-
-Kháu-chō ê sin bi̍t-bé thang tī teng-ji̍p liáu tī ''[[Special:ChangePassword|siu-kái bi̍t-bé]]'' ia̍h kái tiāu.",
+'accmailtext' => '$1 ê bi̍t-bé í-keng kìa khì $2.',
'newarticle' => '(Sin)',
'newarticletext' => "Lí tòe 1 ê liân-kiat lâi kàu 1 bīn iáu-bōe chûn-chāi ê ia̍h. Beh khai-sí pian-chi̍p chit ia̍h, chhiáⁿ tī ē-kha ê bûn-jī keh-á lāi-té phah-jī. ([[{{MediaWiki:Helppage}}|Bo̍k-lio̍k]] kà lí án-choáⁿ chìn-hêng.) Ká-sú lí bô-tiuⁿ-tî lâi kàu chia, ē-sai chhi̍h liû-lám-khì ê '''téng-1-ia̍h''' tńg--khì.",
-'anontalkpagetext' => "''Pún thó-lūn-ia̍h bô kò·-tēng ê kháu-chō/hō·-thâu, kan-na ū 1 ê IP chū-chí (chhin-chhiūⁿ 123.456.789.123). In-ūi bô kāng lâng tī bô kāng sî-chūn ū khó-lêng tú-hó kong-ke kāng-ê IP, lâu tī chia ê oē ū khó-lêng hō· bô kāng lâng ê! Beh pī-bián chit khoán būn-tê, ē-sái khì [[Special:UserLogin/signup|khui 1 ê hō·-thâu a̍h-sī teng-ji̍p]].''",
-'clearyourcache' => "'''Chù-ì:''' Pó-chûn liáu-āu, tio̍h ē-kì leh kā liû-lám-khì ê cache piàⁿ tiāu chiah khoàⁿ-ē-tio̍h kái-piàn.
-*'''Firefox / Safari:''' chhi̍h tiâu \"Shift\" kâng-sî-chūn tiám-kik ''Reload/têng-sin chài-ji̍p'' a̍h-sī chhi̍h ''Ctrl-F5'' \"Ctrl-R\" kî-tiong chi̍t ê (''⌘-R'' tī Mac)
-* '''Google Chrome:''' chhi̍h ''Ctrl-Shift-R'' (''⌘-R-Shift-R'' tī Mac)
-'''Internet Explorer :'''chhi̍h tiâu \"Ctrl\" kâng-sî-chūn tiám-kek ''Refresh/têng-sin chài-ji̍p'' a̍h-sī chhi̍h \"Ctrl-F5\"
+'anontalkpagetext' => "----''Pún thó-lūn-ia̍h bô kò·-tēng ê kháu-chō/hō·-thâu, kan-na ū 1 ê IP chū-chí (chhin-chhiūⁿ 123.456.789.123). In-ūi bô kāng lâng tī bô kāng sî-chūn ū khó-lêng tú-hó kong-ke kāng-ê IP, lâu tī chia ê oē ū khó-lêng hō· bô kāng lâng ê! Beh pī-bián chit khoán būn-tê, ē-sái khì [[Special:UserLogin|khui 1 ê hō·-thâu a̍h-sī teng-ji̍p]].''",
+'clearyourcache' => "'''Chù-ì:''' Pó-chûn liáu-āu, tio̍h ē-kì leh kā liû-lám-khì ê cache piàⁿ tiāu chiah khoàⁿ-ē-tio̍h kái-piàn: *'''Firefox / Safari:''' chhi̍h tiâu \"Shift\" kâng-sî-chūn tiám-kik ''Reload/têng-sin chài-ji̍p'' a̍h-sī chhi̍h ''Ctrl-F5'' \"Ctrl-R\" kî-tiong chi̍t ê (''Command-R'' tī Mac)
+* '''Google Chrome:''' chhi̍h ''Ctrl-Shift-R'' (''Command-Shift-R'' tī Mac)
+'''Internet Explorer :'''chhi̍h tiâu \"Ctrl\" kâng-sî-chūn tiám-kek ''Refresh/têng-sin chài-ji̍p'' a̍h-sī chhi̍h \"Ctrl-F5\"
* '''Konqueror:''' tiám-kek ''Reload/têng-sin chài-ji̍p'' a̍h-sī chhi̍h ''F5''
* '''Opera:''' piàⁿ-tiāu cache tī ''Tools(ke-si) → Preferences(siat-piān)''",
-'usercssyoucanpreview' => "'''Phiat-pō·''': Pó-chûn chìn-chêng ē-sái chhi̍h 'Seng khoàⁿ-māi' kiám-cha sin ê CSS.",
-'userjsyoucanpreview' => "'''Phiat-pō·''': Pó-chûn chìn-chêng ē-sái tiám-kek \"{{int:showpreview}}\" ; chhì lí ê sin JavaScript.",
-'usercsspreview' => "'''Thê-chhíⁿ lí, che chí-sī sian khoàⁿ-māi lí ê su-jîn CSS'''
-'''Che iáu-bōe pó-chûn--khí-lâi !'''",
+'usercssyoucanpreview' => "'''Phiat-pō·''': Pó-chûn chìn-chêng ē-sái chhi̍h 'Seng khoàⁿ-māi' kiám-cha sin ê CSS a̍h-sī JavaScript.",
+'userjsyoucanpreview' => "'''Phiat-pō·''': Pó-chûn chìn-chêng ē-sái chhi̍h 'Seng khoàⁿ-māi' kiám-cha sin ê CSS a̍h-sī JavaScript.",
+'usercsspreview' => "'''Sè-jī! Lí hiān-chú-sî khoàⁿ--ê sī lí ê su-jîn css ê preview; che iáu-bōe pó-chûn--khí-lâi!'''",
'userjspreview' => "'''Sè-jī! Lí hiān-chú-sî chhì khoàⁿ--ê sī lí ka-kī ê javascript; che iáu-bōe pó-chûn--khí-lâi!'''",
'note' => "'''Chù-ì:'''",
-'previewnote' => "'''Thê-chhéⁿ lí, che chí-sī hō͘ lí sian khoàⁿ chi̍t-ē.'''
-Lí kái--ê iáu-bōe pó-chûn--khí-lâi !",
+'previewnote' => "'''Thê-chhéⁿ lí che sī 1 bīn kiám-cha chho͘-phe ēng--ê \"seng-khoàⁿ-ia̍h\", iáu-bōe pó-chûn--khí-lâi!'''",
'session_fail_preview' => "'''Pháiⁿ-sè! Gún chiām-sî bô hoat-tō͘ chhú-lí lí ê pian-chi̍p (goân-in: \"phàng-kiàn sú-iōng kî-kan ê chu-liāu\"). Lô-hoân têng chhì khoàⁿ-māi. Ká-sú iû-goân bô-hāu, ē-sái teng-chhut koh-chài teng-ji̍p hoān-sè tō ē-tit kái-koat.'''",
'editing' => 'Siu-kái $1',
'editingsection' => 'Pian-chi̍p $1 (section)',
'storedversion' => 'Chu-liāu-khò· ê pán-pún',
'editingold' => "'''KÉNG-KÒ: Lí tng teh siu-kái chit ia̍h ê 1 ê kū siu-tēng-pún. Lí nā kā pó-chûn khí lâi, chit ê siu-tēng-pún sòa-āu ê jīm-hô kái-piàn ē bô khì.'''",
'yourdiff' => 'Chha-pia̍t',
-'readonlywarning' => "'''CHÙ-Ì: Chu-liāu-khò· taⁿ só tiâu leh thang pān î-siu khang-khòe, só·-í lí hiān-chú-sî bô thang pó-chûn jīn-hô phian-chi̍p hāng-bo̍k. Lí ē-sái kā siong-koan pō·-hūn tah--ji̍p-khì 1-ê bûn-jī tóng-àn pó-chûn, āu-chhiú chiah koh kè-sio̍k.'''
-
-Kā só tiâu ê koán-lí-goân ū lâu oē: $1",
-'protectedpagewarning' => "'''KÉNG-KÒ: Pún ia̍h só tiâu leh. Kan-taⁿ ū hêng-chèng te̍k-koân ê iōng-chiá (sysop) ē-sái siu-kái.'''
-Ē-kha ū choè-kīn ê kì-lo̍k thang chham-khó:",
-'templatesused' => 'Chit ia̍h iōng {{PLURAL:$1|Template|Templates}} chia ê pang-bô· :',
-'templatesusedpreview' => 'Chit ê preview iōng chia ê {{PLURAL:$1|Template|pang-bô͘}}',
-'templatesusedsection' => 'Chit ê toāⁿ-lo̍k iōng chia ê {{PLURAL:$1|Template|pang-bô͘}}',
+'readonlywarning' => "'''CHÙ-Ì: Chu-liāu-khò· taⁿ só tiâu leh thang pān î-siu khang-khòe, só·-í lí hiān-chú-sî bô thang pó-chûn jīn-hô phian-chi̍p hāng-bo̍k. Lí ē-sái kā siong-koan pō·-hūn tah--ji̍p-khì 1-ê bûn-jī tóng-àn pó-chûn, āu-chhiú chiah koh kè-sio̍k.'''",
+'protectedpagewarning' => "'''KÉNG-KÒ: Pún ia̍h só tiâu leh. Kan-taⁿ ū hêng-chèng te̍k-koân ê iōng-chiá (sysop) ē-sái siu-kái.'''",
+'templatesused' => 'Chit ia̍h iōng chia ê pang-bô·:',
+'templatesusedpreview' => 'Chit ê preview iōng chia ê pang-bô͘:',
+'templatesusedsection' => 'Chit ê section iōng chia ê pang-bô͘:',
'template-protected' => '(pó-hō͘)',
'template-semiprotected' => '(poàⁿ pó-hō͘)',
'permissionserrorstext-withaction' => 'Lí bô ún-chún chò $2, in-ūi ē-kha
{{PLURAL:$1|iân-kò͘|iân-kò͘}}:',
-'recreate-moveddeleted-warn' => "'''Sè-jī: Lí taⁿ chún-pī beh khui ê ia̍h, chêng bat hō͘ lâng thâi tiāu koè.'''
-
-Lí tio̍h chim-chiok soà-chiap pian-chi̍p chit ia̍h ê pit-iàu-sèng.
-Chia ū chit ia̍h ê san-tû kì-lo̍k hō͘ lí chham-khó:",
+'recreate-moveddeleted-warn' => "'''Sè-jī: Lí taⁿ chún-pī beh khui ê ia̍h, chêng bat hō͘ lâng thâi tiāu koè.''' Lí tio̍h chim-chiok soà-chiap pian-chi̍p chit ia̍h ê pit-iàu-sèng. Chia ū chit ia̍h ê san-tû kì-lo̍k (deletion log) hō͘ lí chham-khó:",
'edit-conflict' => 'Siu-kái sio-chhiong',
'defaultmessagetext' => 'Siat piān ê bûn-jī',
'searchprofile-images-tooltip' => 'Chhoé tóng-àn',
'search-section' => '(toān-lo̍h $1)',
'searchall' => 'choân-pō·',
-'showingresults' => "Ē-kha tùi #'''$2''' khai-sí hián-sī {{PLURAL:$1| hāng| hāng}} kiat-kó.",
-'showingresultsnum' => "Ē-kha tùi #'''$2''' khai-sí hián-sī {{PLURAL:$3| hāng| hāng}} kiat-kó.",
+'showingresults' => 'Ē-kha tùi #<b>$2</b> khai-sí hián-sī <b>$1</b> hāng kiat-kó.',
+'showingresultsnum' => 'Ē-kha tùi #<b>$2</b> khai-sí hián-sī <b>$3</b> hāng kiat-kó.',
'powersearch' => 'Kiám-sek',
'powersearch-legend' => 'Kiám-sek',
'preferences' => 'Siat-tēng',
'mypreferences' => 'Góa ê siat-tēng',
'prefsnologin' => 'Bô teng-ji̍p',
-'prefsnologintext' => 'Lí it-tēng ài <span class="plainlinks">[{{fullurl:{{#Special:UserLogin}}|returnto=$1}} teng-ji̍p]</span> chiah ē-tàng chhiâu iōng-chiá ê siat-tēng.',
+'prefsnologintext' => 'Lí it-tēng ài [[Special:UserLogin|teng-ji̍p]] chiah ē-tàng chhiâu iōng-chiá ê siat-tēng.',
'changepassword' => 'Oāⁿ bi̍t-bé',
'prefs-skin' => 'Phôe',
'skin-preview' => 'Chhì khoàⁿ',
'resultsperpage' => '1 ia̍h hián-sī kúi kiāⁿ:',
'recentchangesdays' => 'Hián-sī kúi ji̍t chòe-kīn ê kái-piàn:',
'recentchangesdays-max' => 'siōng-choē $1 {{PLURAL:$1|kang|kang}}',
-'recentchangescount' => 'Beh hián-sī kúi tiâu chòe-kīn kái--ê:',
+'recentchangescount' => 'Hián-sī kúi tiâu chòe-kīn ê kái-piàn:',
'savedprefs' => 'Lí ê iōng-chiá siat-tēng í-keng pó-chûn khí lâi ah.',
'timezonelegend' => 'Sî-khu',
-'localtime' => 'Chāi-tē sî-kan sī:',
-'timezoneoffset' => 'Sî-chha¹:',
-'servertime' => 'Server sî-kan hiān-chāi sī:',
+'localtime' => 'Chāi-tē sî-kan sī',
+'timezoneoffset' => 'Sî-chha¹',
+'servertime' => 'Server sî-kan hiān-chāi sī',
'guesstimezone' => 'Tùi liû-lám-khì chhau--lâi',
'allowemail' => 'Ún-chún pa̍t-ê iōng-chiá kià email kòe-lâi',
'defaultns' => 'Tī chiah ê miâ-khong-kan chhiau-chhōe:',
'uploaddisabled' => 'Pháiⁿ-sè, sàng chiūⁿ-bāng ê kong-lêng bô khui.',
'sourcefilename' => 'Tóng-àn goân miâ:',
'destfilename' => 'Tóng-àn sin miâ:',
-'watchthisupload' => 'Kàm-sī chit ê tóng-àn',
+'watchthisupload' => 'Kàm-sī chit ia̍h',
'upload-success-subj' => 'Sàng-chiūⁿ-bāng sêng-kong',
# File backend
'filehist' => 'Tóng-àn ê le̍k-sú',
'filehist-current' => 'hiān-chāi',
'filehist-datetime' => 'Ji̍t-kî/ Sî-kan',
-'imagelinks' => 'Ēng tio̍h ê tóng-àn',
-'linkstoimage' => 'Ē-bīn ê {{PLURAL:$1|ia̍h liân kàu|$1 ia̍h liân kàu}} chit ê tóng-àn:',
+'imagelinks' => 'Iáⁿ-siōng liân-kiat',
+'linkstoimage' => 'Í-hā ê ia̍h liân kàu chit ê iáⁿ-siōng:',
'nolinkstoimage' => 'Bô poàⁿ ia̍h liân kàu chit tiuⁿ iáⁿ-siōng.',
# MIME search
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|jī-goân|jī-goân}}',
'ncategories' => '$1 {{PLURAL:$1|ê lūi-pia̍t |ê lūi-pia̍t}}',
-'nlinks' => '$1 {{PLURAL:$1|ê|ê}} liân-kiat',
+'nlinks' => '$1 ê liân-kiat',
'nmembers' => '$1 ê sêng-oân',
-'nrevisions' => '$1 {{PLURAL:$1|ê|ê}} siu-tēng-pún',
+'nrevisions' => '$1 ê siu-tēng-pún',
'lonelypages' => 'Ko·-ia̍h',
'uncategorizedpages' => 'Bô lūi-pia̍t ê ia̍h',
'uncategorizedcategories' => 'Bô lūi-pia̍t ê lūi-pia̍t',
'mostcategories' => 'Siōng chē lūi-pia̍t ê ia̍h',
'mostimages' => 'Siōng chia̍p liân-kiat ê iáⁿ-siōng',
'mostrevisions' => 'Siōng chia̍p siu-kái ê ia̍h',
-'prefixindex' => 'SóÍ\98-Å« chià u sû-thâu sek-Ãn liáu ê iaÌ\8dh',
+'prefixindex' => 'Sû-thâu sek-Ãn',
'shortpages' => 'Té-ia̍h',
'deadendpages' => 'Khu̍t-thâu-ia̍h',
'deadendpagestext' => 'Ē-kha ê ia̍h bô liân kàu wiki lāi-té ê kî-thaⁿ ia̍h.',
'ancientpages' => 'Kó·-ia̍h',
'move' => 'Sóa khì',
'movethispage' => 'Sóa chit ia̍h',
-'unusedimagestext' => 'Ē-kha ê tóng-àn bô poàⁿ ia̍h ū teh iōng. M̄-koh ia̍h lâu leh.
-Chhiáⁿ chù-ì: kî-thaⁿ ê bāng-chām ū khó-lêng iōng URL ti̍t-chiap liân kàu iáⁿ-siōng, só·-í sui-jiân bô teh iōng, mā sī ē lia̍t tī chia.',
+'unusedimagestext' => '<p>Chhiáⁿ chù-ì: kî-thaⁿ ê bāng-chām ū khó-lêng iōng URL ti̍t-chiap liân kàu iáⁿ-siōng, só·-í sui-jiân chhiâng-chāi teh iōng, mā sī ē lia̍t tī chia.</p>',
'unusedcategoriestext' => 'Ū ē-kha chiah-ê lūi-pia̍t-ia̍h, m̄-koh bô kî-thaⁿ ê bûn-chiuⁿ a̍h-sī lūi-pia̍t lī-iōng.',
# Book sources
# Special:Log
'specialloguserlabel' => 'Iōng-chiá:',
-'speciallogtitlelabel' => 'Bo̍k-piau (sû-tiâu ia̍h iōng-chiá) :',
+'speciallogtitlelabel' => 'Sû-tiâu:',
'logempty' => 'Log lāi-bīn bô sio-tùi ê hāng-bo̍k.',
# Special:AllPages
# Special:Categories
'categories' => 'Lūi-pia̍t',
-'categoriespagetext' => 'Ē-kha {{PLURAL:$1| ê ūi-pia̍t|ê ūi-pia̍t}} ū ia̍h ia̍h-sī mûi-thé.
-[[Special:UnusedCategories|Bô iōng tio̍h ê ūi-pia̍t]] tō bô tī chiah hián-sī.
-Lēng-goā thang chham-khó [[Special:WantedCategories|beh ti̍h ê lūi-pia̍t]].',
+'categoriespagetext' => 'Chit ê wiki ū ē-kha chia ê lūi-pia̍t.
+[[Special:UnusedCategories|Unused categories]] are not shown here.
+Also see [[Special:WantedCategories|wanted categories]].',
'categoriesfrom' => 'Tùi chit ê lūi-pia̍t khai-sí hián-sī:',
# Special:DeletedContributions
'deletedcontributions-title' => 'Hō͘ lâng thâi tiāu ê kòng-hiàn',
# Special:LinkSearch
-'linksearch' => 'Chhoē chām-goā ê liân-kiat',
+'linksearch' => 'Chhiau-chhoē chām-goā liân-kiat',
# E-mail user
'mailnologin' => 'Bô siu-phoe ê chū-chí',
'mailnologintext' => 'Lí it-tēng ài [[Special:UserLogin|teng-ji̍p]] jī-chhiáⁿ ū 1 ê ū-hāu ê e-mail chū-chí tī lí ê [[Special:Preferences|iōng-chiá siat-tēng]] chiah ē-tàng kià e-mail hō· pa̍t-ūi iōng-chiá.',
'emailuser' => 'Kià e-mail hō· iōng-chiá',
'emailpage' => 'E-mail iōng-chiá',
-'emailpagetext' => 'Lí ē-tàng iōng ē-kha ê pió kià chi̍t tiuⁿ phe hō͘ chit ê iōng-chiá.
-Lí ê [[Special:Preferences|siat-tēng]] ê tiān-chú-phe tē-chí ē chhut-hiān tī tiān-chú-phe ê "Kià-phe-chiá" (From) hit ūi. Án-ne siu-phe-chiá chiah ū hoat-tō· kā lí hôe-phe.',
+'emailpagetext' => 'Ká-sú chit ê iōng-chiá ū siat-tēng 1 ê ū-hāu ê e-mail chū-chí, lí tō ē-tàng ēng ē-kha chit tiuⁿ FORM hoat sìn-sek hō· i. Lí siat-tēng ê e-mail chū-chí ē chhut-hiān tī e-mail ê "Kià-phoe-jîn" (From) hit ūi. Án-ne siu-phoe-jîn chiah ū hoat-tō· kā lí hôe-phoe.',
'noemailtitle' => 'Bô e-mail chū-chí',
-'noemailtext' => 'Chit ūi iōng-chiá pēng-bô lâu ū-hāu ê e-mail chū-chí.',
-'emailfrom' => 'Lâi chū:',
-'emailto' => 'Khì hō·:',
-'emailsubject' => 'Tê-bo̍k:',
+'noemailtext' => 'Chit ūi iōng-chiá pēng-bô lâu ū-hāu ê e-mail chū-chí, bô tio̍h-sī i bô beh chiap-siū pat-ūi iōng-chiá ê e-mail.',
+'emailfrom' => 'Lâi chū',
+'emailto' => 'Khì hō·',
+'emailsubject' => 'Tê-bo̍k',
'emailmessage' => 'Sìn-sit:',
'emailsend' => 'Sàng chhut-khì',
'emailsent' => 'E-mail sàng chhut-khì ah',
'watchnologin' => 'Bô teng-ji̍p',
'watchnologintext' => 'Lí it-tēng ài [[Special:UserLogin|teng-ji̍p]] chiah ē-tàng siu-kái lí ê kàm-sī-toaⁿ.',
'addedwatchtext' => "\"[[:\$1]]\" chit ia̍h í-keng ka-ji̍p lí ê [[Special:Watchlist|kàm-sī-toaⁿ]]. Bī-lâi chit ia̍h a̍h-sī siong-koan ê thó-lūn-ia̍h nā ū kái-piàn, ē lia̍t tī hia. Tông-sî tī [[Special:RecentChanges|Chòe-kīn ê kái-piàn]] ē iōng '''chho·-thé''' hián-sī ia̍h ê piau-tê, án-ne khah bêng-hián. Ká-sú lí beh chiōng chit ia̍h tùi lí ê kàm-sī-toaⁿ tû tiāu, khì khòng-chè-tiâu chhi̍h \"Mài kàm-sī\" chiū ē-sái-tit.",
-'removedwatchtext' => '"[[:$1]]" chit ia̍h í-keng tùi lí ê [[Special:Watchlist|kàm-sī-toaⁿ]] soá cháu.',
+'removedwatchtext' => '"[[:$1]]" chit ia̍h í-keng tùi lí ê kàm-sī-toaⁿ tû tiāu.',
'watch' => 'kàm-sī',
'watchthispage' => 'Kàm-sī chit ia̍h',
'unwatch' => 'Mài kàm-sī',
'watchlist-details' => 'Kàm-sī-toaⁿ ū {{PLURAL:$1|$1 ia̍h|$1 ia̍h}}, thó-lūn-ia̍h bô sǹg chāi-lāi.',
'watchmethod-recent' => 'tng teh kíam-cha choè-kīn ê siu-kái, khoàⁿ ū kàm-sī ê ia̍h bô',
'watchmethod-list' => 'tng teh kiám-cha kàm-sī ê ia̍h khoàⁿ chòe-kīn ū siu-kái bô',
-'watchlistcontains' => 'Lí ê kàm-sī-toaⁿ siu {{PLURAL:$1|ia̍h|ia̍h}} .',
-'wlnote' => "Ē-kha sī tī $3, $4 chìn-chêng {{PLURAL:chi tiám-cheng|'''$2''' tiám-cheng}} í-lâi ê {{PLURAL:$1| chi̍t piàn|'''$1''' piàn}} siu-kái.",
+'watchlistcontains' => 'Lí ê kàm-sī-toaⁿ siu $1 ia̍h.',
+'wlnote' => "Ē-kha sī '''$2''' tiám-cheng í-lāi siōng sin ê $1 ê kái-piàn.",
'wlshowlast' => 'Hián-sī chêng $1 tiám-cheng $2 ji̍t $3',
# Delete
'excontentauthor' => "loē-iông sī: '$1' (î-it ê kòng-hiàn-chiá sī '[[Special:Contributions/$2|$2]]')",
'exbeforeblank' => "chìn-chêng ê lōe-iông sī: '$1'",
'exblank' => 'ia̍h khang-khang',
-'historywarning' => 'Kéng-kò: Lí beh thâi ê ia̍h ū {{PLURAL:$1| ê siu-tèng le̍k-sú|ê siu-tèng le̍k-sú}}:',
+'historywarning' => 'Kéng-kò: Lí beh thâi ê ia̍h ū le̍k-sú:',
'confirmdeletetext' => 'Lí tih-beh kā 1 ê ia̍h a̍h-sī iáⁿ-siōng (pau-koat siong-koan ê le̍k-sú) éng-kiú tùi chu-liāu-khò· thâi tiāu. Chhiáⁿ khak-tēng lí àn-sǹg án-ne chò, jī-chhiáⁿ liáu-kái hiō-kó, jī-chhiáⁿ bô ûi-hoán [[{{MediaWiki:Policy-url}}]].',
'actioncomplete' => 'Chip-hêng sêng-kong',
'deletedtext' => '"$1" í-keng thâi tiāu. Tùi $2 khoàⁿ-ē-tio̍h chòe-kīn thâi ê kì-lo̍k.',
'rollbacklink' => 'ká tńg khì',
'rollbackfailed' => 'Ká bē tńg khì',
'cantrollback' => 'Bô-hoat-tō· kā siu-kái ká-tńg--khì; téng ūi kòng-hiàn-chiá sī chit ia̍h î-it ê chok-chiá.',
-'alreadyrolled' => 'Bô-hoat-tō· kā [[User:$2|$2]] ([[User talk:$2|Thó-lūn]]{{int:pipe-separator}}[[Special:Contributions/$2|{{int:contribslink}}]]) tùi [[:$1]] ê siu-kái ká-tńg-khì;
-í-keng ū lâng siu-kái a̍h-sī ká-tńg chit ia̍h.
-Téng 1 ūi siu-kái-chiá sī [[User:$3|$3]] ([[User talk:$3|talk]]{{int:pipe-separator}}[[Special:Contributions/$3|{{int:contribslink}}]]).',
-'editcomment' => "Pian-chi̍p kài-iàu sī: \"''\$1''\".",
+'alreadyrolled' => 'Bô-hoat-tō· kā [[User:$2|$2]] ([[User talk:$2|Thó-lūn]]) tùi [[:$1]] ê siu-kái ká-tńg-khì; í-keng ū lâng siu-kái a̍h-sī ká-tńg chit ia̍h. Téng 1 ūi siu-kái-chiá sī [[User:$3|$3]] ([[User talk:$3|Thó-lūn]]).',
+'editcomment' => "Siu-kái phêng-lūn sī: \"''\$1''\".",
# Protect
'protectedarticle' => 'pó-hō͘ "[[$1]]"',
-'protect-title' => 'Kái "$1" ê pó-hō· tíng-kip.',
+'protect-title' => 'Pó-hō· "$1"',
'prot_1movedto2' => '[[$1]] sóa khì tī [[$2]]',
'protect-legend' => 'Khak-tēng beh pó-hō·',
'protectcomment' => 'Lí-iû:',
'ipbsubmit' => 'Hong-só chit ūi iōng-chiá',
'badipaddress' => 'Bô-hāu ê IP chū-chí',
'blockipsuccesssub' => 'Hong-só sêng-kong',
-'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] í-keng pī hong-só. <br />Khì [[Special:BlockList|hong-só lia̍t-toaⁿ]] thang khoàⁿ pī hong-só ê .',
-'ipusubmit' => 'Chhú-siau chit ê hong-só',
-'ipblocklist' => 'Siū hong-só ê iōng-chiá',
+'blockipsuccesstext' => '[[Special:Contributions/$1|$1]] í-keng pī hong-só. <br />Khì [[Special:BlockList|IP hong-só lia̍t-toaⁿ]] review hong-só ê IP.',
+'ipusubmit' => 'Chhú-siau hong-só chit ê chū-chí',
+'ipblocklist' => 'Siū hong-só ê IP chū-chí kap iōng-chiá miâ-chheng',
'blocklink' => 'hong-só',
'contribslink' => 'kòng-hiàn',
-'autoblocker' => 'Chū-tōng kìm-chí lí sú-iōng, in-ūi lí kap "[[User:$1|$1]]" kong-ke kāng 1 ê IP chū-chí.
-$1 ê kìm-chí lí-iû sī in-ūi "$2".',
+'autoblocker' => 'Chū-tōng kìm-chí lí sú-iōng, in-ūi lí kap "$1" kong-ke kāng 1 ê IP chū-chí (kìm-chí lí-iû "$2").',
'blocklogentry' => 'hong-só [[$1]], siat kî-hān chì $2 $3',
-'blocklogtext' => 'Chit-ê kì-lio̍k lia̍t-chhut hong-só/khui-só ê tōng-chok. Chū-tōng block ê IP tē-chí bô lia̍t--chhut-lâi ([[Special:BlockList|hong-só chheng-toaⁿ]] ū hiān-chú-sî ū-hāu ê kìm-chí hong-só o·-miâ-toaⁿ).',
+'blocklogtext' => 'Chit-ê log lia̍t-chhut block/unblock ê tōng-chok. Chū-tōng block ê IP chū-chí bô lia̍t--chhut-lâi ([[Special:BlockList]] ū hiān-chú-sî ū-hāu ê block/ban o·-miâ-toaⁿ).',
'block-log-flags-nocreate' => 'Khui kháu-chō thêng-iōng ah',
# Developer tools
# Move page
'move-page' => '徙$1',
'move-page-legend' => 'Sóa ia̍h',
-'movepagetext' => "Ē-kha chit ê pió iōng lâi kái 1 ê ia̍h ê piau-tê (miâ-chheng); só·-ū siong-koan ê le̍k-sú ē tòe leh sóa khì sin piau-tê.
+'movepagetext' => "Ē-kha chit ê form> iōng lâi kái 1 ê ia̍h ê piau-tê (miâ-chheng); só·-ū siong-koan ê le̍k-sú ē tòe leh sóa khì sin piau-tê.
Kū piau-tê ē chiâⁿ-chò 1 ia̍h choán khì sin piau-tê ê choán-ia̍h.
-Liân khì kū piau-tê ê liân-kiat (link) bē khì tāng--tio̍h; ē-kì-tit chhiau-chhōe [[Special:DoubleRedirects|siang-thâu (double)]] ê a̍h-sī [[Special:BrokenRedirects|kò·-chiòng ê choán-ia̍h]].
+Liân khì kū piau-tê ê liân-kiat (link) bē khì tāng--tio̍h; ē-kì-tit chhiau-chhōe siang-thâu (double) ê a̍h-sī kò·-chiòng ê choán-ia̍h.
Lí ū chek-jīm khak-tēng liân-kiat kè-sio̍k liân tio̍h ūi.
Sin piau-tê nā í-keng tī leh (bô phian-chi̍p koè ê khang ia̍h, choán-ia̍h bô chún-sǹg), tō bô-hoat-tō· soá khì hia.
'allmessagesname' => 'Miâ',
'allmessagesdefault' => 'Siat piān ê bûn-jī',
'allmessagescurrent' => 'Bo̍k-chêng ê bûn-jī',
-'allmessagestext' => 'Che sī MediaWiki: miâ-khong-kan lāi-té ê hē-thóng sìn-sit chheng-toaⁿ.
-Lí nā beh tàu saⁿ-kang hoan-e̍k. Chhiáⁿ kàu [//www.mediawiki.org/wiki/Localisation MediaWiki chāi-tè-hoà] kap [//translatewiki.net translatewiki.net] bāng-chām.',
+'allmessagestext' => 'Chia lia̍t chhut só·-ū tī MediaWiki: miâ-khong-kan ê hē-thóng sìn-sit.',
# Thumbnails
'thumbnail-more' => 'Hòng-tōa',
'tooltip-summary' => 'Siá chi̍t-ê kán-tan soat-bêng',
# Attribution
-'anonymous' => '{{SITENAME}} ê {{PLURAL:$1|ê bô kì-miâ ê iōng-chiá|ê bô kì-miâ ê iōng-chiá}} .',
+'anonymous' => '{{SITENAME}} bô kì-miâ ê iōng-chiá',
'siteuser' => '{{SITENAME}} iōng-chiá $1',
'othercontribs' => 'Kin-kù $1 ê kòng-hiàn.',
-'siteusers' => '{{SITENAME}} {{PLURAL:$2|iōng-chiá|iōng-chiá}} $1',
+'siteusers' => '{{SITENAME}} iōng-chiá $1',
# Patrolling
'markaspatrolleddiff' => 'Phiau-sī sûn--kòe',
-'markedaspatrolledtext' => 'Soán-te̍k ê siu-tēng-pún [[:$1]] í-keng kì-hō chò sûn--kòe.',
+'markedaspatrolledtext' => 'Í-keng phiau-sī chit ê siu-tēng-pún ū lâng sûn--kòe.',
# Image deletion
'deletedrevision' => 'Kū siu-tēng-pún $1 thâi-tiāu ā.',
# Browsing diffs
-'previousdiff' => '← Khì chêng 1 ê siu-kái',
-'nextdiff' => 'Khì āu 1 ê siu-kái →',
+'previousdiff' => '← Khì chêng 1 ê diff',
+'nextdiff' => 'Khì āu 1 ê diff →',
# Media information
-'imagemaxsize' => "Iáⁿ-siōng toā-sè ê hān-chè:<br />''(ēng tī tóng-àn soeh-bêng-ia̍h)''",
+'imagemaxsize' => 'Iáⁿ-siōng biô-su̍t-ia̍h ê tô· ke̍k-ke hián-sī jōa tōa tiuⁿ:',
'thumbsize' => 'Sok-tô· (thumbnail) jōa tōa tiuⁿ:',
'file-nohires' => 'Bô khah koân ê kái-sek-tō͘.',
# Special:NewFiles
'newimages' => 'Sin iáⁿ-siōng oē-lóng',
-'imagelisttext' => "Í-hā sī '''$1''' {{PLURAL:$1|tiuⁿ|tiuⁿ}} iáⁿ-siōng ê lia̍t-toaⁿ, chiàu $2 pâi-lia̍t.",
+'imagelisttext' => "Í-hā sī '''$1''' tiuⁿ iáⁿ-siōng ê lia̍t-toaⁿ, $2 pâi-lia̍t.",
'ilsubmit' => 'Kiám-sek',
'bydate' => 'chiàu ji̍t-kî',
# External editor support
'edit-externally' => 'Iōng gōa-pō· èng-iōng nńg-thé pian-chi̍p chit-ê tóng-àn',
-'edit-externally-help' => '(Khoàⁿ [//www.mediawiki.org/wiki/Manual:External_editors siat-tēng soat-bêng] ê chu-liāu.)',
+'edit-externally-help' => 'Chham-khó [http://www.mediawiki.org/wiki/Manual:External_editors Help:External_editors] ê soat-bêng.',
# 'all' in various places, this might be different for inflected languages
'watchlistall2' => 'choân-pō͘',
$3
-Nā-chún *m̄-sī* lí, chhiáⁿ khui ē-kha chit-ê liân-kiat, chhú-siau khak-jīn ê e-mail.
-
-$5
-
-Chit tiuⁿ phoe ê khak-jīn-bé ē chū-tōng tī $4 kòe-kî.',
+Nā-chún *m̄-sī* lí, chhiáⁿ mài tòe liân-kiat khì. Chit tiuⁿ phoe ê khak-jīn-bé ē chū-tōng tī $4 kòe-kî.',
'confirmemail_body_changed' => 'Ū lâng (IP $1, tāi-khài sī lí pún-lâng) tī {{SITENAME}} ēng chit-ê e-mail chū-chí chù-chheh 1 ê kháu-chō "$2".
Chhiáⁿ khui ē-kha chit-ê liân-kiat, thang khak-jīn chit-ê kháu-chō si̍t-chāi sī lí ê:
# Auto-summaries
'autosumm-blank' => 'Kā ia̍h ê loē-iông the̍h tiāu',
'autoredircomment' => 'Choán khì [[$1]]',
-'autosumm-new' => 'Sin ia̍h: $1...',
+'autosumm-new' => 'Sin ia̍h: $1',
# Watchlist editor
-'watchlistedit-numitems' => 'Lí ê kàm-sī-toaⁿ ū {{PLURAL:$1|$1 ia̍h|$1 ia̍h}}, thó-lūn-ia̍h bô sǹg chāi-lāi.',
+'watchlistedit-numitems' => 'Lí ê kàm-sī-toaⁿ ū $1 ia̍h, thó-lūn-ia̍h bô sǹg chāi-lāi.',
'watchlistedit-normal-submit' => 'Mài kàm-sī',
-'watchlistedit-normal-done' => 'Í-keng ū {{PLURAL:$1| ia̍h| ia̍h}} ùi lí ê kám-sī-toaⁿ soá cháu:',
+'watchlistedit-normal-done' => 'Í-keng ū $1 ia̍h ùi lí ê kám-sī-toaⁿ soá cháu:',
# Watchlist editing tools
'watchlisttools-edit' => 'Khoàⁿ koh kái kàm-sī-toaⁿ',
'movelogpagetext' => 'Ambelessì sota a-i é na lista ëd tute le pàgine che a son ëstàite tramudà.',
'movesubpage' => '{{PLURAL:$1|Sot-pàgina|Sot-pàgine}}',
'movesubpagetext' => "Costa pàgina-sì a l'ha $1 {{PLURAL:$1|sot-pàgina|sot-pàgine}} smonùe sì-sota.",
-'movenosubpage' => "Sta pàgina-sì a l'ha pa ëd sotpàgine.",
+'movenosubpage' => "Sta pàgina-sì a l'ha gnun-e sot-pàgine.",
'movereason' => 'Rason:',
-'revertmove' => "buta torna coma a l'era",
-'delete_and_move' => 'Scancela e tramuda',
-'delete_and_move_text' => '==A fa da manca dë scancelé==
+'revertmove' => "buté torna coma a l'era",
+'delete_and_move' => 'Scancelé e tramudé',
+'delete_and_move_text' => "==A fa da manca dë scancelé==
-L\'artìcol ëd destinassion "[[:$1]]" a-i é già. Veul-lo scancelelo për avej ëd pòst për tramudé l\'àutr?',
+L'artìcol ëd destinassion «[[:$1]]» a-i é già. Veul-lo scancelelo për avèj ëd pòst për tramudé l'àutr?",
'delete_and_move_confirm' => 'É, scancela la pàgina',
'delete_and_move_reason' => 'Scancelà për liberé ël pòst për tramudé "[[$1]]"',
'selfmove' => "Tìtol neuv e tìtol vej a resto midem antra lor; as peul pa tramudesse na pàgina butand-la andoa che a l'é già.",
'undelete-error-short' => 'فاغل واپس کرن چ غلطی: $1',
'undelete-error-long' => 'فائل واپس کرن لگیاں غلطیاں ہوئیاں:
$1',
-'undelete-show-file-confirm' => 'تساں نوں کیا پک اے جے تسیں فائل "<نوکی>$1</نوکی>" دی مٹائی ریوین $2 توں $3 تک ویکھنا چاندے او؟',
+'undelete-show-file-confirm' => 'تساں نوں کیا پک اے جے تسیں فائل "<nowiki>$1</nowiki>" دی مٹائی ریوین $2 توں $3 تک ویکھنا چاندے او؟',
'undelete-show-file-submit' => 'ہاں جی',
# Namespace form on various pages
'import-revision-count' => '$1 {{PLURAL:$1|ریوین}}',
'importnopages' => 'لانے آسطے کوئی صفحہ نئیں۔',
'imported-log-entries' => '{{PLURAL:$1|لاگ انٹریلاگ انٹریاں}}!!لیاندی گئی $1 {{PLURAL:$1|لاگ انٹری}}.',
-'importfailed' => 'لیانا فیل: <نوکی>$1</نوکی>',
+'importfailed' => 'لیانا فیل: <nowiki>$1</nowiki>',
'importunknownsource' => 'انجان لیان سورس ٹائپ',
'importcantopen' => 'لیاندی گئی فائل نئیں کھولی جاسکی',
'importbadinterwiki' => 'پیڑا انٹروکی لنک',
O registo de bloqueios é fornecido abaixo para referência:',
'blocklog-showsuppresslog' => 'Este utilizador foi bloqueado e ocultado anteriomente.
O registo de supressão é fornecido abaixo para referência:',
-'blocklogentry' => 'bloqueou "[[$1]]" $3. O bloqueio expira em $2.',
+'blocklogentry' => 'bloqueou "[[$1]]" por $2. $3',
'reblock-logentry' => 'modificou parâmetros de bloqueio de [[$1]] com expiração em $2. $3',
'blocklogtext' => 'Este é um registo de ações de bloqueio e desbloqueio.
Endereços IP sujeitos a bloqueio automático não estão listados.
'file-info-size-pages' => '$1 × $2 pixeli, mărime fișier: $3, tip MIME: $4, $5 {{PLURAL:$5|pagină|pagini}}',
'file-nohires' => 'Rezoluții mai mari nu sunt disponibile.',
'svg-long-desc' => 'fișier SVG, cu dimensiunea nominală de $1 × $2 pixeli, mărime fișier: $3',
-'show-big-image' => 'Mărește rezoluția imaginii',
+'show-big-image' => 'Rezoluție maximă',
'show-big-image-preview' => 'Mărimea acestei previzualizări: $1.',
'show-big-image-other' => '{{PLURAL:$2|Altă rezoluție|Alte rezoluții}}: $1.',
'show-big-image-size' => '$1 × $2 pixeli',
'parser-template-recursion-depth-warning' => "Ha state supranete 'u limite di ricorsione de le template ($1)",
'language-converter-depth-warning' => "'U convertitore de lènghe ha subranate 'u limite de profonnetà ($1)",
'node-count-exceeded-category' => "Pàggene addò 'u cunde de le node ha sbunnate",
+'node-count-exceeded-warning' => "Pagene ha sbunnate 'u condegge de le node",
'expansion-depth-exceeded-category' => "Pàggene addò 'a profonnetà de l'espanzione jè supranate",
'expansion-depth-exceeded-warning' => "Pàggene ca sbonnane 'a profonnetà de espanzione",
# Diffs
'history-title' => 'Liste de le versiune de "$1"',
+'difference-title' => 'Differenze \'mbrà revisiune de "$1"',
+'difference-title-multipage' => 'Differenze \'mbrà le pàggene "$1" e "$2"',
'difference-multipage' => "(Differenze 'mbrà le pàggene)",
'lineno' => 'Linea $1:',
'compareselectedversions' => 'Combronde le versiune selezionete',
'backend-fail-read' => "Non ge pozze leggere 'u file $1.",
'backend-fail-create' => "Non ge pozze ccrejà 'u file $1.",
'backend-fail-readonly' => 'L\'archivije de rete "$1" jè pe stu mumende in sole letture. \'U mutive ha state: "$2"',
+'backend-fail-synced' => "'U file \"\$1\" jè jndr'à 'nu state ingonsistende jndr'à l'archivije inderne",
'backend-fail-connect' => 'Non ge pozze connettere \'a memorie de rrete "$1".',
'backend-fail-internal' => "'N'errore scanusciute s'à verificate jndr'à l'archivije de rrete \"\$1\".",
'backend-fail-contenttype' => 'Non ge pozze capìe \'u tipe de condenute d\'u file da reggistrà sus a "$1".',
'api-error-badaccess-groups' => 'Tu non ge puè carecà file sus a sta Uicchi.',
'api-error-badtoken' => 'Errore inderne: Gettone errate.',
'api-error-copyuploaddisabled' => "'U carecamende da URL jè disabbilitate sus a stu server.",
+'api-error-duplicate-archive-popup-title' => "Dupliche {{PLURAL:$1|'u file ca ha state|le file ca onne state}} scangellate.",
'api-error-duplicate-popup-title' => 'Dupleche {{PLURAL:$1|file|file}}',
'api-error-empty-file' => "'U file ca tu è confermate ere vacande.",
'api-error-emptypage' => 'Quanne se ne ccreje une, le pàggene vacande non ge sò permesse.',
'api-error-hookaborted' => "'U cangiamende ca tu stè pruève a ffà ha state inderrotte da 'n'estenzione.",
'api-error-http' => "Errore inderne: Non ge se riesce a collegà a 'u server",
'api-error-illegal-filename' => "'U nome d'u file non g'è permesse.",
+'api-error-internal-error' => "Errore inderne: Quaccheccose ha sciute male mendre ca ste processamme 'u carecamende tune sus 'a uicchi.",
'api-error-invalid-file-key' => "Errore inderne: 'U file non ge se iacchie jndr'à memorie temboranèe.",
'api-error-missingparam' => 'Errore inderne: Parametre mangande sus a richieste.',
'api-error-missingresult' => "Errore inderne: Non ge se pò determinà ce 'a copie ha state fatte.",
'searchbutton' => 'Найти',
'go' => 'Перейти',
'searcharticle' => 'Перейти',
-'history' => 'история',
+'history' => 'Ð\98стория',
'history_short' => 'история',
'updatedmarker' => 'обновлено после моего последнего посещения',
'printableversion' => 'Версия для печати',
# Diffs
'history-title' => '$1 — история изменений',
'difference-title' => 'Разница между пересмотров " $1 "',
-'difference-title-multipage' => 'Разница между страницами " $1 «и» $2 "',
+'difference-title-multipage' => 'Разница между страницами «$1» и «$2»',
'difference-multipage' => '(Различия между страницами)',
'lineno' => 'Строка $1:',
'compareselectedversions' => 'Сравнить выбранные версии',
'userinvalidcssjstitle' => "'''Увага:''' Тема взгляду „$1“ не екзістує. Не забудьте, же хосновательске .css і .js файлы хоснують малы писмена, наприклад {{ns:user}}:{{BASEPAGENAME}}/vector.css, а не {{ns:user}}:{{BASEPAGENAME}}/Vector.css.",
'updated' => '(Зміна уложена)',
'note' => "'''Позначка:''' ",
-'previewnote' => "'''Ð\9fамÑ\8fÑ\82айÑ\82е, же Ñ\82о лем попеÑ\80еднÑ\97й пеÑ\80еглÑ\8fд,
-текст іщі не є уложеный!'''",
+'previewnote' => "'''Ð\9fамÑ\8fÑ\82айÑ\82е, же Ñ\82о лем наглÑ\8fд.'''
+Зміны іщі не суть уложены!",
'previewconflict' => 'Тот нагляд зображує текст так, як буде вызерати по уложіню сторінкы.',
'session_fail_preview' => "'''Вашу пожадавку ся не подарило зпрацовати, бо были страчены дата сеансу.
Просиме, спробуйте то зясь.
'api-error-uploaddisabled' => 'Начітаваня файлів є на тій вікі выпнуте.',
'api-error-verification-error' => 'Файл є може пошкодженый, або мать плане росшырїня.',
+# Durations
+'duration-seconds' => '$1 {{PLURAL:$1|секунда|секунды|секунд}}',
+'duration-minutes' => '$1 {{PLURAL:$1|минуту|минуты|минут}}',
+'duration-hours' => '$1 {{PLURAL:$1|година|годины|годин}}',
+'duration-days' => '$1 {{PLURAL:$1|день|днї|днів}}',
+'duration-weeks' => '$1 {{PLURAL:$1|тыждень|тыжднї|тыжднїв}}',
+'duration-years' => '$1 {{PLURAL:$1|рік|рокы|років}}',
+'duration-decades' => '$1 {{PLURAL:$1|декада|декады|декад}}',
+'duration-centuries' => '$1 {{PLURAL:$1|стороча|стороча|стороч}}',
+
);
$messages = array(
# User preference toggles
+'tog-underline' => 'Joṛaoko latarre dag udugoḱma:',
+'tog-justify' => 'Olaḱ kạli mońjte sajao:',
'tog-hideminor' => 'Nitaḱ bodolaḱre huḍiṅ kạmi danaṅme',
+'tog-hidepatrolled' => 'Joṛaoakanaḱko nãwã bodolaḱte danaṅkam',
+'tog-newpageshidepatrolled' => 'Biḍạakanaḱ sakamko nãwã sakamreaḱ talikare danȧkam',
'tog-extendwatchlist' => 'Khạli nitoḱ bodolko do baṅ, joto bodolkodo ńeloḱ tạlikare phaylaomẽ.',
+'tog-usenewrc' => 'Cetan darja reaḱ nãwã bodolakanaḱko beoharme',
+'tog-numberheadings' => 'Mukhiạ kathako do actege piṛhipiṛhite sajaḱma',
+'tog-showtoolbar' => 'Joṛaoakanaḱ ṭulbar udugoḱma',
+'tog-editondblclick' => 'Bar dhao lin kate sakam torjomão reaḱ ạidari emogoḱma',
+'tog-editsection' => '[Joṛao] Pahaṭako do joṛao hotete aćtege hoyoḱ lạgit aidạri em ocoḱma',
'tog-showtoc' => 'Ṭibilre menaḱako ńel ( sakamkore 3 khon jạti hedlayenko)',
'tog-watchcreations' => 'Sakamko songe Ińaḱ ńelok tạlikare benao',
'tog-watchdefault' => 'Sakam tońgey me Iń do ińaḱ ńeloḱ tạlikare joṛaokeda',
'tog-watchmoves' => 'Sakamko tońgeyme Ińaḱ ńelok tạlikare kulme',
'tog-watchdeletion' => 'Sakamko tońgeyme Ińaḱ ńeloḱ tạlika khon get́ giḍikam',
+'tog-previewontop' => 'Joṛao bakso purạo lahare unuduḱ hoyoḱma',
+'tog-previewonfirst' => 'Pạhil joṛao purạore unuduḱ hoyoḱma',
+'tog-nocache' => 'Brajar sakam reaḱ kasiṅ bondoemẽ',
'tog-enotifwatchlistpages' => 'E-mailạńme one tinre in̕aḱ n̕eloḱ tạlika do bodolok',
'tog-enotifusertalkpages' => 'E-mailạn̕me one tinre in̕aḱ roṛaḱ laṛcaṛ sakam do bodoloḱa',
'tog-enotifminoredits' => 'E-mailạn̕me arhõ one tinre in̕aḱ sakamre huḍiń kạmi hoyoḱ',
'underline-always' => 'Sanam okte',
'underline-never' => 'Tis hõ ban̕',
+'underline-default' => 'Browjarre cetlekate em hoy akana',
+
+# Font style option in Special:Preferences
+'editfont-serif' => 'Serif fonṭ',
# Dates
'sunday' => 'Aṭhowar',
'yourname' => 'Beoboharicaḱ ńutum',
'yourpassword' => 'Uku namber',
'yourpasswordagain' => 'Arhõ oku namber olme',
-'remembermypassword' => 'In̕aḱ boloḱaḱ disạyme',
+'remembermypassword' => 'Mit khon jạsti pahaṭa reaḱ katha cạbi disạ tahẽnma (Jạsti utạr $1{{PRURAL;$1 din reaḱ din reaḱ}} lạgit)',
'securelogin-stick-https' => 'Bhitri bolo kate HTTPS re soṅge tãhenme',
'login' => "bolok' duar",
'nav-login-createaccount' => 'Boloḱ́ duạr / ekaunt tearme',
'logout' => 'Bahre oḍoń',
'userlogout' => 'Bahre oḍoń',
'notloggedin' => 'Bhitri baṅ bolokana',
-'nologin' => 'Ekaunṭ bạnuḱtama?',
+'nologin' => 'Amaḱ do cet́ wikipediare ekauntx banukytama? Ado',
'nologinlink' => 'account tear me',
'createaccount' => 'Ṭhai benaome',
-'gotaccount' => 'Ekaunṭ menaḱgeya?',
+'gotaccount' => 'Amaḱ do cet́ miṭten ekaunṭ tear menaḱtama? $1 tearmẽ.',
'gotaccountlink' => 'Bhitri bolon',
'userlogin-resetlink' => 'Amaḱ boloḱ talam cạbi sanamem hiṛińkeda?',
'createaccountmail' => 'E-mail hotete',
'previewnote' => "'''Disạyme noa do eken ńeln̕am lạgit.'''
Amaḱ bodolaḱ kodo nit habićte bań ban̕cao akana!",
'continue-editing' => 'Toṅge calaḱkana',
-'editing' => 'Sampadon; joṛao',
+'editing' => 'Joṛao do purạena: $1',
'creating' => 'Benao',
'editingsection' => 'Joṛao $1 (hạṭiń)',
'editingcomment' => 'Joṛao',
'yourtext' => 'Amaḱ ol',
-'templatesused' => 'Noa sakamre beoharen phormat se phormatko',
+'templatesused' => 'Noa sakamre beoharen {{PRURAL:$1 ṭempeleṭ ṭempeleṭko}}:',
'template-protected' => 'Rukhiạ',
'template-semiprotected' => '(Kạṭic-rukhiyạ)',
-'hiddencategories' => 'Noa sakam do mitṭen hoṛkanay',
+'hiddencategories' => 'Noa sakam do {{PLURAL:$1 1 ukuakan bhag $1 uku akan bhagkorenaḱ}} gaõtarenge:',
'permissionserrorstext-withaction' => 'Amaḱ do aydạri bạnuḱtama, Noa karon pan̕jay lạgitte',
'recreate-moveddeleted-warn' => "'''Sontorokme: am do arhõ doṛhate sakamem teyareda oka do sedayre get giḍiyen.
Am do gunạnme cet́ noa joṛao kạmi am lạgit́te ganoḱ ase bań.
'searchprofile-images-tooltip' => 'File sendra',
'searchprofile-everything-tooltip' => 'Sanam ko modre sẽndra ( roṛ sakam modre hõ)',
'searchprofile-advanced-tooltip' => 'Judạ ńutum re sẽndra',
-'search-result-size' => 'Katha Kathako',
+'search-result-size' => '$1 ({{PLURAL:$2 1 Aṛaṅ$2 Aṛaṅko}})',
'search-redirect' => '($1 te sujhi doṛha )',
'search-section' => '(Pahaṭa $1)',
'search-suggest' => 'Am do cet́ $1 em menocoyet tãhẽkana',
'filehist-dimensions' => 'Maṕ',
'filehist-comment' => 'Roṛ',
'imagelinks' => 'Fael bebohar',
-'linkstoimage' => 'Noa sakam do niạ rẽtre/fayel joṛao menaḱa',
+'linkstoimage' => 'Latar reaḱ {{PLURAL:}}$1 gan sakam gan sakam}} khon noa ret̃re joṛao menaḱa:',
'nolinkstoimage' => 'Nonḍe do noa são joṛao sakam banuka',
'sharedupload-desc-here' => 'Noa rẽt do nonḍe khon- $1 ar paseć eṭaḱaḱ porjekṭko beoharakana.
Noa reaḱ pasnao katha [$2 rẽt pasnao sakam] latare emena',
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|baiṭ|baiṭ}}',
-'nmembers' => 'Sãoten/ Sãotenko',
+'nmembers' => '$1 {{PLURAL:$1 Gaõtaren Gaõtarenko',
'prefixindex' => 'Sanam sakam re joṛao menaḱ',
'shortpages' => 'Huḍiń sakamko',
'longpages' => 'Jiliń sakamko',
# Watchlist
'watchlist' => "Inak' n'el ko",
'mywatchlist' => 'Iñak jagarna tạlikạ',
-'watchlistfor2' => 'Lạgit',
+'watchlistfor2' => '$1 ($2) lạ̣gitte',
'watch' => 'Ńelme',
'unwatch' => "bang nelok' a",
'wlshowlast' => 'Mucạt 1 ghonta mucạt 2 maha uduḱme',
'isredirect' => 'Bań sojhe sakam',
'istemplate' => 'Ar mit́ teć sãote joṛao',
'isimage' => 'Ret joṛao',
-'whatlinkshere-prev' => 'Tayom renaḱ Táoy renaḱko',
+'whatlinkshere-prev' => 'Laha renaḱ laha renaḱko',
'whatlinkshere-next' => 'Laha renaḱ Laha renaḱko',
'whatlinkshere-links' => 'Joṛaoko',
'whatlinkshere-hideredirs' => '$1 acurgeya',
'whatlinkshere-hidetrans' => 'Bodolaḱ danaṅ',
-'whatlinkshere-hidelinks' => 'Joṛao danaṅ se uduḱme',
-'whatlinkshere-hideimages' => 'phoṭo em',
+'whatlinkshere-hidelinks' => '$1 joṛao',
+'whatlinkshere-hideimages' => 'Chubi em',
'whatlinkshere-filters' => 'Sapha',
# Block/unblock
* @author Kandar
* @author Meursault2004
* @author Mssetiadi
+ * @author Reedy
* @author Urhixidur
* @author לערי ריינהארט
*/
* Sasaran nudipeungpeuk : \$7
Anjeun bisa nepungan \$1 atawa salasahiji [[{{MediaWiki:Grouppage-sysop}}|kuncén]] séjén pikeun nyawalakeun hal ieu.
-'''<u>Catet</u>''': yén anjeun teu bisa maké fungsi \"surélékan pamaké ieu\" mun anjeun teu ngadaptarkeun alamat surélék nu sah kana [[Special:Preferences|préferénsi pamaké]] anjeun.
+'''Catet''': yén anjeun teu bisa maké fungsi \"surélékan pamaké ieu\" mun anjeun teu ngadaptarkeun alamat surélék nu sah kana [[Special:Preferences|préferénsi pamaké]] anjeun.
Alamat IP anjeun \$3 jeung ID na #\$5.
Lampirkeun informasi ieu dina unggal ''query'' anjeun.",
* @ingroup Language
* @file
*
+ * @author Erdemaslancan
* @author Ganbarzada
* @author Tuzkozbir
* @author Гусейн
# Undelete
'undeletelink' => 'чәшику дәвонијеј/бәрпо кардеј',
'undeleteviewlink' => 'тәмшо кардеј',
+'undelete-search-submit' => 'Нәве',
+'undelete-show-file-submit' => 'Бәле',
# Namespace form on various pages
'namespace' => 'Номон мәкон:',
'tooltip-undo' => 'Дәғандә дәгиши рәдд кардеј ијән "сыфтәнә нишо дој" окардеј, де ләғви сәбәби нышон дој имкони.',
'tooltip-summary' => 'Кыртә тәсвир бынывыштән',
+# Info page
+'pageinfo-header-edits' => 'Сәрост кардеј',
+'pageinfo-header-views' => 'Тәмшо',
+'pageinfo-subjectpage' => 'Сәһифә',
+
# Browsing diffs
'previousdiff' => '← Навынәни дәгиши',
'nextdiff' => 'Думотоно шә дәгиши →',
'svg-long-desc' => 'SVG фајл, номинәләдә $1 × $2 пиксел, фајли памјә: $3',
'show-big-image' => 'Тикәјән јолә кејфијјәтинә шикил',
+# Special:NewFiles
+'ilsubmit' => 'Нәве',
+
# Bad image list
'bad_image_list' => 'Формат бәпе быбу жыго:
* gpslongitude
* gpsaltitude',
+'exif-gaincontrol-0' => 'Ни',
+
+'exif-saturation-0' => 'Ади',
+
# External editor support
'edit-externally' => 'Редактә кардеј ым фајли де заһири програм',
'edit-externally-help' => '(Бо мыффәссәлә мәлумотон бә [//www.mediawiki.org/wiki/Manual:External_editors дәрсәвон бо сохтәј] дијә быкан)',
# Core parser functions
'duplicate-defaultsort' => '\'\'\'Дыггәт:\'\'\' Еһтимал кардә быә "$2" классификасијә ачари нафконә "$1" классификасијә ачари етиборсоз кардә',
+# Special:Version
+'version-entrypoints-header-url' => 'URL',
+
+# Special:FilePath
+'filepath-page' => 'Фајл:',
+'filepath-submit' => 'Давард',
+
+# Special:FileDuplicateSearch
+'fileduplicatesearch-submit' => 'Нәве',
+
# Special:SpecialPages
'specialpages' => 'Хысусиә сәһифон',
* @author Myildirim2007
* @author Reedy
* @author Runningfridgesrule
+ * @author Sadrettin
* @author Srhat
* @author Stultiwikia
* @author Suelnur
'note' => "'''Not: '''",
'previewnote' => "'''Bunun yalnızca bir ön izleme olduğunu unutmayın.'''
Yaptığınız değişiklikler henüz kaydedilmedi!",
+'continue-editing' => 'Düzenlemeye devam et',
'previewconflict' => 'Bu önizleme metin düzenleme kutucuğunun üstünde, maddenin eğer değişikliklerinizi kaydetmeyi seçerseniz nasıl görüneceğini yansıtır.',
'session_fail_preview' => 'Özür dileriz. Oturum açılması ile ilgili veri kaybından kaynaklı değişikliğinizi kaydedemedik. Lütfen tekrar deneyiniz. Eğer bu yöntem işe yaramazsa oturumu kapatıp tekrar sisteme geri giriş yapınız.',
'session_fail_preview_html' => "'''Üzgünüz! Oturum verisinin kaybolmasından dolayı düzenlemenizi işleme geçiremeyeceğiz.'''
'exif-subjectnewscode' => 'Konu kodu',
'exif-event' => 'Adı geçen olay',
'exif-personinimage' => 'Adı geçen kişi',
+'exif-originalimageheight' => 'Resmin kırpılmadan önceki yükseliği',
+'exif-originalimagewidth' => 'Resmin kırpılmadan önceki genişliği',
# EXIF attributes
'exif-compression-1' => 'Sıkıştırılmamış',
'api-error-mustbeposted' => 'İç hata: İstek HTTP POST gerektiriyor.',
'api-error-nomodule' => 'İç hata: Yükleme modülü ayarı yapılmadı.',
'api-error-ok-but-empty' => 'İç hata: Sunucu yanıt vermiyor.',
+'api-error-overwrite' => 'Varolan dosyanın üzerine yazmaya izin verilmiyor.',
'api-error-stashfailed' => 'İç hata: Sunucu, geçici dosyaları kaybetti.',
'api-error-unclassified' => 'Bilinmeyen bir hata oluştu.',
'api-error-unknown-code' => 'Bilinmeyen hata: "$1"',
'api-error-unknown-warning' => 'Bilinmeyen uyarı: $1',
'api-error-unknownerror' => 'Bilinmeyen hata: "$1".',
'api-error-uploaddisabled' => 'Yükleme bu vikide devre dışı bırakılmıştır.',
+'api-error-verification-error' => 'Dosya bozuk veya yanlış uzantıya sahip olabilir.',
);
Điều này thường xảy ra khi bạn sử dụng một dịch vụ proxy vô danh trên web có vấn đề.'''",
'edit_form_incomplete' => "'''Một số phần của biểu mẫu sửa đổi không tới được máy chủ. Hãy kiểm tra rằng các sửa đổi của bạn còn nguyên và thử lại.'''",
'editing' => 'Sửa đổi $1',
-'creating' => 'Đang tạo $1',
+'creating' => 'Tạo $1',
'editingsection' => 'Sửa đổi $1 (đề mục)',
'editingcomment' => 'Sửa đổi $1 (đề mục mới)',
'editconflict' => 'Sửa đổi mâu thuẫn: $1',
'scarytranscludetoolong' => "[Võrgoaadrõs om pall'o pikk]",
# Delete conflict
-'deletedwhileediting' => "<center>'''Hoiatus''': taa leht om ärq kistutõt päält tuud, ku sa taad toimõndama naksit!</center>",
+'deletedwhileediting' => "'''Hoiatus''': taa leht om ärq kistutõt päält tuud, ku sa taad toimõndama naksit!",
'confirmrecreate' => "Pruukja '''[[User:$1|$1]]''' ([[User talk:$1|arotus]]) kistut' taa lehe ärq päält tuud, ku sa naksit taad toimõndama. Põhjus oll':
: ''$2''
Olõq hää, kinnüdäq, et tahat taad lehte vahtsõst luvvaq.",
'exif-gpslongitude-e' => 'מזרח לענג',
'exif-gpslongitude-w' => 'מערב לענג',
+# Pseudotags used for GPSAltitudeRef
+'exif-gpsaltitude-above-sealevel' => '$1 {{PLURAL:$1|ngמעטער|מעטער}} איבערן ים־שפיגלl',
+'exif-gpsaltitude-below-sealevel' => '$1 {{PLURAL:$1|מעטער|מעטער}} אונטערן ים־שפיגל',
+
# Pseudotags used for GPSSpeedRef
'exif-gpsspeed-k' => 'ק"מ אין א שעה',
'exif-gpsspeed-m' => 'מייל פער שעה',
'version-software' => 'אינסטאַלירט ווייכוואַרג',
'version-software-product' => 'פראדוקט',
'version-software-version' => 'ווערסיע',
+'version-entrypoints-header-url' => 'URL',
# Special:FilePath
'filepath' => 'טעקע שטעג',
'titleprotected' => "這個標題已經被[[User:$1|$1]]保護以防止建立。理由是''$2''。",
'filereadonlyerror' => '無法修改文件" $1 "因為文件庫" $2 "處於唯讀模式。 !
管理員鎖定它的解釋是:" $3 "。',
+'invalidtitle-knownnamespace' => '使用名字空間“$2”和文本“$3”的無效標題',
+'invalidtitle-unknownnamespace' => '使用未知名字空間編號$1和文本“$2”的無效標題',
# Virus scanner
'virus-badscanner' => "損壞設定: 未知的病毒掃瞄器: ''$1''",
# Diffs
'history-title' => '「$1」的修訂歷史',
+'difference-title' => '"$1"修訂版本之間的差異',
+'difference-title-multipage' => '"$1"和"$2"頁面之間的差異',
'difference-multipage' => '(頁面間的差異)',
'lineno' => '第$1行:',
'compareselectedversions' => '比較選定的修訂版本',
'http-curl-error' => '擷取URL時出錯:$1',
'http-host-unreachable' => '無法到達URL。',
'http-bad-status' => '進行HTTP請求時出現問題:$1 $2',
+'http-truncated-body' => '只收到部分請求的正文。',
# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
'upload-curl-error6' => '無法訪問 URL',
--- /dev/null
+<?php
+/**
+ * Sync one file backend to another based on the journal of later.
+ *
+ * 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
+ *
+ * @ingroup Maintenance
+ */
+
+require_once( dirname( __FILE__ ) . '/Maintenance.php' );
+
+class SyncFileBackend extends Maintenance {
+ public function __construct() {
+ parent::__construct();
+ $this->mDescription = "Sync one file backend with another using the journal";
+ $this->addOption( 'src', 'Name of backend to sync from', true, true );
+ $this->addOption( 'dst', 'Name of destination backend to sync', true, true );
+ $this->addOption( 'start', 'Starting journal ID', false, true );
+ $this->addOption( 'end', 'Ending journal ID', false, true );
+ $this->addOption( 'posdir', 'Directory to read/record journal positions', false, true );
+ $this->addOption( 'verbose', 'Verbose mode', false, false, 'v' );
+ $this->setBatchSize( 50 );
+ }
+
+ public function execute() {
+ $src = FileBackendGroup::singleton()->get( $this->getOption( 'src' ) );
+ $dst = FileBackendGroup::singleton()->get( $this->getOption( 'dst' ) );
+
+ $posFile = $this->getOption( 'posdir' )
+ ? $this->getOption( 'posdir' ) . '/' . wfWikiID()
+ : false;
+
+ $start = $this->getOption( 'start', 0 );
+ if ( !$start && $posFile ) {
+ $start = is_file( $posFile )
+ ? (int)trim( file_get_contents( $posFile ) )
+ : 0;
+ ++$start; // we already did this ID, start with the next one
+ $startFromPosFile = true;
+ } else {
+ $startFromPosFile = false;
+ }
+ $end = $this->getOption( 'end', INF );
+
+ $this->output( "Synchronizing backend '{$dst->getName()}' to '{$src->getName()}'...\n" );
+ $this->output( "Starting journal position is $start.\n" );
+ if ( is_finite( $end ) ) {
+ $this->output( "Ending journal position is $end.\n" );
+ }
+
+ // Actually sync the dest backend with the reference backend
+ $lastOKPos = $this->syncBackends( $src, $dst, $start, $end );
+
+ // Update the sync position file
+ if ( $startFromPosFile && $lastOKPos >= $start ) { // successfully advanced
+ file_put_contents( $posFile, $lastOKPos, LOCK_EX );
+ $this->output( "Updated journal position file.\n" );
+ }
+
+ if ( $lastOKPos === false ) {
+ if ( !$start ) {
+ $this->output( "No journal entries found.\n" );
+ } else {
+ $this->output( "No new journal entries found.\n" );
+ }
+ } else {
+ $this->output( "Stopped synchronization at journal position $lastOKPos.\n" );
+ }
+
+ if ( $this->isQuiet() ) {
+ print $lastOKPos; // give a single machine-readable number
+ }
+ }
+
+ /**
+ * Sync $dst backend to $src backend based on the $src logs given after $start.
+ * Returns the journal entry ID this advanced to and handled (inclusive).
+ *
+ * @param $src FileBackend
+ * @param $dst FileBackend
+ * @param $start integer Starting journal position
+ * @param $end integer Starting journal position
+ * @return integer|false Journal entry ID or false if there are none
+ */
+ protected function syncBackends( FileBackend $src, FileBackend $dst, $start, $end ) {
+ $lastOKPos = 0; // failed
+ $first = true; // first batch
+
+ if ( $start > $end ) { // sanity
+ $this->error( "Error: given starting ID greater than ending ID.", 1 );
+ }
+
+ do {
+ $limit = min( $this->mBatchSize, $end - $start + 1 ); // don't go pass ending ID
+ $this->output( "Doing id $start to " . ( $start + $limit - 1 ) . "...\n" );
+
+ $entries = $src->getJournal()->getChangeEntries( $start, $limit, $next );
+ $start = $next; // start where we left off next time
+ if ( $first && !count( $entries ) ) {
+ return false; // nothing to do
+ }
+ $first = false;
+
+ $lastPosInBatch = 0;
+ $pathsInBatch = array(); // changed paths
+ foreach ( $entries as $entry ) {
+ if ( $entry['op'] !== 'null' ) { // null ops are just for reference
+ $pathsInBatch[$entry['path']] = 1; // remove duplicates
+ }
+ $lastPosInBatch = $entry['id'];
+ }
+
+ $status = $this->syncFileBatch( array_keys( $pathsInBatch ), $src, $dst );
+ if ( $status->isOK() ) {
+ $lastOKPos = max( $lastOKPos, $lastPosInBatch );
+ } else {
+ $this->output( print_r( $status->getErrorsArray(), true ) );
+ break; // no gaps; everything up to $lastPos must be OK
+ }
+
+ if ( !$start ) {
+ $this->output( "End of journal entries.\n" );
+ }
+ } while ( $start && $start <= $end );
+
+ return $lastOKPos;
+ }
+
+ /**
+ * Sync particular files of backend $src to the corresponding $dst backend files
+ *
+ * @param $paths Array
+ * @param $src FileBackend
+ * @param $dst FileBackend
+ * @return Status
+ */
+ protected function syncFileBatch( array $paths, FileBackend $src, FileBackend $dst ) {
+ $status = Status::newGood();
+ if ( !count( $paths ) ) {
+ return $status; // nothing to do
+ }
+
+ // Source: convert internal backend names (FileBackendMultiWrite) to the public one
+ $sPaths = $this->replaceNamePaths( $paths, $src );
+ // Destination: get corresponding path name
+ $dPaths = $this->replaceNamePaths( $paths, $dst );
+
+ // Lock the live backend paths from modification
+ $sLock = $src->getScopedFileLocks( $sPaths, LockManager::LOCK_UW, $status );
+ $eLock = $dst->getScopedFileLocks( $dPaths, LockManager::LOCK_EX, $status );
+ if ( !$status->isOK() ) {
+ return $status;
+ }
+
+ $ops = array();
+ $fsFiles = array();
+ foreach ( $sPaths as $i => $sPath ) {
+ $dPath = $dPaths[$i]; // destination
+ $sExists = $src->fileExists( array( 'src' => $sPath, 'latest' => 1 ) );
+ if ( $sExists === true ) { // exists in source
+ if ( $this->filesAreSame( $src, $dst, $sPath, $dPath ) ) {
+ continue; // avoid local copies for non-FS backends
+ }
+ // Note: getLocalReference() is fast for FS backends
+ $fsFile = $src->getLocalReference( array( 'src' => $sPath, 'latest' => 1 ) );
+ if ( !$fsFile ) {
+ $this->error( "Unable to sync '$dPath': could not get local copy." );
+ $status->fatal( 'backend-fail-internal', $src->getName() );
+ return $status;
+ }
+ $fsFiles[] = $fsFile; // keep TempFSFile objects alive as needed
+ // Note: prepare() is usually fast for key/value backends
+ $status->merge( $dst->prepare( array( 'dir' => dirname( $dPath ) ) ) );
+ if ( !$status->isOK() ) {
+ return $status;
+ }
+ $ops[] = array( 'op' => 'store',
+ 'src' => $fsFile->getPath(), 'dst' => $dPath, 'overwrite' => 1 );
+ } elseif ( $sExists === false ) { // does not exist in source
+ $ops[] = array( 'op' => 'delete', 'src' => $dPath, 'ignoreMissingSource' => 1 );
+ } else { // error
+ $this->error( "Unable to sync '$dPath': could not stat file." );
+ $status->fatal( 'backend-fail-internal', $src->getName() );
+ return $status;
+ }
+ }
+
+ $status->merge( $dst->doOperations( $ops,
+ array( 'nonLocking' => 1, 'nonJournaled' => 1 ) ) );
+ if ( $status->isOK() && $this->getOption( 'verbose' ) ) {
+ $this->output( "Synchronized these file(s):\n" . implode( "\n", $dPaths ) . "\n" );
+ }
+
+ return $status;
+ }
+
+ /**
+ * Substitute the backend name of storage paths with that of a given one
+ *
+ * @param $paths Array|string List of paths or single string path
+ * @return Array|string
+ */
+ protected function replaceNamePaths( $paths, FileBackend $backend ) {
+ return preg_replace(
+ '!^mwstore://([^/]+)!',
+ StringUtils::escapeRegexReplacement( "mwstore://" . $backend->getName() ),
+ $paths // string or array
+ );
+ }
+
+ protected function filesAreSame( FileBackend $src, FileBackend $dst, $sPath, $dPath ) {
+ return (
+ ( $src->getFileSize( array( 'src' => $sPath ) )
+ === $dst->getFileSize( array( 'src' => $dPath ) ) // short-circuit
+ ) && ( $src->getFileSha1Base36( array( 'src' => $sPath ) )
+ === $dst->getFileSha1Base36( array( 'src' => $dPath ) )
+ )
+ );
+ }
+}
+
+$maintClass = "SyncFileBackend";
+require_once( RUN_MAINTENANCE_IF_MAIN );