* Routing configuration for HTCP multicast purging. Add elements here to
* enable HTCP and determine which purges are sent where. If set to an empty
* array, HTCP is disabled.
- *
+ *
* Each key in this array is a regular expression to match against the purged
* URL, or an empty string to match all URLs. The purged URL is matched against
* the regexes in the order specified, and the first rule whose regex matches
* is used.
- *
+ *
* Example configuration to send purges for upload.wikimedia.org to one
* multicast group and all other purges to another:
* $wgHTCPMulticastRouting = array(
* 'port' => 4827,
* ),
* );
- *
+ *
* @see $wgHTCPMulticastTTL
*/
$wgHTCPMulticastRouting = array();
*
* Note that MediaWiki uses the old non-RFC compliant HTCP format, which was
* present in the earliest Squid implementations of the protocol.
- *
+ *
* This setting is DEPRECATED in favor of $wgHTCPMulticastRouting , and kept
* for backwards compatibility only. If $wgHTCPMulticastRouting is set, this
* setting is ignored. If $wgHTCPMulticastRouting is not set and this setting
* is, it is used to populate $wgHTCPMulticastRouting.
- *
+ *
* @deprecated in favor of $wgHTCPMulticastRouting
*/
$wgHTCPMulticastAddress = false;
*/
$wgDisableCounters = false;
+/**
+ * Set this to an integer to only do synchronous site_stats updates
+ * one every *this many* updates. The other requests go into pending
+ * delta values in $wgMemc. Make sure that $wgMemc is a global cache.
+ * If set to -1, updates *only* go to $wgMemc (useful for daemons).
+ */
+$wgSiteStatsAsyncFactor = false;
+
/**
* Parser test suite files to be run by parserTests.php when no specific
* filename is passed to it.
* Implements functions related to mime types such as detection and mapping to
* file extension.
*
- * Instances of this class are stateles, there only needs to be one global instance
+ * Instances of this class are stateless, there only needs to be one global instance
* of MimeMagic. Please use MimeMagic::singleton() to get that instance.
*/
class MimeMagic {
continue;
}
- #print "processing MIME line $s<br>";
-
$mime = substr( $s, 0, $i );
$ext = trim( substr($s, $i+1 ) );
$wgCanonicalServer, $wgScript;
if( $this->mAttribs['rc_type'] == RC_LOG ) {
- $titleObj = SpecialPage::getTitleFor( 'Log', $this->mAttribs['rc_log_type'] );
+ // Don't use SpecialPage::getTitleFor, backwards compatibility with
+ // IRC API which expects "Log".
+ $titleObj = Title::newFromText( 'Log/' . $this->mAttribs['rc_log_type'], NS_SPECIAL );
} else {
$titleObj =& $this->getTitle();
}
<?php
/**
- * XHTML sanitizer for MediaWiki
+ * XHTML sanitizer for %MediaWiki.
*
* Copyright © 2002-2005 Brion Vibber <brion@pobox.com> et al
* http://www.mediawiki.org/
<?php
+/**
+ * Expansion of the PHP execution time limit feature for a function call.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Class to expand PHP execution time for a function call.
<?php
/**
* Dynamically change configuration variables based on the test suite name and a cookie value.
+ *
* For details on how to configure a wiki for a Selenium test, see:
* http://www.mediawiki.org/wiki/SeleniumFramework#Test_Wiki_configuration
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
*/
+
if ( !defined( 'MEDIAWIKI' ) ) {
die( 1 );
}
<?php
/**
- * Include most things that's need to customize the site
+ * Include most things that's need to customize the site.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
<?php
+/**
+ * Configuration holder, particularly for multi-wiki sites.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
/**
* This is a class used to hold configuration settings, particularly for multi-wiki sites.
*/
<?php
+/**
+ * Accessors and mutators for the site-wide statistics.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Static accessor class for site_stats and related things
protected $views = 0;
protected $edits = 0;
protected $pages = 0;
- protected $goodPages = 0;
+ protected $articles = 0;
protected $users = 0;
protected $images = 0;
- // @TODO: deprecate this
+ // @TODO: deprecate this constructor
function __construct( $views, $edits, $good, $pages = 0, $users = 0 ) {
$this->views = $views;
$this->edits = $edits;
- $this->goodPages = $good;
+ $this->articles = $good;
$this->pages = $pages;
$this->users = $users;
}
public static function factory( array $deltas ) {
$update = new self( 0, 0, 0 );
- $fields = array( 'views', 'edits', 'pages', 'goodPages', 'users', 'images' );
+ $fields = array( 'views', 'edits', 'pages', 'articles', 'users', 'images' );
foreach ( $fields as $field ) {
if ( isset( $deltas[$field] ) && $deltas[$field] ) {
$update->$field = $deltas[$field];
return $update;
}
- /**
- * @param $sql
- * @param $field
- * @param $delta
- */
- function appendUpdate( &$sql, $field, $delta ) {
- if ( $delta ) {
- if ( $sql ) {
- $sql .= ',';
- }
- if ( $delta < 0 ) {
- $sql .= "$field=$field-1";
- } else {
- $sql .= "$field=$field+1";
- }
- }
- }
-
public function doUpdate() {
- $dbw = wfGetDB( DB_MASTER );
+ global $wgSiteStatsAsyncFactor;
- $updates = '';
+ $rate = $wgSiteStatsAsyncFactor; // convenience
+ // If set to do so, only do actual DB updates 1 every $rate times.
+ // The other times, just update "pending delta" values in memcached.
+ if ( $rate && ( $rate < 0 || mt_rand( 0, $rate - 1 ) != 0 ) ) {
+ $this->doUpdatePendingDeltas();
+ } else {
+ $dbw = wfGetDB( DB_MASTER );
+
+ $lockKey = wfMemcKey( 'site_stats' ); // prepend wiki ID
+ if ( $rate ) {
+ // Lock the table so we don't have double DB/memcached updates
+ if ( !$dbw->lockIsFree( $lockKey, __METHOD__ )
+ || !$dbw->lock( $lockKey, __METHOD__, 1 ) // 1 sec timeout
+ ) {
+ $this->doUpdatePendingDeltas();
+ return;
+ }
+ $pd = $this->getPendingDeltas();
+ // Piggy-back the async deltas onto those of this stats update....
+ $this->views += ( $pd['ss_total_views']['+'] - $pd['ss_total_views']['-'] );
+ $this->edits += ( $pd['ss_total_edits']['+'] - $pd['ss_total_edits']['-'] );
+ $this->articles += ( $pd['ss_good_articles']['+'] - $pd['ss_good_articles']['-'] );
+ $this->pages += ( $pd['ss_total_pages']['+'] - $pd['ss_total_pages']['-'] );
+ $this->users += ( $pd['ss_users']['+'] - $pd['ss_users']['-'] );
+ $this->images += ( $pd['ss_images']['+'] - $pd['ss_images']['-'] );
+ }
- $this->appendUpdate( $updates, 'ss_total_views', $this->views );
- $this->appendUpdate( $updates, 'ss_total_edits', $this->edits );
- $this->appendUpdate( $updates, 'ss_good_articles', $this->goodPages );
- $this->appendUpdate( $updates, 'ss_total_pages', $this->pages );
- $this->appendUpdate( $updates, 'ss_users', $this->users );
- $this->appendUpdate( $updates, 'ss_images', $this->images );
+ // Need a separate transaction because this a global lock
+ $dbw->begin( __METHOD__ );
- if ( $updates ) {
- $site_stats = $dbw->tableName( 'site_stats' );
- $sql = "UPDATE $site_stats SET $updates";
+ // Build up an SQL query of deltas and apply them...
+ $updates = '';
+ $this->appendUpdate( $updates, 'ss_total_views', $this->views );
+ $this->appendUpdate( $updates, 'ss_total_edits', $this->edits );
+ $this->appendUpdate( $updates, 'ss_good_articles', $this->articles );
+ $this->appendUpdate( $updates, 'ss_total_pages', $this->pages );
+ $this->appendUpdate( $updates, 'ss_users', $this->users );
+ $this->appendUpdate( $updates, 'ss_images', $this->images );
+ if ( $updates != '' ) {
+ $dbw->update( 'site_stats', array( $updates ), array(), __METHOD__ );
+ }
+
+ if ( $rate ) {
+ // Decrement the async deltas now that we applied them
+ $this->removePendingDeltas( $pd );
+ // Commit the updates and unlock the table
+ $dbw->unlock( $lockKey, __METHOD__ );
+ }
- # Need a separate transaction because this a global lock
- $dbw->begin( __METHOD__ );
- $dbw->query( $sql, __METHOD__ );
$dbw->commit( __METHOD__ );
}
}
);
return $activeUsers;
}
+
+ protected function doUpdatePendingDeltas() {
+ $this->adjustPending( 'ss_total_views', $this->views );
+ $this->adjustPending( 'ss_total_edits', $this->edits );
+ $this->adjustPending( 'ss_good_articles', $this->articles );
+ $this->adjustPending( 'ss_total_pages', $this->pages );
+ $this->adjustPending( 'ss_users', $this->users );
+ $this->adjustPending( 'ss_images', $this->images );
+ }
+
+ /**
+ * @param $sql string
+ * @param $field string
+ * @param $delta integer
+ */
+ protected function appendUpdate( &$sql, $field, $delta ) {
+ if ( $delta ) {
+ if ( $sql ) {
+ $sql .= ',';
+ }
+ if ( $delta < 0 ) {
+ $sql .= "$field=$field-" . abs( $delta );
+ } else {
+ $sql .= "$field=$field+" . abs( $delta );
+ }
+ }
+ }
+
+ /**
+ * @param $type string
+ * @param $sign string ('+' or '-')
+ * @return void
+ */
+ private function getTypeCacheKey( $type, $sign ) {
+ return wfMemcKey( 'sitestatsupdate', 'pendingdelta', $type, $sign );
+ }
+
+ /**
+ * Adjust the pending deltas for a stat type.
+ * Each stat type has two pending counters, one for increments and decrements
+ * @param $type string
+ * @param $delta integer Delta (positive or negative)
+ * @return void
+ */
+ protected function adjustPending( $type, $delta ) {
+ global $wgMemc;
+
+ if ( $delta < 0 ) { // decrement
+ $key = $this->getTypeCacheKey( $type, '-' );
+ } else { // increment
+ $key = $this->getTypeCacheKey( $type, '+' );
+ }
+
+ $magnitude = abs( $delta );
+ if ( !$wgMemc->incr( $key, $magnitude ) ) { // not there?
+ if ( !$wgMemc->add( $key, $magnitude ) ) { // race?
+ $wgMemc->incr( $key, $magnitude );
+ }
+ }
+ }
+
+ /**
+ * Get pending delta counters for each stat type
+ * @return Array Positive and negative deltas for each type
+ * @return void
+ */
+ protected function getPendingDeltas() {
+ global $wgMemc;
+
+ $pending = array();
+ foreach ( array( 'ss_total_views', 'ss_total_edits',
+ 'ss_good_articles', 'ss_total_pages', 'ss_users', 'ss_images' ) as $type )
+ {
+ // Get pending increments and pending decrements
+ $pending[$type]['+'] = (int)$wgMemc->get( $this->getTypeCacheKey( $type, '+' ) );
+ $pending[$type]['-'] = (int)$wgMemc->get( $this->getTypeCacheKey( $type, '-' ) );
+ }
+
+ return $pending;
+ }
+
+ /**
+ * Reduce pending delta counters after updates have been applied
+ * @param Array Result of getPendingDeltas(), used for DB update
+ * @return void
+ */
+ protected function removePendingDeltas( array $pd ) {
+ global $wgMemc;
+
+ foreach ( $pd as $type => $deltas ) {
+ foreach ( $deltas as $sign => $magnitude ) {
+ // Lower the pending counter now that we applied these changes
+ $wgMemc->decr( $this->getTypeCacheKey( $type, $sign ), $magnitude );
+ }
+ }
+ }
}
/**
<?php
+/**
+ * Base class for all skins.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
/**
* @defgroup Skins Skins
*/
<?php
/**
- * Base class for template-based skins
+ * Base class for template-based skins.
*
* 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
<?php
/**
- * SpecialPage: handling special pages and lists thereof.
+ * Parent class for all special pages.
*
- * To add a special page in an extension, add to $wgSpecialPages either
- * an object instance or an array containing the name and constructor
- * parameters. The latter is preferred for performance reasons.
+ * 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.
*
- * The object instantiated must be either an instance of SpecialPage or a
- * sub-class thereof. It must have an execute() method, which sends the HTML
- * for the special page to $wgOut. The parent class has an execute() method
- * which distributes the call to the historical global functions. Additionally,
- * execute() also checks if the user has the necessary access privileges
- * and bails out if not.
+ * 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.
*
- * To add a core special page, use the similar static list in
- * SpecialPage::$mList. To remove a core static special page at runtime, use
- * a SpecialPage_initList hook.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
* @ingroup SpecialPage
- * @defgroup SpecialPage SpecialPage
*/
/**
<?php
/**
- * SpecialPage: handling special pages and lists thereof.
+ * Factory for handling the special page list and generating SpecialPage objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup SpecialPage
+ * @defgroup SpecialPage SpecialPage
+ */
+
+/**
+ * Factory for handling the special page list and generating SpecialPage objects.
*
* To add a special page in an extension, add to $wgSpecialPages either
* an object instance or an array containing the name and constructor
* SpecialPage::$mList. To remove a core static special page at runtime, use
* a SpecialPage_initList hook.
*
- * @file
- * @ingroup SpecialPage
- * @defgroup SpecialPage SpecialPage
- */
-
-/**
- * Factory for handling the special page list and generating SpecialPage objects
* @ingroup SpecialPage
* @since 1.17
*/
<?php
+/**
+ * Squid and Varnish cache purging.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
/**
* An HTTP 1.0 client built for the purposes of purging Squid and Varnish.
* Uses asynchronous I/O, allowing purges to be done in a highly parallel
<?php
+/**
+ * Generic operation result.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Generic operation result class
<?php
/**
- * Functions related to the output of file content
+ * Functions related to the output of file content.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
*
* @file
*/
+
+/**
+ * Functions related to the output of file content
+ */
class StreamFile {
const READY_STREAM = 1;
const NOT_MODIFIED = 2;
<?php
+/**
+ * Methods to play with strings.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
/**
* A collection of static methods to play with strings.
*/
<?php
+/**
+ * Delayed loading of global objects.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
/**
* Class to implement stub globals, which are globals that delay loading the
return (int)$this->mLatest;
}
+ /**
+ * Get the Revision object of the oldest revision
+ * @return Revision|null
+ */
+ public function getOldestRevision() {
+ wfProfileIn( __METHOD__ );
+
+ // Try using the slave database first, then try the master
+ $continue = 2;
+ $db = wfGetDB( DB_SLAVE );
+ $revSelectFields = Revision::selectFields();
+
+ while ( $continue ) {
+ $row = $db->selectRow(
+ array( 'page', 'revision' ),
+ $revSelectFields,
+ array(
+ 'page_namespace' => $this->mTitle->getNamespace(),
+ 'page_title' => $this->mTitle->getDBkey(),
+ 'rev_page = page_id'
+ ),
+ __METHOD__,
+ array(
+ 'ORDER BY' => 'rev_timestamp ASC'
+ )
+ );
+
+ if ( $row ) {
+ $continue = 0;
+ } else {
+ $db = wfGetDB( DB_MASTER );
+ $continue--;
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ if ( $row ) {
+ return Revision::newFromRow( $row );
+ } else {
+ return null;
+ }
+ }
+
/**
* Loads everything except the text
* This isn't necessary for all uses, so it's only done if needed.
}
}
+ /**
+ * Get the User object of the user who created the page
+ * @param $audience Integer: one of:
+ * Revision::FOR_PUBLIC to be displayed to all users
+ * Revision::FOR_THIS_USER to be displayed to $wgUser
+ * Revision::RAW get the text regardless of permissions
+ * @return User|null
+ */
+ public function getCreator( $audience = Revision::FOR_PUBLIC ) {
+ $revision = $this->getOldestRevision();
+ if ( $revision ) {
+ $userName = $revision->getUserText( $audience );
+ return User::newFromName( $userName, false );
+ } else {
+ return null;
+ }
+ }
+
/**
* @param $audience Integer: one of:
* Revision::FOR_PUBLIC to be displayed to all users
$res['expiry'] = $block->mExpiry == wfGetDB( DB_SLAVE )->getInfinity()
? 'infinite'
: wfTimestamp( TS_ISO_8601, $block->mExpiry );
+ $res['id'] = $block->getId();
} else {
# should be unreachable
$res['expiry'] = '';
+ $res['id'] = '';
}
$res['reason'] = $params['reason'];
'name' => $lastUser,
);
if ( $fld_blockinfo && !is_null( $row->ipb_by_text ) ) {
+ $lastUserData['blockid'] = $row->ipb_id;
$lastUserData['blockedby'] = $row->ipb_by_text;
+ $lastUserData['blockedbyid'] = $row->ipb_by;
$lastUserData['blockreason'] = $row->ipb_reason;
$lastUserData['blockexpiry'] = $row->ipb_expiry;
}
$this->addFields( 'ipb_deleted' );
if ( $showBlockInfo ) {
- $this->addFields( array( 'ipb_reason', 'ipb_by_text', 'ipb_expiry' ) );
+ $this->addFields( array( 'ipb_id', 'ipb_by', 'ipb_by_text', 'ipb_reason', 'ipb_expiry' ) );
}
// Don't show hidden names
'endsortkey' => "Sortkey to end listing at. Must be given in binary format. Can only be used with {$p}sort=sortkey",
'startsortkeyprefix' => "Sortkey prefix to start listing from. Can only be used with {$p}sort=sortkey. Overrides {$p}startsortkey",
'endsortkeyprefix' => "Sortkey prefix to end listing BEFORE (not at, if this value occurs it will not be included!). Can only be used with {$p}sort=sortkey. Overrides {$p}endsortkey",
- 'continue' => 'For large categories, give the value retured from previous query',
+ 'continue' => 'For large categories, give the value returned from previous query',
'limit' => 'The maximum number of pages to return.',
);
if ( isset( $this->prop['blockinfo'] ) ) {
if ( $user->isBlocked() ) {
- $vals['blockedby'] = User::whoIs( $user->blockedBy() );
+ $block = $user->getBlock();
+ $vals['blockid'] = $block->getId();
+ $vals['blockedby'] = $block->getByName();
+ $vals['blockedbyid'] = $block->getBy();
$vals['blockreason'] = $user->blockedFor();
}
}
$data[$name]['hidden'] = '';
}
if ( isset( $this->prop['blockinfo'] ) && !is_null( $row->ipb_by_text ) ) {
+ $data[$name]['blockid'] = $row->ipb_id;
$data[$name]['blockedby'] = $row->ipb_by_text;
+ $data[$name]['blockedbyid'] = $row->ipb_by;
$data[$name]['blockreason'] = $row->ipb_reason;
$data[$name]['blockexpiry'] = $row->ipb_expiry;
}
}
$res['id'] = $block->getId();
- $res['user'] = $block->getType() == Block::TYPE_AUTO ? '' : $block->getTarget();
+ $target = $block->getType() == Block::TYPE_AUTO ? '' : $block->getTarget();
+ $res['user'] = $target;
+ $res['userid'] = $target instanceof User ? $target->getId() : 0;
$res['reason'] = $params['reason'];
$this->getResult()->addValue( null, $this->getModuleName(), $res );
}
$form = new UserrightsPage;
$r['user'] = $user->getName();
+ $r['userid'] = $user->getId();
list( $r['added'], $r['removed'] ) =
$form->doSaveUserGroups(
$user, (array)$params['add'],
return 'CONCAT(' . implode( ',', $stringList ) . ')';
}
+ /**
+ * Check to see if a named lock is available. This is non-blocking.
+ *
+ * @param $lockName String: name of lock to poll
+ * @param $method String: name of method calling us
+ * @return Boolean
+ * @since 1.20
+ */
+ public function lockIsFree( $lockName, $method ) {
+ return true;
+ }
+
/**
* Acquire a named lock
*
return parent::streamStatementEnd( $sql, $newLine );
}
+ /**
+ * Check to see if a named lock is available. This is non-blocking.
+ *
+ * @param $lockName String: name of lock to poll
+ * @param $method String: name of method calling us
+ * @return Boolean
+ * @since 1.20
+ */
+ public function lockIsFree( $lockName, $method ) {
+ $lockName = $this->addQuotes( $lockName );
+ $result = $this->query( "SELECT IS_FREE_LOCK($lockName) AS lockstatus", $method );
+ $row = $this->fetchObject( $result );
+ return ( $row->lockstatus == 1 );
+ }
+
/**
* @param $lockName string
* @param $method string
$lockName = $this->addQuotes( $lockName );
$result = $this->query( "SELECT RELEASE_LOCK($lockName) as lockstatus", $method );
$row = $this->fetchObject( $result );
- return $row->lockstatus;
+ return ( $row->lockstatus == 1 );
}
/**
global $wgUser;
$userName = $context->getUser();
- if ( !$userName ) {
+ if ( $userName === null ) {
return array();
}
protected function getPages( ResourceLoaderContext $context ) {
$username = $context->getUser();
- if ( !$username ) {
+ if ( $username === null ) {
return array();
}
$out->wrapWikiMsg( "<div class='mw-tags-intro'>\n$1\n</div>", 'tags-intro' );
// Write the headers
- $html = Xml::tags( 'tr', null, Xml::tags( 'th', null, wfMsgExt( 'tags-tag', 'parseinline' ) ) .
- Xml::tags( 'th', null, wfMsgExt( 'tags-display-header', 'parseinline' ) ) .
- Xml::tags( 'th', null, wfMsgExt( 'tags-description-header', 'parseinline' ) ) .
- Xml::tags( 'th', null, wfMsgExt( 'tags-hitcount-header', 'parseinline' ) )
+ $html = Xml::tags( 'tr', null, Xml::tags( 'th', null, $this->msg( 'tags-tag' )->parse() ) .
+ Xml::tags( 'th', null, $this->msg( 'tags-display-header' )->parse() ) .
+ Xml::tags( 'th', null, $this->msg( 'tags-description-header' )->parse() ) .
+ Xml::tags( 'th', null, $this->msg( 'tags-hitcount-header' )->parse() )
);
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( 'change_tag', array( 'ct_tag', 'count(*) AS hitcount' ),
$disp = ChangeTags::tagDescription( $tag );
$disp .= ' ';
- $editLink = Linker::link( Title::makeTitle( NS_MEDIAWIKI, "Tag-$tag" ), wfMsgHtml( 'tags-edit' ) );
+ $editLink = Linker::link( Title::makeTitle( NS_MEDIAWIKI, "Tag-$tag" ), $this->msg( 'tags-edit' )->escaped() );
$disp .= $this->msg( 'parentheses' )->rawParams( $editLink )->escaped();
$newRow .= Xml::tags( 'td', null, $disp );
- $msg = wfMessage( "tag-$tag-description" );
+ $msg = $this->msg( "tag-$tag-description" );
$desc = !$msg->exists() ? '' : $msg->parse();
$desc .= ' ';
- $editDescLink = Linker::link( Title::makeTitle( NS_MEDIAWIKI, "Tag-$tag-description" ), wfMsgHtml( 'tags-edit' ) );
+ $editDescLink = Linker::link( Title::makeTitle( NS_MEDIAWIKI, "Tag-$tag-description" ), $this->msg( 'tags-edit' )->escaped() );
$desc .= $this->msg( 'parentheses' )->rawParams( $editDescLink )->escaped();
$newRow .= Xml::tags( 'td', null, $desc );
- $hitcount = wfMsgExt( 'tags-hitcount', array( 'parsemag' ), $this->getLanguage()->formatNum( $hitcount ) );
+ $hitcount = $this->msg( 'tags-hitcount' )->numParams( $hitcount )->escaped();
$hitcount = Linker::link( SpecialPage::getTitleFor( 'Recentchanges' ), $hitcount, array(), array( 'tagfilter' => $tag ) );
$newRow .= Xml::tags( 'td', null, $hitcount );
'allpagesbadtitle' => 'العنوان المقترح للصفحة غير مقبول أو يضم لغات أخرى أو سابقة إنترويكي.
يمكن أن يتضمن حروفا لا يمكن استعمالها للعناوين.',
'allpages-bad-ns' => '{{SITENAME}} لا يوجد بها نطاق "$1".',
+'allpages-hide-redirects' => 'أخفِ التحويلات',
# Special:Categories
'categories' => 'تصنيفات',
'version-software' => 'البرنامج المثبت',
'version-software-product' => 'المنتج',
'version-software-version' => 'النسخة',
+'version-entrypoints-header-url' => 'المسار',
# Special:FilePath
'filepath' => 'مسار ملف',
'api-error-uploaddisabled' => 'تم تعطيل تحميل على هذا الويكي.',
'api-error-verification-error' => 'هذا الملف قد يكون معطوباً أو يحتوي على ملحق غير صحيح.',
+# Durations
+'duration-seconds' => '{{PLURAL:$1|أقل من ثانية|ثانية واحدة|ثانيتان|$1 ثوانٍ|$1 ثانية}}',
+'duration-minutes' => '{{PLURAL:$1|أقل من دقيقة|دقيقة واحدة|دقيقتان|$1 دقائق|$1 دقيقة}}',
+'duration-hours' => '({{PLURAL:$1||ساعة واحد|ساعتان|$1 ساعات|$1 ساعة}})',
+'duration-days' => '{{PLURAL:$1||يوم واحد|يومان|$1 أيام|$1 يومًا|$1 يوم}}',
+'duration-weeks' => '{{PLURAL:$1||أسبوع واحد|أسبوعان|$1 أسابيع|$1 أسبوعًا|$1 أسبوع}}',
+'duration-years' => '{{PLURAL: $1||سنة واحدة|سنتان|$1 سنين|$1 سنة}}',
+'duration-decades' => '{{PLURAL: $1||عقد واحد|عقدان|$1 عقود|$1 عقدًا|$1 عقد}}',
+'duration-centuries' => '{{PLURAL: $1||قرن واحد|قرنان|$1 قرون|$1 قرنًا|$1 قرن}}',
+'duration-millennia' => '{{PLURAL: $1||ألفية واحدة|ألفيتان|$1 ألفيات|$1 ألفية}}',
+
);
'filereadonlyerror' => "Nelze změnit soubor „$1“, protože úložiště souborů „$2“ je momentálně pouze pro čtení.
Správce serveru, který úložiště zamkl, poskytl toto zdůvodnění: „''$3''“.",
+'invalidtitle-knownnamespace' => 'Neplatný název se jmenným prostorem „$2“ a textem „$3“',
+'invalidtitle-unknownnamespace' => 'Neplatný název s neznámým číslem jmenného prostoru $1 a textem „$2“',
# Virus scanner
'virus-badscanner' => "Špatná konfigurace: neznámý antivirový program: ''$1''",
'node-count-exceeded-warning' => 'Stránka překročila počet uzlů',
'expansion-depth-exceeded-category' => 'Stránky překračující hloubku expanze',
'expansion-depth-exceeded-warning' => 'Stránka překročila hloubku expanze',
+'parser-unstrip-loop-warning' => 'Detekováno zacyklení unstrip',
+'parser-unstrip-recursion-limit' => 'Překročen limit rekurze unstrip ($1)',
# "Undo" feature
'undo-success' => 'Editace může být zrušena. Zkontrolujte a pak potvrďte změny zobrazené níže.',
'http-curl-error' => 'Chyba při čtení z URL: $1',
'http-host-unreachable' => 'Nepodařilo se kontaktovat URL',
'http-bad-status' => 'Při provádění HTTP požadavku nastal problém: $1 $2',
+'http-truncated-body' => 'Přijaté tělo požadavku bylo neúplné.',
# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
'upload-curl-error6' => 'Z URL nelze číst',
'node-count-exceeded-warning' => 'Die Seite hat die Knotenpunktanzahl überschritten.',
'expansion-depth-exceeded-category' => 'Seiten, die die Expansionstiefe überschritten haben',
'expansion-depth-exceeded-warning' => 'Die Seite hat die Expansionstiefe überschritten.',
+'parser-unstrip-loop-warning' => 'Zirkelbezug festgestellt',
+'parser-unstrip-recursion-limit' => 'Rekursionsgrenze beim Auflösen überschritten ($1)',
# "Undo" feature
'undo-success' => 'Die Bearbeitung kann rückgängig gemacht werden.
'filereadonlyerror' => 'Njejo móžno dataju "$1" změniś, dokulaž datajowy repozitorium "$2" jo jano cytajobny.
Administrator, kenž jo jen zastajił, jo toś tu pśicynu pódał: "$3".',
+'invalidtitle-knownnamespace' => 'Njepłaśiwy titel z mjenjowym rumom "$2" a tekstom "$3"',
+'invalidtitle-unknownnamespace' => 'Njepłaśiwy titel z njeznatym mjenjowym rumom $1 a tekstom "$2"',
# Virus scanner
'virus-badscanner' => "Špatna konfiguracija: njeznaty wirusowy scanner: ''$1''",
'http-curl-error' => 'Zmólka pśi wótwółowanju URL: $1',
'http-host-unreachable' => 'URL njejo był pśistupny.',
'http-bad-status' => 'Wob cas HTTP-napšašowanje jo problem był: $1 $2',
+'http-truncated-body' => 'Wopśimjeśe napšašowanja jo se jano pó źělach pśiwzeło.',
# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
'upload-curl-error6' => 'URL njejo pśistupna.',
'february-gen' => 'فوریهٔ',
'march-gen' => 'مارس',
'april-gen' => 'آوریل',
-'may-gen' => 'مهٔ',
+'may-gen' => 'مه',
'june-gen' => 'ژوئن',
'july-gen' => 'ژوئیهٔ',
'august-gen' => 'اوت',
'filereadonlyerror' => 'Impossible de modifier le fichier « $1 » parce que le répertoire de fichiers « $2 » est en lecture seule.
L’administrateur qui l’a verrouillé a fourni ce motif: « $3 ».',
-'invalidtitle-knownnamespace' => 'Titre invalide avec l\'espace de noms "$2" et le libellé "$3"',
-'invalidtitle-unknownnamespace' => 'Titre invalide avec un numéro d\'espace de nommage $1 inconnu et le libellé "$2"',
+'invalidtitle-knownnamespace' => 'Titre invalide avec l’espace de noms « $2 » et l’intitulé « $3 »',
+'invalidtitle-unknownnamespace' => 'Titre invalide avec le numéro d’espace de noms $1 et l’intitulé « $2 » inconnus',
# Virus scanner
'virus-badscanner' => "Mauvaise configuration : scanneur de virus inconnu : ''$1''",
'node-count-exceeded-warning' => 'Page dépassant le nombre de nœuds',
'expansion-depth-exceeded-category' => "Pages où la profondeur d'expansion est dépassée",
'expansion-depth-exceeded-warning' => "Page dépassant la profondeur d'expansion",
+'parser-unstrip-loop-warning' => 'Boucle non démontable détectée',
+'parser-unstrip-recursion-limit' => 'Limite de récursion non démontable dépassée ($1)',
# "Undo" feature
'undo-success' => 'Cette modification va être défaite. Veuillez vérifier les modifications ci-dessous, puis publier si c’est bien ce que vous voulez faire.',
'filereadonlyerror' => 'Non se puido modificar o ficheiro "$1" porque o repositorio "$2" está en modo de só lectura.
O administrador que bloqueou o repositorio achegou este motivo: "$3".',
+'invalidtitle-knownnamespace' => 'Título inválido co espazo de nomes "$2" e o texto "$3"',
+'invalidtitle-unknownnamespace' => 'Título inválido cun número de espazo de nomes, $1, descoñecido e o texto "$2"',
# Virus scanner
'virus-badscanner' => "Configuración errónea: escáner de virus descoñecido: ''$1''",
'http-curl-error' => 'Ocorreu un erro ao acceder ao URL: $1',
'http-host-unreachable' => 'Non se puido acceder ao URL.',
'http-bad-status' => 'Houbo un problema durante a solicitude HTTP: $1 $2',
+'http-truncated-body' => 'O corpo de solicitude recibiuse parcialmente.',
# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
'upload-curl-error6' => 'Non se logrou acceder a ese URL',
'vector-view-edit' => 'ફેરફાર કરો',
'vector-view-history' => 'ઇતિહાસ જુઓ',
'vector-view-view' => 'વાંચો',
-'vector-view-viewsource' => 'સà«\8dતà«\8dરà«\8bત àª\9cà«\81àª\93',
+'vector-view-viewsource' => 'સ્રોત જુઓ',
'actions' => 'ક્રિયાઓ',
'namespaces' => 'નામાવકાશો',
'variants' => 'ભિન્ન રૂપો',
Function: $1<br />
Query: $2',
'viewsource' => 'સ્રોત જુઓ',
-'viewsource-title' => '$1 માàª\9fà«\87 સà«\8dતà«\8dરà«\8bત àª\9cà«\81વàª\91',
+'viewsource-title' => '$1 માàª\9fà«\87 સà«\8dરà«\8bત àª\9cà«\81àª\93',
'actionthrottled' => 'અકાળે અટાકાવી દીધેલી ક્રિયા',
'actionthrottledtext' => 'સ્પામ નિયંત્રણ તકેદારી રૂપે આ ક્રિયા અમુક મર્યાદામાં જ કરી શકો છો, અને તમે તે મર્યાદા વટાવી દીધી છે. કૃપા કરી થોડાક સમય પછી ફરી પ્રયત્ન કરો.',
'protectedpagetext' => 'ફેરફારો થતાં રોકવા માટે આ પાનું સુરક્ષિત કરવામાં આવ્યું છે.',
# History merging
'mergehistory' => 'પાનાનાં ઇતિહાસોનું વિલીનીકરણ',
-'mergehistory-header' => 'àª\86 પાનà«\81àª\82 તમનà«\87 સà«\8dતà«\8dરà«\8bત પાનાનà«\8b àª\88તિહાસ નવા પાનામાàª\82 વિલિન àª\95રવા માàª\82 મદદ àª\95રà«\87 àª\9bà«\87.
+'mergehistory-header' => 'આ પાનું તમને સ્રોત પાનાનો ઈતિહાસ નવા પાનામાં વિલિન કરવા માં મદદ કરે છે.
એ વાતનું ધ્યાન રાખશો કે ઇતિહાસ પાનાની સળંગતા જળવાઇ રહે.',
'mergehistory-box' => 'બે પાનાના ફેરફાર વિલિન કરો',
-'mergehistory-from' => 'સà«\8dતà«\8dરà«\8bત પાનà«\81àª\82',
+'mergehistory-from' => 'સ્રોત પાનું',
'mergehistory-into' => 'લક્ષ્ય પાનું',
'mergehistory-list' => 'વિલિનીકરણશીલ ફેરફારનો ઈતિહાસ',
'mergehistory-merge' => '[[:$1]] દ્વારા કરેલ ફેરફારો [[:$2]] માંવિલિન કરી શકાયા.
'mergehistory-empty' => 'પુનરાવર્તન સાચવી ન શકાયા',
'mergehistory-success' => '[[:$1]] ના $3 {{PLURAL:$3|ફેરફાર |ફેરફારો}} ને સફળતા પૂર્વક [[:$2]] માં વિલિનાકરાયા.',
'mergehistory-fail' => 'ઇતિહાસ પાના વિલિન ન કરી શકાયા, પાના અને સમય સંબંધી વિકલ્પો ચકાસો.',
-'mergehistory-no-source' => 'સà«\8dતà«\8dરà«\8bત પાનà«\81àª\82 $1 àª\89પલબà«\8dધ નથà«\80.',
+'mergehistory-no-source' => 'સ્રોત પાનું $1 ઉપલબ્ધ નથી.',
'mergehistory-no-destination' => 'લક્ષ્ય પાનું $1 અસ્તિત્વમાં નથી',
-'mergehistory-invalid-source' => 'સà«\8dતà«\8dરà«\8bત પાનà«\81àª\82 વà«\88ધ શà«\80રà«\8dષàª\95 હà«\8bવà«\81àª\82 àª\9c àª\9cà«\8bàª\88àª\8f',
+'mergehistory-invalid-source' => 'સà«\8dરà«\8bત પાનà«\81àª\82 વà«\88ધ શà«\80રà«\8dષàª\95 હà«\8bવà«\81àª\82 àª\9c àª\9cà«\8bàª\88àª\8f.',
'mergehistory-invalid-destination' => 'લક્ષ્ય પાનું એક વૈધ શીર્ષક હોવું જોઇએ',
'mergehistory-autocomment' => ' [[:$1]] ને [[:$2]] માં વિલિન કર્યું',
'mergehistory-comment' => '[[:$1]] ને [[:$2]]: $3 માં વિલિન કર્યું',
-'mergehistory-same-destination' => 'સà«\8dતà«\8dરà«\8bત àª\85નà«\87 લàª\95à«\8dષà«\8dય પાના àª\8fàª\95ાસમાન ના હોઈ શકે',
+'mergehistory-same-destination' => 'સà«\8dરà«\8bત àª\85નà«\87 લàª\95à«\8dષà«\8dય પાના àª\8fàª\95 સમાન ના હોઈ શકે',
'mergehistory-reason' => 'કારણ:',
# Merge log
'right-move-subpages' => 'પાનાઓને તેમના ઉપ પાના સાથે ખસેડો.',
'right-move-rootuserpages' => 'મૂળ સભ્ય પાના હટાવો',
'right-movefile' => 'ફાઈલો હટાવો',
-'right-suppressredirect' => 'પાના હàª\9fાવતà«\80 વàª\96તના સમયà«\87 સà«\8dતà«\8dરà«\8bત પાનામાàª\82થà«\80 દિશા નિરà«\8dદà«\87શ વરà«\8dàª\9cà«\80ત',
+'right-suppressredirect' => 'પાના હટાવતી વખતના સમયે સ્રોત પાનામાંથી દિશા નિર્દેશ વર્જીત',
'right-upload' => 'ફાઇલ ચડાવો',
'right-reupload' => 'વિહરમાન ફાઇલ પર પુનર્લેખન કરો',
'right-reupload-own' => 'સભ્ય દ્વારા જાતે ચઢાવેલી તાઇલ પર પુનર્લેખન કરો',
'fileuploadsummary' => 'સારાંશ:',
'filereuploadsummary' => 'ફાઈલ ફેરફારો',
'filestatus' => 'પ્રકાશનાધિકાર સ્થિતિ',
-'filesource' => 'સà«\8dતà«\8dરà«\8bત:',
+'filesource' => 'સ્રોત:',
'uploadedfiles' => 'ફાઇલ ચડાવો',
'ignorewarning' => 'ચેતવણીને અવગણી ને પણ ફાઇલ સાચવો',
'ignorewarnings' => 'કોઇ પણ ચેતવણી અવગણો',
વિવરણ : $1',
'uploadjava' => 'આ ફાઇલ એ ZIP ફાઈલ છે જે Java .class ધરાવે છે.
Java ફાઇલ ચડાવવાની પરવાનગી નથી, કેમકે તેઓ સુરક્ષા તપાસને અવગણી નાખવાની ક્ષમતા ધરાવે છે.',
-'upload-source' => 'સà«\8dતà«\8dરà«\8bત ફાàª\87લ',
-'sourcefilename' => 'સà«\8dતà«\8dરà«\8bત ફાàª\87લ નામ',
-'sourceurl' => 'સà«\8dતà«\8dરà«\8bત URL:',
+'upload-source' => 'સ્રોત ફાઇલ',
+'sourcefilename' => 'સà«\8dરà«\8bત ફાàª\87લ નામ:',
+'sourceurl' => 'સ્રોત URL:',
'destfilename' => 'લક્ષ્ય ફાઇલ નામ',
'upload-maxfilesize' => 'મહત્તમ ફાઈલ કદ : $1',
'upload-description' => 'ફાઇલ માહિતી',
'querypage-disabled' => 'કાર્યક્ષમતાના કારણે આ ખાસ પાનું નિષ્ક્રિ કરાયું છે.',
# Book sources
-'booksources' => 'પà«\81સà«\8dતàª\95 સà«\8dતà«\8dરà«\8bત',
-'booksources-search-legend' => 'પà«\81સà«\8dતàª\95 સà«\8dતà«\8dરà«\8bત શà«\8bધà«\8b',
+'booksources' => 'પુસ્તક સ્રોત',
+'booksources-search-legend' => 'પુસ્તક સ્રોત શોધો',
'booksources-isbn' => 'આઇએસબીએન:',
'booksources-go' => 'જાઓ',
'booksources-text' => 'નીચે દર્શાવેલ યાદી એ કડીઓ બતાવે છે જેઓ નવા અને જૂના પુસ્તકો વેચે છે , અને તમે માંગેલ વસ્તુ સંબંધિ વધુ મહિતી પણ ધરાવી શકે છે.',
-'booksources-invalid-isbn' => 'આપેલ ISBN વૈધ નથી લાગતો. મૂળ સ્ત્રોત થે ચકાસીને ભૂલ શોધી ખરી માહિતી આપો.',
+'booksources-invalid-isbn' => 'આપેલ ISBN વૈધ નથી લાગતો; મૂળ સ્રોતને ચકાસી, ભૂલ શોધી, ખરી માહિતી આપો.',
# Special:Log
'specialloguserlabel' => 'અભિનય:',
શું તમે આને હટાવીને સ્થળાંતર કરવાનો માર્ગ મોકળો કરવા માંગો છો?',
'delete_and_move_confirm' => 'હા, આ પાનું હટાવો',
'delete_and_move_reason' => 'હટાવવાનું કામ આગળ વધાવવા ભૂંસી દેવાયુ "[[$1]]"',
-'selfmove' => 'સà«\8dતà«\8dરà«\8bત નà«\87 લàª\95à«\8dષà«\8dય શà«\80રà«\8dષàª\95à«\8b સમાન àª\9bà«\87.
+'selfmove' => 'સà«\8dરà«\8bત નà«\87 લàª\95à«\8dષà«\8dય શà«\80રà«\8dષàª\95à«\8b સમાન àª\9bà«\87;
પાના ને તેવા જ નામ ધરાવતા પાના પર પુનઃ સ્થાપન નહીં કરી શકાય.',
'immobile-source-namespace' => '"$1" નામાસ્થળમાં પાના ન ખસેડી શાકાયા',
'immobile-target-namespace' => '"$1" નામાસ્થળમાં પાના ન ખસેડી શાકાયા',
'import-interwiki-text' => 'આયાત કરવાના વિકિ અને પાનાનું શીર્ષક પસંદ કરો.
ફેરફરની તારીખ અને લેખકો વિષે ની માહિતી સચવાશે.
આંતર વિકિ આયાત આદિ [[Special:Log/import|import log]] માં અંકિત થાય છે.',
-'import-interwiki-source' => 'સà«\8dતà«\8dરà«\8bત વિàª\95િ/પાનà«\81àª\82',
+'import-interwiki-source' => 'સà«\8dરà«\8bત વિàª\95િ/પાનà«\81àª\82:',
'import-interwiki-history' => 'આ પાના બધા ઐતિહાસીક ફેરફારોની નકલ કરો',
'import-interwiki-templates' => 'બધા ઢાંચા શામિલ કરો',
'import-interwiki-submit' => 'આયાત કરો',
'import-interwiki-namespace' => 'લક્ષ્ય નામ સ્થળ',
'import-upload-filename' => 'ફાઇલ નામ',
'import-comment' => 'ટિપ્પણી:',
-'importtext' => 'àª\95à«\83પયા [[Special:Export|export utility]] વાપરà«\80 વિàª\95િ સà«\8dતà«\8dરà«\8bત પરથà«\80 ફાàª\87લ નિàª\95ાસ àª\95રà«\8b.
-તà«\87નà«\87 તમારા સàª\82àª\97ણàª\95 પર સાચવો અને અહીં ચડાવો.',
+'importtext' => 'કૃપયા [[Special:Export|export utility]] વાપરી વિકિ સ્રોત પરથી ફાઇલ નિકાસ કરો.
+તà«\87નà«\87 તમારા àª\95à«\89મà«\8dપà«\8dયà«\81àª\9fર પર સાચવો અને અહીં ચડાવો.',
'importstart' => 'આયાત કામ જારી છે....',
'import-revision-count' => '$1 {{PLURAL:$1|પુનરાવર્તન|પુનરાવર્તનો}}',
'importnopages' => 'આયાત કરવા માટે કોઇ પાનું નથી!',
'imported-log-entries' => 'આયાતી $1 {{PLURAL:$1|log entry|log entries}}.',
'importfailed' => 'આયાત નિષ્ફળ: <nowiki>$1</nowiki>',
-'importunknownsource' => 'àª\85àª\9cà«\8dàª\9eાત àª\86યાતà«\80 સà«\8dતà«\8dરà«\8bત પà«\8dરàª\95ાર',
+'importunknownsource' => 'અજ્ઞાત આયાતી સ્રોત પ્રકાર',
'importcantopen' => 'આયાતી ફાઈલ નાખોલી શકાઈ',
'importbadinterwiki' => 'ખરાબ આંતરીકા વિકિ કડી',
'importnotext' => 'ખાલી કે શબ્દ વિહીન',
'importsuccess' => 'આયાત સંપૂર્ણ',
'importhistoryconflict' => 'એક બીજાથી વિસંગત ફેરફારો અસ્તિત્વ ધરાવે છે ( કદાક આ પાનું પહેલાં આયાત કરાયું હોય)',
-'importnosources' => 'àª\95à«\8bàª\87 પણ àª\86àª\82તર વિàª\95િ સà«\8dતà«\8dરà«\8bત àª\9cણાવાયા નથà«\80 àª\85નà«\87 સà«\80ધા àª\87તિહાસ ફાàª\87લ àª\9aડાવવા પર રà«\8bàª\95 લાàª\97à«\87લà«\80 àª\9bà«\87.',
+'importnosources' => 'કોઇ પણ આંતર વિકિ સ્રોત જણાવાયા નથી અને સીધા ઇતિહાસ ફાઇલ ચડાવવા પર રોક લાગેલી છે.',
'importnofile' => 'કોઇ પણ આયાતી ફાઇલ ન ચડાવી શકાઇ',
'importuploaderrorsize' => 'આયાતી ફાઇલ ચડાવવાનું અસફળ
મંજૂર કદ કરતા આ ફાઈલાનું કદ મોટું છે.',
'exif-maxaperturevalue' => 'મહત્તમ ભૂમિ છીદ્ર',
'exif-subjectdistance' => 'વસ્તુનું અંતર',
'exif-meteringmode' => 'મીટરીંગ ઢબ',
-'exif-lightsource' => 'પ્રકાશા સ્ત્રોત',
+'exif-lightsource' => 'પ્રકાશ સ્રોત',
'exif-flash' => 'જબકારો (ફ્લેશ)',
'exif-focallength' => 'કાંચનું કેન્દ્રીય લંબાઇ (ફોકલ લેંથ)',
'exif-subjectarea' => 'વિષ્યવસ્તુ ક્ષેત્ર',
'exif-subjectlocation' => 'વસ્તુનું સ્થાન',
'exif-exposureindex' => 'પ્રકાશાગમ અનુક્ર્મ',
'exif-sensingmethod' => 'સંવેદનાની રીત',
-'exif-filesource' => 'ફાàª\87લ સà«\8dતà«\8dરà«\8bત',
+'exif-filesource' => 'ફાઇલ સ્રોત',
'exif-scenetype' => 'દ્રશ્ય પ્રકાર',
'exif-customrendered' => 'સ્થાનીય ચિત્ર પ્રક્રિયા',
'exif-exposuremode' => 'પ્રકાશાગમ પ્રકાર',
'exif-objectname' => 'લઘુ શીર્ષક',
'exif-specialinstructions' => 'ખાસ સૂચનાઓ',
'exif-headline' => 'મથાળું',
-'exif-credit' => 'àª\8bણ સà«\8dવà«\80àª\95ાર/સà«\8dતà«\8dરà«\8bત',
-'exif-source' => 'સà«\8dતà«\8dરà«\8bત',
+'exif-credit' => 'ઋણ સ્વીકાર/સ્રોત',
+'exif-source' => 'સ્રોત',
'exif-editstatus' => 'ચિત્ર સંપાદનની સ્થિતી',
'exif-urgency' => 'તાત્કાલિકતા',
'exif-fixtureidentifier' => 'સાધન નામ',
'exif-lightsource-18' => 'પ્રમાણભૂત પ્રકાશ B',
'exif-lightsource-19' => 'પ્રમાણભૂત પ્રકાશ C',
'exif-lightsource-24' => 'ISO સ્ટુડીયો ટંગસ્ટન',
-'exif-lightsource-255' => 'પà«\8dરàª\95ાશના àª\85નà«\8dય સà«\8dત્રોત',
+'exif-lightsource-255' => 'àª\85નà«\8dય પà«\8dરàª\95ાશ સ્રોત',
# Flash modes
'exif-flash-fired-0' => 'પ્રકાશ ઝબકારો ન થયો',
'exif-dc-publisher' => 'પ્રકાશક',
'exif-dc-relation' => 'સંબધિત માધ્યમ',
'exif-dc-rights' => 'હક્કો',
-'exif-dc-source' => 'સà«\8dતà«\8dરà«\8bત માધà«\8dયમ',
+'exif-dc-source' => 'સ્રોત માધ્યમ',
'exif-dc-type' => 'માધ્યમનો પ્રકાર',
'exif-rating-rejected' => 'નામંજૂર',
'node-count-exceeded-warning' => 'Strona je ličbu sukow překročiła',
'expansion-depth-exceeded-category' => 'Strony, hdźež ekspansiska hłubokosć je překročena',
'expansion-depth-exceeded-warning' => 'Strona je ekspansisku hłubokosć překročił',
+'parser-unstrip-loop-warning' => 'Njeskónčna sekla namakana',
+'parser-unstrip-recursion-limit' => 'Rekursiska hranica překročena ($1)',
# "Undo" feature
'undo-success' => 'Wersija je so wuspěšnje wotstroniła. Prošu přepruwuj deleka w přirunanskim napohledźe, hač twoja změna bu přewzata a klikń potom na „Składować”, zo by změnu składował.',
'node-count-exceeded-warning' => 'Le numero de nodos in iste pagina excede le limite',
'expansion-depth-exceeded-category' => 'Paginas in que le profunditate de expansion excede le limite',
'expansion-depth-exceeded-warning' => 'Le profunditate de expansion in iste pagina excede le limite',
+'parser-unstrip-loop-warning' => 'Bucla de "unstrip" detegite',
+'parser-unstrip-recursion-limit' => 'Limite de recursion de "unstrip" excedite ($1)',
# "Undo" feature
'undo-success' => 'Le modification pote esser disfacite.
'updated' => '(Uppfært)',
'note' => "'''Athugið:'''",
'previewnote' => "'''Það sem sést hér er aðeins forskoðun og hefur ekki enn verið vistað!'''",
+'continue-editing' => 'Halda áfram að breyta',
'previewconflict' => 'Þessi forskoðun endurspeglar textann í efra breytingarsvæði eins og hann myndi líta út ef þú vistar.',
'session_fail_preview' => "'''Því miður! Gat ekki unnið úr breytingum þínum vegna týndra lotugagna.
Vinsamlegast reyndu aftur síðar. Ef það virkar ekki heldur skaltu reyna að skrá þig út og inn á ný.'''",
'mypage' => 'Жеке бетім',
'mytalk' => 'Талқылауым',
'anontalk' => 'IP талқылауы',
-'navigation' => 'Ð\9dавигаÑ\86иÑ\8f',
+'navigation' => 'Ð\91аÒ\93Ñ\8bÑ\82Ñ\82аÑ\83',
'and' => ' және',
# Cologne Blue skin
'userpage-userdoesnotexist-view' => '«$1» тергеу джазыу (аккаунт) джокъду.',
'blocked-notice-logextract' => 'Бу къошулуучу бусагъатда блокланыб турады.
Тюбюнде блокланыуланы журналындан ахыр джазыу бериледи:',
-'clearyourcache' => "'''Эслегиз:''' Бетде сакъланнгандан сора тюрлендириуле кёрюнюрча браузеригизни кэшин ариулатыгъыз:
-'''Mozilla / Firefox''': ''Ctrl+Shift+R'',
-'''IE:''' ''Ctrl+F5'',
-'''Safari''': ''Cmd+Shift+R'',
- '''Konqueror''': ''F5'',
-'''Opera''': ''Tools→Preferences'' меню бла.",
+'clearyourcache' => "'''Эслегиз.''' Бетде сакъланнгандан сора тюрлендириуле кёрюнюрча браузеригизни кэшин ариулатыргъа керек болургъа боллукъду.
+* '''Firefox / Safari''': ''Shift'' тиекни басыб тургъанлай инструментлени панелинде ''Джангырт'' тиекни басыгъыз, неда ''Ctrl-F5'' басыгъыз, неда ''Ctrl-R'' (Mac-да — ''⌘-R'')
+* '''Google Chrome:''' ''Ctrl-Shift-R'' басыгъыз (Mac-да — ''⌘-Shift-R'')
+* '''Internet Explorer:''' ''Ctrl'' тиекни басыб тургъанлай ''Джангырт'' тиекни басыгъыз, неда ''Ctrl-F5'' басыгъыз
+* '''Konqueror:''' ''Джангырт'' тиекни басыгъыз, неда ''F5'' тиекни
+* '''Opera:''' ''Инструментле → Джарашдырыула'' менюда кэшни ариулауну сайлагъыз",
'usercssyoucanpreview' => "'''Юретиу.''' «{{int:showpreview}}» тиекни басыгъыз, джангы CSS-файлны сакълатырыгъызны аллы бла тинтиб кёрюрча.",
'userjsyoucanpreview' => "'''Юретиу.''' «{{int:showpreview}}» тиекни басыгъыз, джангы JS-файлны сакълатырыгъызны аллы бла тинтиб кёрюрча.",
'usercsspreview' => "'''Эсде тутугъуз, бу къуру ал къарауду, CSS файлыгъыз алкъын сакъланмагъанды!'''",
'userjspreview' => "'''Эсде тутугъуз, бу къуру ал къарауду, javascript файлыгъыз алкъын сакъланмагъанды!'''",
+'sitecsspreview' => "'''Эслегиз, бу CSS-ни къуру ал къараууду.'''
+ '''Ол алкъын сакъланмагъанды!'''",
+'sitejspreview' => "'''Эслегиз, бу JavaScript-кодну къуру ал къараууду.'''
+ '''Ол алкъын сакъланмагъанды!'''",
'userinvalidcssjstitle' => "'''Эс бёлюгюз:''' «$1» атлы тема джокъду. Эсде тутугъуз, .css эм .js бетле атлары ажымсыз къуру гитче харифледен болургъа керекди, сёз ючюн: {{ns:user}}:Foo/vector.css, былай {{ns:user}}:Foo/Vector.css тюйюл!",
'updated' => '(Джангыртылды)',
'note' => "'''Белги:'''",
'edit-no-change' => 'Текстде тюрлениуле эсленмегени ючюн, сизни тюрлендириуюгюз къабыл этилмеди.',
'edit-already-exists' => 'Джангы бет къураргъа боллукъ тюлдю.
Алайсызда барды бу атлы бет.',
+'defaultmessagetext' => 'Тынгылау бла текст',
# Parser/template warnings
'expensive-parserfunction-warning' => "'''Эсгериу:''' Бу бетде асыры кёб къайнакълы функция барды.
'rev-deleted-user-contribs' => '[къошулуучуну аты неда IP-адреси кетерилгенди — тюрлендириу къошакъны бетинде кёргюзюлмейди]',
'rev-deleted-text-permission' => "Бетни бу версиясы '''кетерилгенди'''.
[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Кетериулени журналында] табыб къояргъа боллукъсуз.",
-'rev-deleted-text-unhide' => "Бу бетни версиясы '''кетерилгенди'''.
-[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Кетериулени журналында] чурумла ангылатылгъан болур.
-Ð\90дминиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80 болгÑ\8aанÑ\8bгÑ\8aÑ\8bз Ñ\8eÑ\87Ñ\8eн [$1 бу версияны кёрюрге боллукъсуз].",
-'rev-suppressed-text-unhide' => "Бетни бу версиясы '''джашырылгъанды'''.
-[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Джашырылыуланы журналында] чурумла берилген болурла.
-Ð\90дминиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80 болгÑ\8aанÑ\8bгÑ\8aÑ\8bз Ñ\8eÑ\87Ñ\8eн [$1 версияны кёрюрге боллукъсуз].",
-'rev-deleted-text-view' => "Ð\91еÑ\82ни бÑ\83 веÑ\80Ñ\81иÑ\8fÑ\81Ñ\8b '''кеÑ\82еÑ\80илгенди'''.
-Ð\90дминиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80 болгÑ\8aанÑ\8bз Ñ\8eÑ\87Ñ\8eн аннга кÑ\8aаÑ\80аÑ\80гÑ\8aа боллÑ\83кÑ\8aÑ\81Ñ\83з; Ð\90нгÑ\8bлаÑ\82Ñ\8bÑ\83ла [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Ð\9aеÑ\82еÑ\80иÑ\83лени жÑ\83Ñ\80налÑ\8bнда] болÑ\83Ñ\80гÑ\8aа боллÑ\83кÑ\8aдÑ\83ла.",
-'rev-suppressed-text-view' => "Бу бетни версиясы '''джашырылгъанды'''.
-Ð\90дминиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80 болгÑ\8aанÑ\8bгÑ\8aÑ\8bз Ñ\8eÑ\87Ñ\8eн кÑ\8aаÑ\80аÑ\80гÑ\8aа боллÑ\83кÑ\8aÑ\81Ñ\83з. Ð\90нгÑ\8bлаÑ\82Ñ\8bÑ\83ла [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Ð\94жаÑ\88Ñ\8bÑ\80Ñ\8bÑ\83ланÑ\8b жÑ\83Ñ\80налÑ\8bнда] болÑ\83Ñ\80гÑ\8aа боллÑ\83кÑ\8aдÑ\83ла.",
+'rev-deleted-text-unhide' => "Бетни бу версиясы '''кетерилгенди'''.
+[{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} Кетериулени журналында] чурумла ангылатылгъандыла.
+СÑ\8eйÑ\81егиз [$1 бу версияны кёрюрге боллукъсуз].",
+'rev-suppressed-text-unhide' => "Бетни бу версиясы '''джашырылыбды'''.
+[{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} Джашырылыуланы журналында] чурумла берилгендиле.
+СÑ\8eйÑ\81егиз [$1 версияны кёрюрге боллукъсуз].",
+'rev-deleted-text-view' => "Ð\91еÑ\82ни бÑ\83 веÑ\80Ñ\81иÑ\8fÑ\81Ñ\8b '''кеÑ\82еÑ\80илибди'''.
+СÑ\8eйÑ\81егиз кÑ\8aаÑ\80аÑ\80гÑ\8aа боллÑ\83кÑ\8aÑ\81Ñ\83з. Ð\90нгÑ\8bлаÑ\82Ñ\8bÑ\83ла [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} кеÑ\82еÑ\80иÑ\83лени жÑ\83Ñ\80налÑ\8bнда] баÑ\80дÑ\8bла.",
+'rev-suppressed-text-view' => "Бетни бу версиясы '''джашырылыбды'''.
+СÑ\8eйÑ\81егиз кÑ\8aаÑ\80аÑ\80гÑ\8aа боллÑ\83кÑ\8aÑ\81Ñ\83з. Ð\90нгÑ\8bлаÑ\82Ñ\8bÑ\83ла [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} кеÑ\82еÑ\80иÑ\83лени жÑ\83Ñ\80налÑ\8bнда] баÑ\80дÑ\8bла.",
'rev-deleted-no-diff' => "Бетни версияларыны бири '''кетерилгени''' ючюн, тенглешдиреллик тюлсюз.
Ангылатыула [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} кетериулени журналында] болургъа боллукъдула.",
'rev-suppressed-no-diff' => "Бетни бу версияларын тенглешдиреллик тюлсюз, аладан бири '''кетерилиб''' турады.",
-'rev-deleted-unhide-diff' => "Бетни версияларыны бири '''кетерилгенди'''.
-Ангылатыула [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} кетериулени журналында] болургъа болур.
-Администратор болгъаныгъыз ючюн [$1 версиягъа къараргъа боллукъсуз].",
-'rev-suppressed-unhide-diff' => "Бу тенглешдириуну версияларыны бири '''джашырылгъанды'''.
-Ангылатыула [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} джашырыуланы журналында] болургъа болур.
-Администратор болгъаныгъыз ючюн, андан ары бардырыргъа излей эсегиз [$1 версияланы бу башхалыгъына] къараргъа боллукъсуз.",
-'rev-deleted-diff-view' => "Бу тенглешдириуню версияларыны бири '''кетерилгенди'''.
-Администратор болгъаныгъыз ючюн бу тенглештириуге къараргъа боллукъсуз, ангылатыула
-Как администратор, вы можете просмотреть это сравнение, подробности могут быть указаны в [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} кетериулени журналында] болургъа боллукъдула.",
-'rev-suppressed-diff-view' => "Бу тенглешдириуню версияларыны бири '''джашырылгъанды'''.
-Администратор болгъаныгъыз ючюн, бу тенглешдириуге къараргъа боллукъсуз, ангылатыула [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} джашырыуланы журналында] болургъа боллукъду.",
+'rev-deleted-unhide-diff' => "Бетни версияларындан бири '''кетерилибди'''.
+Ангылатыула [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} кетериулени журналында] бардыла.
+Сюйсегиз [$1 версияланы башхалыкъларына къараргъа боллукъсуз].",
+'rev-suppressed-unhide-diff' => "Бетни версияларындан бири ''''''джашырылыбды''''''.
+Ангылатыула [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} кетериулени журналында] бардыла.
+Сюйсегиз [$1 версияланы башхалыкъларына къараргъа боллукъсуз].",
+'rev-deleted-diff-view' => "Бу тенглешдириуню версияларыны бири '''кетерилибди'''.
+Сюйсегиз бу тенглештириуге къараргъа боллукъсуз. Ангылатыула [{{fullurl:{{#Special:Log}}/delete|page={{FULLPAGENAMEE}}}} кетериулени журналында] бардыла.",
+'rev-suppressed-diff-view' => "Бу тенглешдириуню версияларыны бири '''джашырылыбды'''.
+Сюйсегиз бу тенглештириуге къараргъа боллукъсуз. Ангылатыула [{{fullurl:{{#Special:Log}}/suppress|page={{FULLPAGENAMEE}}}} кетериулени журналында] бардыла.",
'rev-delundel' => 'кёргюзюу/джашырыу',
'rev-showdeleted' => 'кёргюз',
'revisiondelete' => 'Бетни версияларын кетер/къайтар',
# Suppression log
'suppressionlog' => 'Джашырыуланы журналы',
-'suppressionlogtext' => 'ТÑ\8eбÑ\8eндеги, админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80ладан джаÑ\88Ñ\8bÑ\80Ñ\8bлгÑ\8aан маÑ\82еÑ\80иаллада кÑ\8aоÑ\88Ñ\83лгÑ\8aан кÑ\91б болмай Ñ\8dÑ\82илген кеÑ\82еÑ\80иÑ\83ле бла Ñ\82Ñ\8bйÑ\8bлÑ\8bÑ\83ланÑ\8b Ñ\81пиÑ\81огÑ\83дÑ\83.
-Бусагъатдагъы тыйылыуланы списоклары ючюн [[Special:IPBlockList|IP-тыйылыуланы списогуна]] къарагъыз.',
+'suppressionlogtext' => 'ТÑ\8eбÑ\8eндеги, админиÑ\81Ñ\82Ñ\80аÑ\82оÑ\80ладан джаÑ\88Ñ\8bÑ\80Ñ\8bлгÑ\8aан маÑ\82еÑ\80иаллада болгÑ\8aан кеÑ\82еÑ\80иÑ\83ле бла блок Ñ\8dÑ\82иÑ\83лени Ñ\82измеÑ\81иди.
+[[Special:BlockList|Блок этиулени тизмесинде]] бусагъатдагъы блокланы табаргъа боллукъду.',
# History merging
'mergehistory' => 'Бетни тарихлерини бирлештириую.',
# img_auth script messages
'img-auth-accessdenied' => 'Эркинлик джасакъланнганды',
-'img-auth-nopathinfo' => 'PATH_INFO джокъду.
+'img-auth-nopathinfo' => '<code>PATH_INFO</code> джокъду.
Серверигиз бу билгилени джиберир ючюн джарашмагъанды.
-CGI тамалында ишлерге эмда img_auth бла ишлемезге болур.
-https://www.mediawiki.org/wiki/Manual:Image_Authorization бетге къара.',
+CGI тамалында ишлерге эмда <code>img_auth</code> бла ишлемезге болур.
+Къарагъыз: https://www.mediawiki.org/wiki/Manual:Image_Authorization.',
'img-auth-notindir' => 'Изленнген джол джюклениулени папкасы бла байламлы тюлдю.',
'img-auth-badtitle' => '«$1» бла джараулу башлыкъ этилмейди.',
'img-auth-nologinnWL' => 'Сиз системагъа кирмедигиз, эмда «$1» акъ списокда тюлдю.',
'upload_source_file' => '(компьютеригиздеги файл)',
# Special:ListFiles
-'listfiles-summary' => 'Бу къуллукъ бет бютеу джюкленнген файлланы кёргюзеди.
-Кеб болмай джюкленнге файлла тынгылау бла списокну башында кёргюзюледиле.
-Колонканы башлыгъына басыу сафламаны тюрлендиреди.',
+'listfiles-summary' => 'Бу къуллукъ бет, бютеу джюкленнген файлланы кёргюзеди.
+Къошулуучугъа кёре айырыуда, ол къошулуучуну джангыз кёб болмай джюклеген файллары кёргюзюледиле.',
'listfiles_search_for' => 'Медиа ат бла изле:',
'imgfile' => 'файл',
'listfiles' => 'Файлланы списогу',
'filehist-filesize' => 'Файлны ёлчеми',
'filehist-comment' => 'Эсгериу',
'filehist-missing' => 'Файл джокъду',
-'imagelinks' => 'ФайлгÑ\8aа джибеÑ\80иÑ\83ле',
+'imagelinks' => 'ФайлнÑ\8b Ñ\85айÑ\8bÑ\80ланÑ\8bÑ\83Ñ\83',
'linkstoimage' => 'Бу файлгъа {{PLURAL:$1|бет|$1 бет}} джибередиле:',
'linkstoimage-more' => '$1-ден артыкъ {{PLURAL:$1|бет|бет}} бу файлгъа джибериу береди.
Кёзюудеги список къуру бу файлгъа джибериу берген {{PLURAL:$1|биринчи файлны|биринчи $1 файлны}} кёргюзеди.
'statistics-users-active-desc' => 'Ахыр {{PLURAL:$1|1 кюнде|$1 кюнде}} ишлеме этген къошулуучула',
'statistics-mostpopular' => 'Эм кёб къаралгъан бетле',
-'disambiguations' => 'Ð\9aÑ\91б магÑ\8aаналÑ\8b ангÑ\8bламланÑ\8b беÑ\82леÑ\80и',
+'disambiguations' => 'Ð\90нгÑ\8bлам айÑ\8bÑ\80гÑ\8aан беÑ\82леге джибеÑ\80иÑ\83леÑ\80и болгÑ\8aан беÑ\82ле',
'disambiguationspage' => 'Template:кёб магъаналылыкъ',
'disambiguations-text' => "Бу бетле '''кёб магъаналы бетлеге''' джибериу этедиле. Аны орнуна ала белгили бир статьягъа джибериу этерге керек болурла.<br />
[[MediaWiki:Disambiguationspage]] бетде аты салынган шаблон бетде болса, ол бет кёб магъаналы бетге саналады.",
'watchlisttools-raw' => 'Mudifega la lista in furmaa test',
# Signatures
-'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ciciaràde]])',
+'signature' => '[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ciciarade]])',
# Special:Version
'version' => 'Versiun',
'ns-specialprotected' => 'Specialieji puslapiai negali būti redaguojami.',
'titleprotected' => "[[User:$1|$1]] apsaugojo šį pavadinimą nuo sukūrimo.
Nurodyta priežastis yra ''$2''.",
+'filereadonlyerror' => 'Neįmanoma pakeisti failo " $1 " nes failų saugykla " $2 " yra nustatyta tik skaitymo režimu.
+Ją užrakinęs administratorius pateikė šį paaiškinimą: " $3 ".',
# Virus scanner
'virus-badscanner' => "Neleistina konfigūracija: nežinomas virusų skeneris: ''$1''",
'invalidemailaddress' => 'El. pašto adresas negali būti priimtas, nes atrodo, kad jis nėra teisingo formato.
Prašome įvesti gerai suformuotą adresą arba palikite tą laukelį tuščią.',
'cannotchangeemail' => 'Paskyros e-mail adresas šiame viki negali būti keičiamas.',
+'emaildisabled' => 'Ši svetainė negali siųsti elektroninių laiškų.',
'accountcreated' => 'Paskyra sukurta',
'accountcreatedtext' => 'Naudotojo paskyra $1 buvo sukurta.',
'createaccount-title' => '{{SITENAME}} paskyros kūrimas',
'updated' => '(Atnaujinta)',
'note' => "'''Pastaba:'''",
'previewnote' => "''Nepamirškite, kad tai tik peržiūra, pakeitimai dar nėra išsaugoti!'''",
+'continue-editing' => 'Tęsti redagavimą',
'previewconflict' => 'Ši peržiūra parodo tekstą iš viršutiniojo teksto redagavimo lauko taip, kaip jis bus rodomas, jei pasirinksite išsaugoti.',
'session_fail_preview' => "'''Atsiprašome! Mes negalime vykdyti jūsų keitimo dėl sesijos duomenų praradimo.
Prašome pamėginti vėl. Jei tai nepadeda, pamėginkite atsijungti ir prisijungti atgal.'''",
'edit-no-change' => 'Jūsų keitimas buvo ignoruotas kadangi nebuvo atlikta jokių teksto pakeitimų.',
'edit-already-exists' => 'Negalima sukurti naujo puslapio.
Jis jau egzistuoja.',
+'defaultmessagetext' => 'Numatytasis pranešimo tekstas',
# Parser/template warnings
'expensive-parserfunction-warning' => 'Įspėjimas: Šiame puslapyje yra per daug užtrunkančių analizatoriaus funkcijų šaukinių.
'newsectionsummary' => '/* $1 */ naujas skyrius',
'rc-enhanced-expand' => 'Rodyti detales (reikia JavaScript)',
'rc-enhanced-hide' => 'Slėpti detales',
+'rc-old-title' => 'iš pradžių sukurtas kaip " $1 "',
# Recent changes linked
'recentchangeslinked' => 'Susiję keitimai',
'backend-fail-closetemp' => 'Negalima uždaryti laikino failo.',
'backend-fail-read' => 'Negalima nuskaityti failo $1.',
'backend-fail-create' => 'Negalima sukurti failo $1.',
+'backend-fail-maxsize' => 'Failo $1 sukurti nepavyko nes jis didesnis nei {{PLURAL:$2|vienas baitas|$2 baitai|$2 baitų}}.',
'backend-fail-readonly' => 'Galutinė saugykla "$1" dabar yra skirta tik skaitymui. Buvo nurodyta priežastis: "$2"',
'backend-fail-synced' => 'Failas "$1", esantis vidinėje galutinėje saugykloje, yra pažymėtas kaip nepilnas.',
'backend-fail-connect' => 'Negalima prisijungti prie galutinės saugyklos "$1".',
'allpagesprefix' => 'Rodyti puslapiu su priedėliu:',
'allpagesbadtitle' => 'Duotas puslapio pavadinimas yra neteisingas arba turi tarpkalbininį arba tarpprojektinį priedėlį. Jame yra vienas ar keli simboliai, kurių negalima naudoti pavadinimuose.',
'allpages-bad-ns' => '{{SITENAME}} neturi „$1“ vardų srities.',
+'allpages-hide-redirects' => 'Slėpti peradresavimus',
+
+# SpecialCachedPage
+'cachedspecial-viewing-cached-ttl' => 'Jūs matote kompiuterio atmintyje išsaugotą puslapio versiją, kuri gali būti $1 senumo.',
+'cachedspecial-viewing-cached-ts' => 'Jūs matote kompiuterio atmintyje išsaugotą puslapio versiją, kuri gali neatitikti naujausios versijos.',
+'cachedspecial-refresh-now' => 'Peržiūrėti naujausius.',
# Special:Categories
'categories' => 'Kategorijos',
'version-software' => 'Įdiegta programinė įranga',
'version-software-product' => 'Produktas',
'version-software-version' => 'Versija',
+'version-entrypoints-header-url' => 'URL',
# Special:FilePath
'filepath' => 'Failo kelias',
'feedback-submit' => 'Siųsti Atsiliepimą',
'feedback-adding' => 'Pridedamas atsiliepimas į puslapį ...',
'feedback-error2' => 'Klaida: Redagavimas nepavyko',
+'feedback-close' => 'Atlikta',
# API errors
'api-error-badaccess-groups' => 'Jums neleidžiama įkelti failus į šią wiki.',
'api-error-unknown-code' => 'Nežinoma klaida: " $1 "',
'api-error-unknown-error' => 'Vidinė klaida: kažkas nutiko bandant įkelti failą.',
'api-error-unknown-warning' => 'Nežinomas įspėjimas: $1',
+'api-error-unknownerror' => 'Nežinoma klaida: " $1 "',
'api-error-uploaddisabled' => 'Įkėlimas išjungtas šioje wiki.',
+'api-error-verification-error' => 'Šis failas gali būti sugadintas arba turi neteisingą papildinį.',
+
+# Durations
+'duration-seconds' => '$1 {{PLURAL:$1|sekundė|sekundės|sekundžių}}',
+'duration-minutes' => '$1 {{PLURAL:$1|minutė|minutės|minučių}}',
+'duration-hours' => '$1 {{PLURAL:$1|valanda|valandos|valandų}}',
+'duration-days' => '$1 {{PLURAL:$1|diena|dienos|dienų}}',
+'duration-weeks' => '$1 {{PLURAL:$1|savaitė|savaitės|savaičių}}',
+'duration-years' => '$1 {{PLURAL:$1|metai|metai|metų}}',
+'duration-decades' => '$1 {{PLURAL:$1|dešimtmetis|dešimtmečiai|dešimtmečių}}',
+'duration-centuries' => '$1 {{PLURAL:$1|amžius|amžiai|amžių}}',
+'duration-millennia' => '$1 {{PLURAL:$1|tūkstantmetis|tūkstantmečiai|tūkstantmečių}}',
);
Таквите аргументи ќе бидат изземени при парсирањето.",
'post-expand-template-argument-category' => 'Страници кои содржат изземени аргументи на шаблони',
'parser-template-loop-warning' => 'Пронајдена е јамка во шаблонот: [[$1]]',
-'parser-template-recursion-depth-warning' => 'Ð\9eгÑ\80аниÑ\87Ñ\83ваÑ\9aеÑ\82о на Ñ\80екÑ\83Ñ\80зивнаÑ\82а длабоÑ\87ина надмината во шаблонот ($1)',
-'language-converter-depth-warning' => 'Ð\9dадминаÑ\82а е гÑ\80аниÑ\86аÑ\82а на длабоÑ\87инаÑ\82а на јазичниот претворач ($1)',
+'parser-template-recursion-depth-warning' => 'Ð\9fÑ\80еÑ\87екоÑ\80ена е гÑ\80аниÑ\86аÑ\82а на длабоÑ\87инаÑ\82а на Ñ\80екÑ\83Ñ\80зиÑ\98ата во шаблонот ($1)',
+'language-converter-depth-warning' => 'Ð\9fÑ\80еÑ\87екоÑ\80ена е гÑ\80аниÑ\86аÑ\82а на длабоÑ\87инаÑ\82а на јазичниот претворач ($1)',
'node-count-exceeded-category' => 'Страници каде е надминат бројот на јазли',
'node-count-exceeded-warning' => 'Страницата го надмина бројот на јазли',
-'expansion-depth-exceeded-category' => 'СÑ\82Ñ\80аниÑ\86и каде е надминаÑ\82а длабочината на проширувањето',
+'expansion-depth-exceeded-category' => 'СÑ\82Ñ\80аниÑ\86и каде е пÑ\80еÑ\87екоÑ\80ена длабочината на проширувањето',
'expansion-depth-exceeded-warning' => 'Страницата ја надмина длабочината на проширувањето',
+'parser-unstrip-loop-warning' => 'Утврдена е јамка',
+'parser-unstrip-recursion-limit' => 'Пречекорена е границата на рекурзија ($1)',
# "Undo" feature
'undo-success' => 'Уредувањето може да се откаже.
'filereadonlyerror' => 'പ്രമാണ ശേഖരണി "$2" ഇപ്പോൾ "കാണൽ-മാത്രം" വിധത്തിൽ ക്രമീകരിച്ചിരിക്കുന്നതിനാൽ "$1" എന്ന പ്രമാണത്തിൽ മാറ്റം വരുത്താനാകില്ല.
ബന്ധിച്ച കാര്യനിർവാഹക(ൻ) നൽകിയിരിക്കുന്ന കാരണം "\'\'$3\'\'" എന്നാണ്.',
+'invalidtitle-knownnamespace' => 'നാമമേഖല "$2", എഴുത്ത് "$3" എന്നിവ ഉപയോഗിച്ചുള്ള അസാധുവായ തലക്കെട്ട്',
+'invalidtitle-unknownnamespace' => 'അപരിചിതമായ നാമമേഖലാ സംഖ്യ $1, എഴുത്ത് "$2" എന്നിവ ഉപയോഗിച്ചുള്ള അസാധുവായ തലക്കെട്ട്',
# Virus scanner
'virus-badscanner' => "തെറ്റായ ക്രമീകരണങ്ങൾ: അപരിചിതമായ വൈറസ് തിരച്ചിൽ ഉപാധി : ''$1''",
'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}}.',
'userlogin' => 'Teng-ji̍p / khui sin kháu-chō',
-'userloginnocreate' => 'Teng-ji̍p',
+'userloginnocreate' => '登入',
'logout' => 'Teng-chhut',
'userlogout' => 'Teng-chhut',
'notloggedin' => 'Bô teng-ji̍p',
'gotaccountlink' => 'Teng-ji̍p',
'userlogin-resetlink' => '袂記得你登入的資料?',
'createaccountmail' => 'Thàu koè tiān-chú-phoe',
-'createaccountreason' => 'Lí-iû:',
+'createaccountreason' => '理由:',
'badretype' => 'Lí su-ji̍p ê 2-cho· bi̍t-bé bô tùi.',
'userexists' => 'Lí beh ti̍h ê iōng-chiá miâ-chheng í-keng ū lâng iōng. Chhiáⁿ kéng pa̍t-ê miâ.',
'loginerror' => 'Teng-ji̍p chhò-gō·',
De opgegeven reden is "\'\'$3\'\'".',
'invalidtitle-knownnamespace' => 'Ongeldige titel met naamruimte "$2" en tekst "$3"',
-'invalidtitle-unknownnamespace' => 'Ongeldige titel met onbekende naamruimtenummer $1 en tekst "$2"',
+'invalidtitle-unknownnamespace' => 'Ongeldige titel met onbekend naamruimtenummer $1 en tekst "$2"',
# Virus scanner
'virus-badscanner' => "Onjuiste configuratie: onbekende virusscanner: ''$1''.",
'movepage-max-pages' => "Ël màssim ëd {{PLURAL:$1|na pàgina|pàgine}} a l'é stàit tramudà e a na saran pa pì tramudà automaticament.",
'movelogpage' => 'Registr dij San Martin',
'movelogpagetext' => 'Ambelessì sota a-i é na lista ëd tute le pàgine che a son ëstàite tramudà.',
-'movesubpage' => '{{PLURAL:$1|Sotpàgina|Sotpàgine}}',
-'movesubpagetext' => "Sta pàgina-sì a l'ha $1 {{PLURAL:$1|sotpàgina|sotpàgine}} mostà ambelessì.",
+'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.",
'movereason' => 'Rason:',
'revertmove' => "buta torna coma a l'era",
'filereadonlyerror' => 'Não é possível modificar o ficheiro "$1" porque o repositório de ficheiros "$2" está em modo de leitura.
O administrador que efetuou o bloqueio deu a seguinte explicação: "$3".',
+'invalidtitle-knownnamespace' => 'Título inválido com o espaço nominal "$2" e texto "$3"',
+'invalidtitle-unknownnamespace' => 'Título inválido com número de espaço nominal $1 desconhecido e texto "$2"',
# Virus scanner
'virus-badscanner' => "Má configuração: antivírus desconhecido: ''$1''",
'node-count-exceeded-warning' => 'A página excedeu o total de nós',
'expansion-depth-exceeded-category' => 'Páginas em que a profundidade de expansão é excedida',
'expansion-depth-exceeded-warning' => 'A página excedeu a profundidade de expansão',
+'parser-unstrip-loop-warning' => 'Detectado loop unstrip',
+'parser-unstrip-recursion-limit' => 'Limite de recursão do unstrip excedido ($1)',
# "Undo" feature
'undo-success' => 'É possível desfazer a edição.
'http-curl-error' => 'Ocorreu um erro ao aceder à URL: $1',
'http-host-unreachable' => 'Não foi possível aceder à URL',
'http-bad-status' => 'Ocorreu um problema durante o pedido HTTP: $1 $2',
+'http-truncated-body' => 'O corpo da solicitação foi recebido apenas parcialmente.',
# Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>
'upload-curl-error6' => 'Não foi possível aceder à URL',
'backend-fail-readonly' => 'L\'archivije de rete "$1" jè pe stu mumende in sole letture. \'U mutive ha state: "$2"',
'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".',
# Lock manager
'lockmanager-notlocked' => 'Non ge pozze sbloccà "$1"; jidde non g\'è bloccate.',
'filereadonlyerror' => "Не удаётся изменить файл «$1», так как хранилище «$2» находится в режиме «только для чтения».
Установивший этот режим администратор оставил следующее разъяснение: «''$3''».",
+'invalidtitle-knownnamespace' => 'Недопустимый заголовок с пространством имен «$2» и текстом «$3»',
+'invalidtitle-unknownnamespace' => 'Недопустимый заголовок с неизвестным номером пространства $1 и текстом «$2»',
# Virus scanner
'virus-badscanner' => "Ошибка настройки. Неизвестный сканер вирусов: ''$1''",
'invalidemailaddress' => 'Адрес электронной почты не может быть принят, так как он не соответствует формату.
Пожалуйста, введите корректный адрес или оставьте поле пустым.',
'cannotchangeemail' => 'Адреса электронной почты этой учётной записи не могут быть изменены в этой вики.',
-'emaildisabled' => 'Ð\91ұл Ñ\81айÑ\82 Ñ\8d-поÑ\88Ñ\82анÑ\8bÒ£ Ñ\85абаÑ\80ламаÑ\81Ñ\8bн жÑ\96беÑ\80е алмайды.',
+'emaildisabled' => 'ÐÑ\82оÑ\82 Ñ\81айÑ\82 не можеÑ\82 оÑ\82пÑ\80авлÑ\8fÑ\82Ñ\8c Ñ\81ообÑ\89ениÑ\8f Ñ\8dлекÑ\82Ñ\80онной поÑ\87Ñ\82ы.',
'accountcreated' => 'Учётная запись создана',
'accountcreatedtext' => 'Создана учётная запись участника $1.',
'createaccount-title' => '{{SITENAME}}: создание учётной записи',
'parser-template-loop-warning' => 'Обнаружена петля в шаблонах: [[$1]]',
'parser-template-recursion-depth-warning' => 'Превышен предел глубины рекурсии шаблона ($1)',
'language-converter-depth-warning' => 'Превышен предел глубины преобразователя языков ($1)',
+'node-count-exceeded-category' => 'Странице, на которых превышено число узлов',
+'node-count-exceeded-warning' => 'На странице превышено число узлов',
+'expansion-depth-exceeded-category' => 'Страницы с превышением глубины раскрытия',
+'expansion-depth-exceeded-warning' => 'На странице превышен предел вложенности',
+'parser-unstrip-loop-warning' => 'Обнаружен незакрытый pre',
+'parser-unstrip-recursion-limit' => 'Превышен предел рекурсии ($1)',
# "Undo" feature
'undo-success' => 'Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.',
'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' => 'Невозможно обратить по указанному адресу.',
'updated' => '(Atnaujėnta)',
'note' => "'''Pastebiejims:'''",
'previewnote' => "'''Nepamėrškėt, kū tas tėktās pervaiza, pakeitėmā da nier ėšsauguotė!'''",
+'continue-editing' => 'Dėrbtė tuoliau',
'previewconflict' => 'Šėta parvaiza paruod teksta ėš vėršotinėjė teksta redagavėma lauka tēp, kāp ans bus ruodoms, jei pasirinksėt anū ėšsauguotė.',
'session_fail_preview' => "'''Atsiprašuom! Mes nagalėm vīkdītė Tamstas keitėma diel sesėjės doumenū praradima.
Prašuom pamiegintė vielēk. Jei šėtā napaded, pamieginkėt atsėjongtė ėr prėsėjongtė atgal.'''",
'note' => "'''සටහන:'''",
'previewnote' => "'''මෙය පෙරදසුනක් පමණක් බව සිහිතබාගන්න.'''
ඔබගේ වෙනස්කිරීම් තවමත් සුරැකීමට ලක් කොට නොමැත!",
+'continue-editing' => 'සංස්කරණය කරගෙනයන්න',
'previewconflict' => 'ඔබ විසින් සුරැකීම තෝරාගත්තොත්, ඉහළ පෙළ සංස්කරණ සරියෙහි, පෙළ දර්ශනය විය හැකි අයුර මෙම පෙර-දසුනෙන් ආවර්ජනය වේ.',
'session_fail_preview' => "'''කණගාටුයි! සැසි දත්ත හානියක් හේතුවෙන් අප විසින් ඔබගේ සංස්කරණය ක්රියායයනය කිරීමට නොහැකි වී ඇත.
කරුණාකර නැවත උත්සාහ කරන්න.
'node-count-exceeded-warning' => 'Stran je prekoračila število vozlišč',
'expansion-depth-exceeded-category' => 'Strani s prekoračeno globino razširitve',
'expansion-depth-exceeded-warning' => 'Stran je prekoračila globino razširitve',
+'parser-unstrip-loop-warning' => 'Zaznal sem odvezano zanko',
+'parser-unstrip-recursion-limit' => 'Presežena je omejitev odvezane rekurzije ($1)',
# "Undo" feature
'undo-success' => 'Urejanje ste razveljavili. Prosim, potrdite in nato shranite spodnje spremembe.',
'pagecategories' => '{{PLURAL:$1|Ntlawa|intlawa}}',
'category_header' => 'Matluka eka ntlawa wa "$1"',
'subcategories' => 'Mintlawa-ntsongo',
+'category-media-header' => 'Matluka ya xifaniso kumbe mpfumawulo eka ntlawa wa "$1"',
'category-empty' => "''Ntlawa lowu eka nkarhi wa sweswi, wuhava matluka kumbe swifaniso.''",
'hidden-categories' => '{{PLURAL:$1|Ntlawa lowu tumbetiweke|Mintlawa leyi tumbetiweke}}',
'category-subcat-count' => '{{PLURAL:$2|Ntlawa lowu wukhome mintlawa-ntsongo leyi landzelaka.|Ntlawa lowu wuni {{PLURAL:$1|ntlwa-ntsongo|$1 wa mintlaw-ntsongo}}, eka $2 wa mintlawa-ntsongo.}}',
'category-article-count' => '{{PLURAL:$2|Ntlawa lowu wukhome matluka lamalandzelaka ntsena.| {{PLURAL:$1|Tluka leri ri le|$1 matluka lawa male}} ndzeni ka ntlawa lowu, eka $2 wamintlawa.}}',
+'category-file-count' => '{{PLURAL:$2|Ntlawa lowu wukhome matluka lamalandzelaka ntsena.| {{PLURAL:$1|Tluka leri ri le|$1 matluka lawa male}} ndzeni ka ntlawa lowu, eka $2 wamintlawa.}}',
'listingcontinuesabbrev' => 'Mahlwe.',
'noindex-category' => 'Matluka lama kayivelaka xikombandlela xa tinhlokomhaka',
'about' => 'Timhaka hi',
+'article' => 'Matluka lama tsariweke',
'newwindow' => '(Yi pfula e ndhzawini yintswa)',
'cancel' => 'Thsika',
'moredotdotdot' => "Swin'wana...",
'create-this-page' => 'Tumbuluxa tluka leri',
'delete' => 'Sula',
'deletethispage' => 'Sula tluka leri',
+'viewdeleted_short' => 'Vona {{PLURAL:$1|ndzulamiso lowu suriweke|$1 mindzulamiso leyi suriweke}}',
'protect' => 'Sirhelela',
'protect_change' => 'Cinca',
'protectthispage' => 'Sirhelela tluka leri',
'toolbox' => 'Bokisi ra switirhisiwa',
'otherlanguages' => "Hi ti ndzimi tin'wana",
'redirectedfrom' => '(Ritlerisewe kusuka e $1)',
+'redirectpagesub' => 'Tluka ro kongomisa',
'lastmodifiedat' => 'Tluka leri rihetelele ku lulamisiwa hi $1, nkarhi kuri $2.',
'jumpto' => 'Tlulela eka:',
'jumptonavigation' => 'Xikomba-ndlela',
'remembermypassword' => 'Tsundzuka ku nghena eka Khompuyuta leyi (kufikela eka $1 {{PLURAL:$1|siku|masiku}})',
'login' => 'Pfula u nghena',
'nav-login-createaccount' => 'Pfula unghena / Tumbuluxa akhawunti',
+'loginprompt' => 'U fanele ku pfumelela swipfuneti leswaku u pfula unghena eka {{SITENAME}}.',
'userlogin' => 'Pfula unghena / Tumbuluxa akhawunti',
'logout' => 'Pfala u famba',
'userlogout' => 'Pfala u famba',
'gotaccount' => 'Xna una akhawunti hi khale? $1.',
'gotaccountlink' => 'Pfula unghena',
'userlogin-resetlink' => 'Xana u rivele vuxokoxoko bya wena byo pfula unghena?',
+'mailmypassword' => 'Rhumela vito-mpfungulo lerintwsa',
'loginlanguagelabel' => 'Ririmi: $1',
# Edit page toolbar
'extlink_sample' => 'http://www.example.com khwekerisa nhlokomhaka',
'extlink_tip' => 'Xikhwekerisi xa tluka ralehandle ka wiki leyi (tsundzuka xi rhangi xa http:// )',
'headline_sample' => 'tsala ra nhlokomhaka',
+'headline_tip' => 'Nhloko mhaka ya xiyenge xa 2',
'nowiki_sample' => 'Hoxa xivulwa lexi nga sasekisiwangiki mavonele laha',
'nowiki_tip' => 'bakanya kuxongisa marito ka wiki',
'image_tip' => 'Fayili leyi angarhiweke',
'showdiff' => 'Komba ku cinca',
'anoneditwarning' => "'''Watsundzuxiwa:''' awu pfulanga unghena eka wiki leyi.
Adirese ya khompuyuta ya wena ya IP yita tsariwa eka matimu ya ku lulamisiwa ka tluka leri.",
+'newarticle' => '(yintswa)',
'newarticletext' => "Ulandzele xikhwekerisi lexi kombaka tluka leringasi tsariwaka.
Leswaku u tumbuluxa tluka leri, tsala eka bokisi leringa e hansi (Nkambe unga ye eka [[{{MediaWiki:Helppage}}|tluka ra mpfuno]] kukuma vuxokoxoko lebyi engetelekeke).
Loko ufike eka tluka leri hixihoxo, thlava bhatheni leyinge '''thlelela'''.",
'previewnote' => "'''Lowu i ndzinganiso ntsena;
kucinca a ku sihlayisiwa!'''",
'editing' => 'Ulekululamiseni ka $1',
+'editingsection' => 'Ndzulamiso wa $1 (Xiyenge)',
'copyrightwarning' => "Xiya leswaku minyikelo hinkwayo e ka {{SITENAME}} yi tekiwa yitshuxiwe e hansi ka $2 (Vona $1 ku kuma vuxokoxoko).
loko unga tsakeli leswaku vutsari bya wena byi lulamisiwa no aviwa handle ko tweriwa vusiwana, unga tsari laha.<br />
U hi tshembisa nakambe leswaku hi wena mutsari wa leswi nyikeriwaka laha, kumbe leswi u swinyikelaka u swi tekile e xihloveni xa lerivaleni kumbe laha kunga na mpfumelelo wa mani na mani.
'templatesused' => '{{PLURAL:$1|Xivumbiwa ntirho lexi|Swivumbiwa ntirho leswi}} tirhisiweke eka tluka leri:',
'template-protected' => '(Ri sirheleriwile)',
'template-semiprotected' => '(lisirheleriwile switsanana)',
+'hiddencategories' => 'Tluka leri i nandza wa {{PLURAL:$1|ntlwa lowu tumbetiweke|$1 mintlawa leyi tumbetiweke}}:',
'permissionserrorstext-withaction' => 'Awupfumeleriwanga ku $2, hikwalaho ka {{PLURAL:$1|wa xivangelo|wa swivangelo}}:',
+'recreate-moveddeleted-warn' => "'''Tivonele: utumbuluxa tluka leri raha ku suriwa kungarikhale.'''
+
+Nhlahluvisisa loko swifanerile ku ya emahlweni u lulamisa tluka leri.
+Matimu yo sula no susa ma kombila laha ehansi ku ku pfuna:",
'moveddeleted-notice' => 'Tluka leri ri suriwile.
nhula ya minxaxamelo leyi kombaka ku suriwa na ku susiwa ka tluka leri ya kombiwa laha ehansi.',
'viewpagelogs' => 'Vona nghula ya minxaxamelo ya tluka leri',
'currentrev-asof' => 'Mindzulamiso ya sweswinyana ya $1',
'revisionasof' => 'Ndzulamiso kusukela hi $1',
+'revision-info' => 'Mindzulamiso ku sukela hi $1 leyi endliweke hi $2',
'previousrevision' => '← Ndzulamiso wakhale',
'nextrevision' => 'Ndzulamiso wa sweswinyana →',
'currentrevisionlink' => 'Ndzulamiso wasweswinyana',
# Diffs
'history-title' => 'Matimu ya mindulamiso ya "$1"',
+'difference' => '(Kuhambana exikarhi ka mindzulamiso)',
'lineno' => 'Ntila $1:',
'compareselectedversions' => 'Hambaniisa exikarhi ka mindzulamiso leyi langiweke',
'editundo' => 'Thlerisela',
'prevn-title' => '$1 {{PLURAL:$1|nkutlunya lo wu|minkutlunya leyi}} hundzeke',
'nextn-title' => '$1 {{PLURAL:$1|nkutlunya lowu|minkutlunya leyi}} landzelaka',
'shown-title' => "Komba $1 {{PLURAL:$1|mbuyelo|mimbuyelo}} eka tluka rin'wana na ri n'wana",
+'viewprevnext' => 'Vona ($1 {{int:pipe-separator}} $2) ($3)',
'searchmenu-exists' => "'''Tluka leri vuriwaka \"[[:\$1]]\" ikhale ririkona eka wiki leyi.'''",
'searchmenu-new' => "'''Tumbuluxa tluka ra \"[[:\$1]]\" eka wiki leyi!'''",
'searchhelp-url' => 'Help:Leswinga ndzeni',
'searchprofile-everything-tooltip' => 'Lavalava eka matsalwa hinkwawo (kuhlanganisa na matluka ya mbulavulo)',
'searchprofile-advanced-tooltip' => 'Lavalava eka swisivela mavito leswi tolovelekeke',
'search-result-size' => '$1 ({{PLURAL:$2|1 viti|$2 maviti}})',
+'search-result-category-size' => '{{PLURAL:$1|nandza|$1 wa malandza}} ({{PLURAL:$2|ntlawa-ntsongo|$2 wa mintlawa-ntsongo}}, {{PLURAL:$3|fayili|$3 wa tifayili}})',
'search-redirect' => '(nkongomiso kusaka e $1)',
'search-section' => '(Xiyenge $1)',
'search-suggest' => 'Xana uvula: $1',
'saveprefs' => 'Hlayisa',
'resetprefs' => 'sula kucinca lokungahlayisiwangiki',
'prefs-editing' => 'Kululamisa',
+'youremail' => 'E-mail:',
'yourrealname' => 'Vito ra ntiyiso:',
'yourlanguage' => 'Ririmi:',
'prefs-help-email' => 'Adiresi ya e-mail ayibohi, kambe yita laveka leswaku u cinca ritompfungulo ra wena, loko swiendleka leswaku u ri rivala.',
'nchanges' => '$1 {{PLURAL:$1|wa ndzulamiso|wa mindzulamiso}}',
'recentchanges' => 'Ku cinca ka sweswi-nyana',
'recentchanges-legend' => 'Tindlela to langutisa ku cinca ka sweswinyana',
+'recentchangestext' => 'Landzelela mindzulamiso ya sweswinyana ya wiki leyi eka tluka leri.',
+'recentchanges-feed-description' => 'Landzelela mindzulamiso ya sweswinyana eka wiki leyi hi xiphameri-hungu lexi.',
'recentchanges-label-newpage' => 'Ndzulamiso lowu wu tumbuluxe tluka rintswa',
'recentchanges-label-minor' => 'Lowu i ndzulamiso wu tsongo',
'recentchanges-label-bot' => 'Ndzulamiso lowu wu endliwe hi rhobhoto',
'recentchanges-label-unpatrolled' => 'Ndzulamiso lowu awusi languteriwa',
+'rcnote' => "Lha hansi ku kombiwa {{PLURAL:$1|ku cinca|''$1''' wa mindzulamiso}} endzeni ka {{PLURAL:$2|siku|'''$2''' wa masiku}} lamahundzeke, hi $5, $4.",
+'rcnotefrom' => "Laha hansi kuxaxametiwe ku cinca kusukela hi '''$2''' (kuya ka '''$1''').",
'rclistfrom' => 'Komba mindzilamiso leyintswa kusukela eka $1',
'rcshowhideminor' => '$1 wa mindzulamiso leyi ntsanana',
'rcshowhidebots' => '$1 wati rhobhoto',
# Statistics
'statistics' => 'Mintsengo',
+'disambiguationspage' => 'Template:Hambanisa marito',
+
# Miscellaneous special pages
'nbytes' => '$1 {{PLURAL:$1|wa bayiti|wa tibayit}}',
'nmembers' => '$1 {{PLURAL:$1|museketeri| wa vaseketeri}}',
+'prefixindex' => 'Matluka hinkwawo lama sungulaka hi',
+'usercreated' => '{{GENDER:$3|u tumbuluxe}} hi siku ra $1 hinkarhi wa $2',
'newpages' => 'Matluka mantswa',
'move' => 'Yi sa kunwana',
'movethispage' => 'Yisa tluka leri ndhzawini yinwana',
+'pager-newer-n' => '{{PLURAL:$1|xa khale|$1 swa khale}}',
+'pager-older-n' => '{{PLURAL:$1|ra khale|$1 ya khale}}',
# Book sources
'booksources' => 'Swihlovo swatibuku',
+'booksources-search-legend' => 'Lavalava swihlovo swa tibuku',
'booksources-go' => 'Nghena',
# Special:Log
'linksearch-ok' => 'Lava',
'linksearch-line' => '$1 yi khwekerisiwe kusuka eka $2',
+# Special:Log/newusers
+'newuserlogpage' => 'Nghula ya nxaxamelo wa ku tumbuluxiwa ka vatirhisi',
+
# Special:ListGroupRights
'listgrouprights-members' => '(nxaxamelo wa valandzeri)',
# Watchlist
'watchlist' => 'Leswi ndziswilanguteke',
'mywatchlist' => 'Leswi ndziswilanguteke',
+'watchlistfor2' => 'Swa $1 $2',
'watch' => 'Languta',
'watchthispage' => 'Languta tluka leri',
'unwatch' => 'Ungalanguti',
+'watchlist-details' => '{{PLURAL:$1|$1 tluka|$1 wa matluka}} eka nxaxamelo wa leswi uswilanguteke, kungasi hlayiwa matluka yu mbulavulo.',
'wlshowlast' => 'Komba $1 wati awara $2 wa masiku kumbe $3',
+'watchlist-options' => 'Minhlawulo ya nxaxamelo wa leswilangutiweke',
# Displayed when you click the "watch" button and it is in the process of watching
'watching' => 'Ulangutile...',
# Contributions
'contributions' => 'Minyikelo ya mutirhisi',
+'contributions-title' => 'Minyikelo ya vutirhisi ya $1',
'mycontris' => 'Minyikelo ya mina',
'contribsub2' => 'For $1 ($2)',
'nocontribs' => 'Ku hava ku cinca loku kumiweke eka xiyenge lexi.',
'sp-contributions-newbies' => 'Komba minyikela ya ti akhawunti tintswa ntsena',
'sp-contributions-newbies-sub' => 'Eka ti akhawunti ti ntswa',
+'sp-contributions-blocklog' => 'Ngula ya nxaxamelo wa kusivela',
+'sp-contributions-uploads' => 'Nxaxamelo wa ku nghenisa',
+'sp-contributions-logs' => 'Nghula ya nxaxamelo',
'sp-contributions-talk' => 'Mbulavulo',
'sp-contributions-search' => 'Lava minyikelo',
+'sp-contributions-username' => 'Hoxa Direse ya IP kumbe vito ra mutirhisi:',
+'sp-contributions-toponly' => 'Komba ntsena mindzulamiso leyi yinga haku endliwa sweswinyana',
'sp-contributions-submit' => 'Lava',
# What links here
'whatlinkshere-title' => 'Matluka lama khwekelaka eka $1',
'whatlinkshere-page' => 'Tluka:',
'linkshere' => "Matluka lama landzelaka makhwekela eka '''[[:$1]]''':",
+'nolinkshere' => "Kuhava matluka lama khwekelaka eka '''[[:$1]]'''.",
'isredirect' => 'Tluka ro kongomisa',
+'istemplate' => 'Swisivela ndhzawu',
'isimage' => 'Xikhwekerisi xa fayili',
'whatlinkshere-prev' => '{{PLURAL:$1|leri hundzeka| $1 lama hundzeke}}',
'whatlinkshere-next' => '{{PLURAL:$1|lowu landzelaka| $1 leyi landzelaka}}',
'whatlinkshere-links' => '← Swikhwekerisi',
'whatlinkshere-hideredirs' => '$1 ya matluka yo thlerisela',
+'whatlinkshere-hidetrans' => '$1 wa swisivela ndhzawu',
'whatlinkshere-hidelinks' => '$1 wa swikhwekeri',
'whatlinkshere-hideimages' => '$1 swikhwekerisi saw xifaniso',
'whatlinkshere-filters' => 'Tinhlelo',
'change-blocklink' => 'Cinca xirhapa',
'contribslink' => 'Minyikelo',
'blocklogpage' => 'Ngula ya nxaxamelo wa kusiverwa ka vatirhisi',
+'blocklogentry' => 'Nsivelo wa mutirhisi [[$1]] wu hela hi $2 $3',
'block-log-flags-nocreate' => 'Kupfula akhawunti swa arisiwa',
# Move page
+'movelogpage' => 'Nghula ya nxaxamelo waku susiwa',
'revertmove' => 'thlerisela',
# Export
'tooltip-t-recentchangeslinked' => 'Kucinca kasweswinyana ka matluka la ma thlavinyetiweke eka tluka leri',
'tooltip-feed-atom' => 'Vuhaxi bya Atom bya tluka leri',
'tooltip-t-contributions' => 'Nxaxamelo wa minyikelo ya mutirhisi loyi',
+'tooltip-t-emailuser' => 'Rhumela mutirhisa loyi e-mail',
'tooltip-t-upload' => 'Khandziyisa tifayili',
'tooltip-t-specialpages' => 'Nxaxamelo wa matluka yo hlawuleka',
'tooltip-t-print' => 'Gangliso wa tluka leri',
'tooltip-summary' => 'Tsala nkomiso',
# Browsing diffs
+'previousdiff' => '← Ndzulamiso wakhale',
'nextdiff' => 'Ndzulamiso lowu ntswa →',
# Media information
'file-info-size' => '$1 × $2 ku anama na leha hi ti phikisele, Vukulu bya fayili: $3, muxaka waMIME: $4',
'file-nohires' => 'Xifaniso lexi axikuriseki kuhundza laha.',
+'svg-long-desc' => 'Fayili ya SVG, vukulu lebyi ringaneke $1 × $2 hi ti phikisele, vukulu bya fayili: $3',
'show-big-image' => 'kuleha na ku anama hixitalo',
# Bad image list
Swithlavinyeti leswi engetelekeke eka ntila lowu fanaka swilangutiwa swiri swihambukisi, hileswaku matluka lawa fiyili yinga kumekaka kona endzeni.',
# Metadata
+'metadata' => 'Nghula ya vuxokoxoko',
'metadata-help' => 'Fayili leyi yi khome vuxokoxoko lebyi engetelekeke, swingaendleka yi hoxiwile kusuka eka Khemera kumbe muchini wo gandlisa lowu tirhisiweke ku yi tumbuluxa.
Loko fayili yi antswisiwile kusukela eka matshamelo ya yona yo sungula, vuxokoxoko bya yona byinga va byi cincile.',
'metadata-fields' => "Vuxokoxoko bya xifaniso lexi nga eka hungu leri byi ta kombiwa eka tluka leri kombaka xifaniso lexi loko tafula ra nxaxamela wa vuxokoxoko ri pfariwa.
'edit-externally-help' => '(Vona [//www.mediawiki.org/wiki/Manual:External_editors swiletelo swo sungurisa] leswaku ukuma vuxokoxoko lebyi engetelekeke)',
# 'all' in various places, this might be different for inflected languages
+'watchlistall2' => 'Hinkwawo',
'namespacesall' => 'Hinkwawo',
'monthsall' => 'hikwato',
# Watchlist editing tools
'watchlisttools-view' => 'Vona kucinca loku yelanaka',
+'watchlisttools-edit' => 'Langutisa naswona u lulamisa nxaxamelo wa leswilangutiweke',
'watchlisttools-raw' => 'Lulamisa nxaxamelo-mbisi wa leswilangutiweke',
# Core parser functions
# Special:SpecialPages
'specialpages' => 'Matluka yo hlawuleka',
+# External image whitelist
+'external_image_whitelist' => ' #Tshika ntila lowu wunga cinciwanga<pre>
+#Hoxa hlamuselo lowu tolovelekeke (xiphemu lexi nga exikarhi ka //) laha hansi
+#Swita hlanganisiwa na tiURL to swifaniso swa le handle (leswi khwekerisiweke)
+#Leswi yelanaka swi ta kombiwa swiri swifaniso, lokoswingaritano kuta kombiwa ntsena swikhwekerisi swa xifaniso
+#Mintila leyi sungulaka # yivona kuri ma vonele/nlhamulo
+#Xi lava marito lama xaxametiweke hi marito-nkulu na lama tsongo
+
+#hoxa swiphemu hinkwaswo swa regex ehenhla ka ntilalowu. Tshika ntila lowu wuri leswi wunga xiswona</pre>',
+
# Special:Tags
'tag-filter' => 'Xihluti xa [[Special:Tags|Xi angi]]:',
'filereadonlyerror' => '无法修改文件“$1”,因为文件库“$2”处于只读模式。
管理员对锁定它给出的解释是:“$3”。',
+'invalidtitle-knownnamespace' => '使用名字空间“$2”和文本“$3”的无效标题',
+'invalidtitle-unknownnamespace' => '使用未知名字空间编号$1和文本“$2”的无效标题',
# Virus scanner
'virus-badscanner' => "错误的配置:未知的病毒扫描程序:''$1''",
'parser-template-loop-warning' => '检查到模板循环:[[$1]]',
'parser-template-recursion-depth-warning' => '模板递归深度越限($1)',
'language-converter-depth-warning' => '字词转换器深度越限($1)',
+'node-count-exceeded-category' => '页面的节点数超出限制',
+'node-count-exceeded-warning' => '页面超出了节点数',
# "Undo" feature
'undo-success' => '此编辑可以被撤销。请检查以下比较以核实这正是您想做的,然后保存以下更改完成撤销编辑。',
'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',
# SpecialCachedPage
'cachedspecial-viewing-cached-ttl' => '你正在浏览本页的缓存版本,至多可能存在 $1 的延迟。',
+'cachedspecial-viewing-cached-ts' => '您正浏览此页的缓存版本,不一定是最新的完整版本。',
'cachedspecial-refresh-now' => '查看最新的。',
# Special:Categories
'version-software' => '已安装的软件',
'version-software-product' => '产品',
'version-software-version' => '版本',
+'version-entrypoints' => '入口点 URL',
+'version-entrypoints-header-entrypoint' => '入口点',
'version-entrypoints-header-url' => 'URL',
# Special:FilePath
}
/**
- * Recursively resolves dependencies and detects circular references
+ * Resolves dependencies and detects circular references.
+ *
+ * @param module String Name of the top-level module whose dependencies shall be
+ * resolved and sorted.
+ * @param resolved Array Returns a topological sort of the given module and its
+ * dependencies, such that later modules depend on earlier modules. The array
+ * contains the module names. If the array contains already some module names,
+ * this function appends its result to the pre-existing array.
+ * @param unresolved Object [optional] Hash used to track the current dependency
+ * chain; used to report loops in the dependency graph.
+ * @throws Error if any unregistered module or a dependency loop is encountered
*/
- function recurse( module, resolved, unresolved ) {
+ function sortDependencies( module, resolved, unresolved ) {
var n, deps, len;
if ( registry[module] === undefined ) {
registry[module].dependencies = [registry[module].dependencies];
}
}
+ if ( $.inArray( module, resolved ) !== -1 ) {
+ // Module already resolved; nothing to do.
+ return;
+ }
+ // unresolved is optional, supply it if not passed in
+ if ( !unresolved ) {
+ unresolved = {};
+ }
// Tracks down dependencies
deps = registry[module].dependencies;
len = deps.length;
for ( n = 0; n < len; n += 1 ) {
if ( $.inArray( deps[n], resolved ) === -1 ) {
- if ( $.inArray( deps[n], unresolved ) !== -1 ) {
+ if ( unresolved[deps[n]] ) {
throw new Error(
'Circular reference detected: ' + module +
' -> ' + deps[n]
}
// Add to unresolved
- unresolved[unresolved.length] = module;
- recurse( deps[n], resolved, unresolved );
- // module is at the end of unresolved
- unresolved.pop();
+ unresolved[module] = true;
+ sortDependencies( deps[n], resolved, unresolved );
+ delete unresolved[module];
}
}
resolved[resolved.length] = module;
}
/**
- * Gets a list of module names that a module depends on in their proper dependency order
+ * Gets a list of module names that a module depends on in their proper dependency
+ * order.
*
* @param module string module name or array of string module names
* @return list of dependencies, including 'module'.
* @throws Error if circular reference is detected
*/
function resolve( module ) {
- var modules, m, deps, n, resolved;
+ var m, resolved;
// Allow calling with an array of module names
if ( $.isArray( module ) ) {
- modules = [];
+ resolved = [];
for ( m = 0; m < module.length; m += 1 ) {
- deps = resolve( module[m] );
- for ( n = 0; n < deps.length; n += 1 ) {
- modules[modules.length] = deps[n];
- }
+ sortDependencies( module[m], resolved );
}
- return modules;
+ return resolved;
}
if ( typeof module === 'string' ) {
resolved = [];
- recurse( module, resolved, [] );
+ sortDependencies( module, resolved );
return resolved;
}
}
/**
- * Automatically executes jobs and modules which are pending with satistifed dependencies.
+ * Determine whether all dependencies are in state 'ready', which means we may
+ * execute the module or job now.
+ *
+ * @param dependencies Array dependencies (module names) to be checked.
*
- * This is used when dependencies are satisfied, such as when a module is executed.
+ * @return Boolean true if all dependencies are in state 'ready', false otherwise
*/
- function handlePending( module ) {
- var j, r;
+ function allReady( dependencies ) {
+ return filter( 'ready', dependencies ).length === dependencies.length;
+ }
- try {
- // Run jobs whose dependencies have just been met
- for ( j = 0; j < jobs.length; j += 1 ) {
- if ( compare(
- filter( 'ready', jobs[j].dependencies ),
- jobs[j].dependencies ) )
- {
- var callback = jobs[j].ready;
- jobs.splice( j, 1 );
- j -= 1;
- if ( $.isFunction( callback ) ) {
- callback();
+ /**
+ * Log a message to window.console, if possible. Useful to force logging of some
+ * errors that are otherwise hard to detect, even if mw.log is not available. (I.e.,
+ * this logs also if not in debug mode.)
+ *
+ * @param msg String text for the log entry
+ * @param e Error [optional] to also log.
+ */
+ function log( msg, e ) {
+ if ( window.console && typeof window.console.log === 'function' ) {
+ console.log( msg );
+ if ( e ) {
+ console.log( e );
+ }
+ }
+ }
+
+ /**
+ * A module has entered state 'ready', 'error', or 'missing'. Automatically update pending jobs
+ * and modules that depend upon this module. if the given module failed, propagate the 'error'
+ * state up the dependency tree; otherwise, execute all jobs/modules that now have all their
+ * dependencies satisfied. On jobs depending on a failed module, run the error callback, if any.
+ *
+ * @param module String name of module that entered one of the states 'ready', 'error', or 'missing'.
+ */
+ function handlePending( module ) {
+ var j, job, hasErrors, m, stateChange;
+
+ // Modules.
+ if ( $.inArray( registry[module].state, ['error', 'missing'] ) !== -1 ) {
+ // If the current module failed, mark all dependent modules also as failed.
+ // Iterate until steady-state to propagate the error state upwards in the
+ // dependency tree.
+ do {
+ stateChange = false;
+ for ( m in registry ) {
+ if ( $.inArray( registry[m].state, ['error', 'missing'] ) === -1 ) {
+ if ( filter( ['error', 'missing'], registry[m].dependencies ).length > 0 ) {
+ registry[m].state = 'error';
+ stateChange = true;
+ }
}
}
- }
- // Execute modules whose dependencies have just been met
- for ( r in registry ) {
- if ( registry[r].state === 'loaded' ) {
- if ( compare(
- filter( ['ready'], registry[r].dependencies ),
- registry[r].dependencies ) )
- {
- execute( r );
+ } while ( stateChange );
+ }
+
+ // Execute all jobs whose dependencies are either all satisfied or contain at least one failed module.
+ for ( j = 0; j < jobs.length; j += 1 ) {
+ hasErrors = filter( ['error', 'missing'], jobs[j].dependencies ).length > 0;
+ if ( hasErrors || allReady( jobs[j].dependencies ) ) {
+ // All dependencies satisfied, or some have errors
+ job = jobs[j];
+ jobs.splice( j, 1 );
+ j -= 1;
+ try {
+ if ( hasErrors ) {
+ throw new Error ("Module " + module + " failed.");
+ } else {
+ if ( $.isFunction( job.ready ) ) {
+ job.ready();
+ }
+ }
+ } catch ( e ) {
+ if ( $.isFunction( job.error ) ) {
+ try {
+ job.error( e, [module] );
+ } catch ( ex ) {
+ // A user-defined operation raised an exception. Swallow to protect
+ // our state machine!
+ log( 'mw.loader::handlePending> Exception thrown by job.error()', ex );
+ }
}
}
}
- } catch ( e ) {
- // Run error callbacks of jobs affected by this condition
- for ( j = 0; j < jobs.length; j += 1 ) {
- if ( $.inArray( module, jobs[j].dependencies ) !== -1 ) {
- if ( $.isFunction( jobs[j].error ) ) {
- jobs[j].error( e, module );
- }
- jobs.splice( j, 1 );
- j -= 1;
+ }
+
+ if ( registry[module].state === 'ready' ) {
+ // The current module became 'ready'. Recursively execute all dependent modules that are loaded
+ // and now have all dependencies satisfied.
+ for ( m in registry ) {
+ if ( registry[m].state === 'loaded' && allReady( registry[m].dependencies ) ) {
+ execute( m );
}
}
- throw e;
}
}
/**
* Adds a script tag to the DOM, either using document.write or low-level DOM manipulation,
- * depending on whether document-ready has occured yet and whether we are in async mode.
+ * depending on whether document-ready has occurred yet and whether we are in async mode.
*
* @param src String: URL to script, will be used as the src attribute in the script tag
* @param callback Function: Optional callback which will be run when the script is done
*
* @param module string module name to execute
*/
- function execute( module, callback ) {
+ function execute( module ) {
var style, media, i, script, markModuleReady, nestedAddScript;
if ( registry[module] === undefined ) {
markModuleReady = function() {
registry[module].state = 'ready';
handlePending( module );
- if ( $.isFunction( callback ) ) {
- callback();
- }
};
nestedAddScript = function ( arr, callback, async, i ) {
// Recursively call addScript() in its own callback
} catch ( e ) {
// This needs to NOT use mw.log because these errors are common in production mode
// and not in debug mode, such as when a symbol that should be global isn't exported
- if ( window.console && typeof window.console.log === 'function' ) {
- console.log( 'mw.loader::execute> Exception thrown by ' + module + ': ' + e.message );
- console.log( e );
- }
+ log('mw.loader::execute> Exception thrown by ' + module + ': ' + e.message, e);
registry[module].state = 'error';
+ handlePending( module );
}
}
}
currReqBase = $.extend( { 'version': formatVersionNumber( maxVersion ) }, reqBase );
+ // For user modules append a user name to the request.
+ if ( group === "user" && mw.config.get( 'wgUserName' ) !== null ) {
+ currReqBase.user = mw.config.get( 'wgUserName' );
+ }
currReqBaseLength = $.param( currReqBase ).length;
async = true;
// We may need to split up the request to honor the query string length limit,
if ( registry[module] !== undefined && registry[module].script !== undefined ) {
throw new Error( 'module already implemented: ' + module );
}
- // Mark module as loaded
- registry[module].state = 'loaded';
// Attach components
registry[module].script = script;
registry[module].style = style;
registry[module].messages = msgs;
- // Execute or queue callback
- if ( compare(
- filter( ['ready'], registry[module].dependencies ),
- registry[module].dependencies ) )
- {
- execute( module );
+ // The module may already have been marked as erroneous
+ if ( $.inArray( registry[module].state, ['error', 'missing'] ) === -1 ) {
+ registry[module].state = 'loaded';
+ if ( allReady( registry[module].dependencies ) ) {
+ execute( module );
+ }
}
},
}
// Resolve entire dependency map
dependencies = resolve( dependencies );
- // If all dependencies are met, execute ready immediately
- if ( compare( filter( ['ready'], dependencies ), dependencies ) ) {
+ if ( allReady( dependencies ) ) {
+ // Run ready immediately
if ( $.isFunction( ready ) ) {
ready();
}
- }
- // If any dependencies have errors execute error immediately
- else if ( filter( ['error'], dependencies ).length ) {
+ } else if ( filter( ['error', 'missing'], dependencies ).length ) {
+ // Execute error immediately if any dependencies have errors
if ( $.isFunction( error ) ) {
- error( new Error( 'one or more dependencies have state "error"' ),
+ error( new Error( 'one or more dependencies have state "error" or "missing"' ),
dependencies );
}
- }
- // Since some dependencies are not yet ready, queue up a request
- else {
+ } else {
+ // Not all dependencies are ready: queue up a request
request( dependencies, ready, error );
}
},
* be assumed if loading a URL, and false will be assumed otherwise.
*/
load: function ( modules, type, async ) {
- var filtered, m;
+ var filtered, m, module;
// Validate input
if ( typeof modules !== 'object' && typeof modules !== 'string' ) {
// an array of unrelated modules, whereas the modules passed to
// using() are related and must all be loaded.
for ( filtered = [], m = 0; m < modules.length; m += 1 ) {
- if ( registry[modules[m]] !== undefined ) {
- filtered[filtered.length] = modules[m];
+ module = registry[modules[m]];
+ if ( module !== undefined ) {
+ if ( $.inArray( module.state, ['error', 'missing'] ) === -1 ) {
+ filtered[filtered.length] = modules[m];
+ }
}
}
+ if (filtered.length === 0) {
+ return;
+ }
// Resolve entire dependency map
filtered = resolve( filtered );
- // If all modules are ready, nothing dependency be done
- if ( compare( filter( ['ready'], filtered ), filtered ) ) {
+ // If all modules are ready, nothing to be done
+ if ( allReady( filtered ) ) {
return;
}
- // If any modules have errors
- if ( filter( ['error'], filtered ).length ) {
+ // If any modules have errors: also quit.
+ if ( filter( ['error', 'missing'], filtered ).length ) {
return;
}
- // Since some modules are not yet ready, queue up a request
+ // Since some modules are not yet ready, queue up a request.
request( filtered, null, null, async );
- return;
},
/**
if ( registry[module] === undefined ) {
mw.loader.register( module );
}
- if ( state === 'ready' && registry[module].state !== state) {
+ if ( $.inArray(state, ['ready', 'error', 'missing']) !== -1
+ && registry[module].state !== state ) {
// Make sure pending modules depending on this one get executed if their
// dependencies are now fulfilled!
registry[module].state = state;
*/
class SkinVector extends SkinTemplate {
+ protected static $bodyClasses = array( 'vector-animateLayout' );
+
var $skinname = 'vector', $stylename = 'vector',
$template = 'VectorTemplate', $useHeadElement = true;
parent::setupSkinUserCss( $out );
$out->addModuleStyles( 'skins.vector' );
}
+
+ /**
+ * Adds classes to the body element.
+ *
+ * @param $out OutputPage object
+ * @param &$bodyAttrs Array of attributes that will be set on the body element
+ */
+ function addToBodyAttributes( OutputPage $out, &$bodyAttrs ) {
+ if ( isset( $bodyAttrs['class'] ) && strlen( $bodyAttrs['class'] ) > 0 ) {
+ $bodyAttrs['class'] .= ' ' . implode( ' ', static::$bodyClasses );
+ } else {
+ $bodyAttrs['class'] = implode( ' ', static::$bodyClasses );
+ }
+ }
}
/**
/* Animate between standard and high definition layouts */
-div#content,
-div#footer {
+body.vector-animateLayout div#content,
+body.vector-animateLayout div#footer {
transition: margin-left 250ms, padding 250ms;
-moz-transition: margin-left 250ms, padding 250ms;
-webkit-transition: margin-left 250ms, padding 250ms;
-o-transition: margin-left 250ms, padding 250ms;
}
-#p-logo,
-#left-navigation {
+body.vector-animateLayout #p-logo,
+body.vector-animateLayout #left-navigation {
transition: left 250ms;
-moz-transition: left 250ms;
-webkit-transition: left 250ms;
-o-transition: left 250ms;
}
-#mw-panel {
+body.vector-animateLayout #mw-panel {
transition: padding-left 250ms;
-moz-transition: padding-left 250ms;
-webkit-transition: padding-left 250ms;
-o-transition: padding-left 250ms;
}
-#p-search {
+body.vector-animateLayout #p-search {
transition: margin-right 250ms;
-moz-transition: margin-right 250ms;
-webkit-transition: margin-right 250ms;
-o-transition: margin-right 250ms;
}
-#p-personal {
+body.vector-animateLayout #p-personal {
transition: right 250ms;
-moz-transition: right 250ms;
-webkit-transition: right 250ms;
-o-transition: right 250ms;
}
-#mw-head-base {
+body.vector-animateLayout #mw-head-base {
transition: margin-left 250ms;
-moz-transition: margin-left 250ms;
-webkit-transition: margin-left 250ms;
--- /dev/null
+<?php
+/**
+ * ResourceLoader stub working with pre-defined test modules.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @package MediaWiki
+ * @author Lupo
+ * @since 1.20
+ */
+header( 'Content-Type: text/javascript; charset=utf-8' );\r
+
+require_once "../../../includes/Xml.php";
+
+$modules = array (
+ 'test.use_missing' => array (
+ 'src' => 'mw.loader.implement("test.use_missing", function () {start(); ok(false, "Module test.use_missing should not run.");}, {}, {});',
+ 'deps' => array ( 'test.missing' )
+ ),
+ 'test.use_missing2' => array (
+ 'src' => 'mw.loader.implement("test.use_missing2", function () {start(); ok(false, "Module test.use_missing2 should not run.");}, {}, {});',
+ 'deps' => array ( 'test.missing2' )
+ )
+);
+
+// Copied from ResourceLoaderContext
+function expandModuleNames( $modules ) {\r
+ $retval = array();\r
+ // For backwards compatibility with an earlier hack, replace ! with .\r
+ $modules = str_replace( '!', '.', $modules );\r
+ $exploded = explode( '|', $modules );\r
+ foreach ( $exploded as $group ) {\r
+ if ( strpos( $group, ',' ) === false ) {\r
+ // This is not a set of modules in foo.bar,baz notation\r
+ // but a single module\r
+ $retval[] = $group;\r
+ } else {\r
+ // This is a set of modules in foo.bar,baz notation\r
+ $pos = strrpos( $group, '.' );\r
+ if ( $pos === false ) {\r
+ // Prefixless modules, i.e. without dots\r
+ $retval = explode( ',', $group );\r
+ } else {\r
+ // We have a prefix and a bunch of suffixes\r
+ $prefix = substr( $group, 0, $pos ); // 'foo'\r
+ $suffixes = explode( ',', substr( $group, $pos + 1 ) ); // array( 'bar', 'baz' )\r
+ foreach ( $suffixes as $suffix ) {\r
+ $retval[] = "$prefix.$suffix";\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return $retval;\r
+}
+
+function addModule ( $moduleName, &$gotten ) {
+ global $modules;
+
+ $result = "";
+ if ( isset( $gotten[$moduleName] ) ) {
+ return $result;
+ }
+ $gotten[$moduleName] = true;
+ if ( isset( $modules[$moduleName] ) ) {
+ $deps = $modules[$moduleName]['deps'];
+ foreach ( $deps as $depName ) {
+ $result .= addModule( $depName, $gotten ) . "\n";
+ }
+ $result .= $modules[$moduleName]['src'] . "\n";
+ } else {
+ $result .= 'mw.loader.state( ' . Xml::encodeJsVar( $moduleName ) . ', "missing" );' . "\n";
+ }
+ return $result . "\n";
+}
+
+$result = "";
+
+if ( isset( $_GET['modules'] ) ) {
+ $toGet = expandModuleNames( $_GET['modules'] );
+ $gotten = array();
+ foreach ( $toGet as $moduleName ) {
+ $result .= addModule( $moduleName, $gotten );
+ }
+}
+
+echo $result;
});
+test( 'mw.loader erroneous indirect dependency', function() {
+ expect( 3 );
+ mw.loader.register( [
+ ['test.module1', '0'],
+ ['test.module2', '0', ['test.module1']],
+ ['test.module3', '0', ['test.module2']]
+ ] );
+ mw.loader.implement( 'test.module1', function() { throw new Error( 'expected' ); }, {}, {} );
+ strictEqual( mw.loader.getState( 'test.module1' ), 'error', 'Expected "error" state for test.module1' );
+ strictEqual( mw.loader.getState( 'test.module2' ), 'error', 'Expected "error" state for test.module2' );
+ strictEqual( mw.loader.getState( 'test.module3' ), 'error', 'Expected "error" state for test.module3' );
+} );
+
+test( 'mw.loader out-of-order implementation', function() {
+ expect( 9 );
+ mw.loader.register( [
+ ['test.module4', '0'],
+ ['test.module5', '0', ['test.module4']],
+ ['test.module6', '0', ['test.module5']]
+ ] );
+ mw.loader.implement( 'test.module4', function() {}, {}, {} );
+ strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+ strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
+ strictEqual( mw.loader.getState( 'test.module6' ), 'registered', 'Expected "registered" state for test.module6' );
+ mw.loader.implement( 'test.module6', function() {}, {}, {} );
+ strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+ strictEqual( mw.loader.getState( 'test.module5' ), 'registered', 'Expected "registered" state for test.module5' );
+ strictEqual( mw.loader.getState( 'test.module6' ), 'loaded', 'Expected "loaded" state for test.module6' );
+ mw.loader.implement( 'test.module5', function() {}, {}, {} );
+ strictEqual( mw.loader.getState( 'test.module4' ), 'ready', 'Expected "ready" state for test.module4' );
+ strictEqual( mw.loader.getState( 'test.module5' ), 'ready', 'Expected "ready" state for test.module5' );
+ strictEqual( mw.loader.getState( 'test.module6' ), 'ready', 'Expected "ready" state for test.module6' );
+} );
+
+test( 'mw.loader missing dependency', function() {
+ expect( 13 );
+ mw.loader.register( [
+ ['test.module7', '0'],
+ ['test.module8', '0', ['test.module7']],
+ ['test.module9', '0', ['test.module8']]
+ ] );
+ mw.loader.implement( 'test.module8', function() {}, {}, {} );
+ strictEqual( mw.loader.getState( 'test.module7' ), 'registered', 'Expected "registered" state for test.module7' );
+ strictEqual( mw.loader.getState( 'test.module8' ), 'loaded', 'Expected "loaded" state for test.module8' );
+ strictEqual( mw.loader.getState( 'test.module9' ), 'registered', 'Expected "registered" state for test.module9' );
+ mw.loader.state( 'test.module7', 'missing' );
+ strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
+ strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
+ strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
+ mw.loader.implement( 'test.module9', function() {}, {}, {} );
+ strictEqual( mw.loader.getState( 'test.module7' ), 'missing', 'Expected "missing" state for test.module7' );
+ strictEqual( mw.loader.getState( 'test.module8' ), 'error', 'Expected "error" state for test.module8' );
+ strictEqual( mw.loader.getState( 'test.module9' ), 'error', 'Expected "error" state for test.module9' );
+ mw.loader.using(
+ ['test.module7'],
+ function() {
+ ok( false, "Success fired despite missing dependency" );
+ ok( true , "QUnit expected() count dummy" );
+ },
+ function( e, dependencies ) {
+ strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
+ deepEqual( dependencies, ['test.module7'], 'Error callback called with module test.module7' );
+ }
+ );
+ mw.loader.using(
+ ['test.module9'],
+ function() {
+ ok( false, "Success fired despite missing dependency" );
+ ok( true , "QUnit expected() count dummy" );
+ },
+ function( e, dependencies ) {
+ strictEqual( $.isArray( dependencies ), true, 'Expected array of dependencies' );
+ dependencies.sort();
+ deepEqual(
+ dependencies,
+ ['test.module7', 'test.module8', 'test.module9'],
+ 'Error callback called with all three modules as dependencies'
+ );
+ }
+ );
+} );
+
+test( 'mw.loader real missing dependency', function() {
+ expect( 6 );
+
+ mw.loader.addSource(
+ 'test',
+ {'loadScript' : QUnit.fixurl( mw.config.get( 'wgScriptPath' ) + '/tests/qunit/data/testloader.php' )}
+ );
+ mw.loader.register( [
+ ['test.missing', '0', [], null, 'test'], ['test.missing2', '0', [], null, 'test'],
+ ['test.use_missing', '0', ['test.missing'], null, 'test'],
+ ['test.use_missing2', '0', ['test.missing2'], null, 'test']
+ ] );
+
+ stop();
+ // Asynch ahead
+
+ mw.loader.load( ['test.use_missing'] );
+
+ function verifyModuleStates() {
+ strictEqual( mw.loader.getState( 'test.missing' ), 'missing', 'Module "test.missing" must have state "missing"' );
+ strictEqual( mw.loader.getState( 'test.missing2' ), 'missing', 'Module "test.missing2" must have state "missing"' );
+ strictEqual( mw.loader.getState( 'test.use_missing' ), 'error', 'Module "test.use_missing" must have state "error"' );
+ strictEqual( mw.loader.getState( 'test.use_missing2' ), 'error', 'Module "test.use_missing2" must have state "error"' );
+ }
+
+ mw.loader.using( ['test.use_missing2'],
+ function() {
+ start();
+ ok( false, "Success called wrongly." );
+ ok( true , "QUnit expected() count dummy" );
+ verifyModuleStates();
+ },
+ function( e, dependencies ) {
+ start();
+ ok( true, "Error handler called correctly." );
+ deepEqual( dependencies, ['test.missing2'], "Dependencies correct." );
+ verifyModuleStates();
+ }
+ );
+} );
+
test( 'mw.loader bug29107' , function () {
expect(2);