text:
<?php
/**
 * Include most things that are needed to make %MediaWiki work.
 *
 * This file is included by WebStart.php and doMaintenance.php so that both
 * web and maintenance scripts share a final set up phase to include necessary
 * files and create global object variables.
 *
 * 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
 */
use MediaWiki\MediaWikiServices;

/**
 * This file is not a valid entry point, perform no further processing unless
 * MEDIAWIKI is defined
 */
if ( !defined( 'MEDIAWIKI' ) ) {
	exit( 1 );
}

$fname = 'Setup.php';
$ps_setup = Profiler::instance()->scopedProfileIn( $fname );

// If any extensions are still queued, force load them
ExtensionRegistry::getInstance()->loadFromQueue();

// Check to see if we are at the file scope
if ( !isset( $wgVersion ) ) {
	echo "Error, Setup.php must be included from the file scope, after DefaultSettings.php\n";
	die( 1 );
}

mb_internal_encoding( 'UTF-8' );

// Set various default paths sensibly...
$ps_default = Profiler::instance()->scopedProfileIn( $fname . '-defaults' );

if ( $wgScript === false ) {
	$wgScript = "$wgScriptPath/index.php";
}
if ( $wgLoadScript === false ) {
	$wgLoadScript = "$wgScriptPath/load.php";
}

if ( $wgArticlePath === false ) {
	if ( $wgUsePathInfo ) {
		$wgArticlePath = "$wgScript/$1";
	} else {
		$wgArticlePath = "$wgScript?title=$1";
	}
}

if ( !empty( $wgActionPaths ) && !isset( $wgActionPaths['view'] ) ) {
	// 'view' is assumed the default action path everywhere in the code
	// but is rarely filled in $wgActionPaths
	$wgActionPaths['view'] = $wgArticlePath;
}

if ( $wgResourceBasePath === null ) {
	$wgResourceBasePath = $wgScriptPath;
}
if ( $wgStylePath === false ) {
	$wgStylePath = "$wgResourceBasePath/skins";
}
if ( $wgLocalStylePath === false ) {
	// Avoid wgResourceBasePath here since that may point to a different domain (e.g. CDN)
	$wgLocalStylePath = "$wgScriptPath/skins";
}
if ( $wgExtensionAssetsPath === false ) {
	$wgExtensionAssetsPath = "$wgResourceBasePath/extensions";
}

if ( $wgLogo === false ) {
	$wgLogo = "$wgResourceBasePath/resources/assets/wiki.png";
}

if ( $wgUploadPath === false ) {
	$wgUploadPath = "$wgScriptPath/images";
}
if ( $wgUploadDirectory === false ) {
	$wgUploadDirectory = "$IP/images";
}
if ( $wgReadOnlyFile === false ) {
	$wgReadOnlyFile = "{$wgUploadDirectory}/lock_yBgMBwiR";
}
if ( $wgFileCacheDirectory === false ) {
	$wgFileCacheDirectory = "{$wgUploadDirectory}/cache";
}
if ( $wgDeletedDirectory === false ) {
	$wgDeletedDirectory = "{$wgUploadDirectory}/deleted";
}

if ( $wgGitInfoCacheDirectory === false && $wgCacheDirectory !== false ) {
	$wgGitInfoCacheDirectory = "{$wgCacheDirectory}/gitinfo";
}

if ( $wgEnableParserCache === false ) {
	$wgParserCacheType = CACHE_NONE;
}

// Fix path to icon images after they were moved in 1.24
if ( $wgRightsIcon ) {
	$wgRightsIcon = str_replace(
		"{$wgStylePath}/common/images/",
		"{$wgResourceBasePath}/resources/assets/licenses/",
		$wgRightsIcon
	);
}

if ( isset( $wgFooterIcons['copyright']['copyright'] )
	&& $wgFooterIcons['copyright']['copyright'] === []
) {
	if ( $wgRightsIcon || $wgRightsText ) {
		$wgFooterIcons['copyright']['copyright'] = [
			'url' => $wgRightsUrl,
			'src' => $wgRightsIcon,
			'alt' => $wgRightsText,
		];
	}
}

if ( isset( $wgFooterIcons['poweredby'] )
	&& isset( $wgFooterIcons['poweredby']['mediawiki'] )
	&& $wgFooterIcons['poweredby']['mediawiki']['src'] === null
) {
	$wgFooterIcons['poweredby']['mediawiki']['src'] =
		"$wgResourceBasePath/resources/assets/poweredby_mediawiki_88x31.png";
	$wgFooterIcons['poweredby']['mediawiki']['srcset'] =
		"$wgResourceBasePath/resources/assets/poweredby_mediawiki_132x47.png 1.5x, " .
		"$wgResourceBasePath/resources/assets/poweredby_mediawiki_176x62.png 2x";
}

/**
 * Unconditional protection for NS_MEDIAWIKI since otherwise it's too easy for a
 * sysadmin to set $wgNamespaceProtection incorrectly and leave the wiki insecure.
 *
 * Note that this is the definition of editinterface and it can be granted to
 * all users if desired.
 */
$wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface';

/**
 * The canonical names of namespaces 6 and 7 are, as of v1.14, "File"
 * and "File_talk".  The old names "Image" and "Image_talk" are
 * retained as aliases for backwards compatibility.
 */
$wgNamespaceAliases['Image'] = NS_FILE;
$wgNamespaceAliases['Image_talk'] = NS_FILE_TALK;

/**
 * Initialise $wgLockManagers to include basic FS version
 */
$wgLockManagers[] = [
	'name' => 'fsLockManager',
	'class' => 'FSLockManager',
	'lockDirectory' => "{$wgUploadDirectory}/lockdir",
];
$wgLockManagers[] = [
	'name' => 'nullLockManager',
	'class' => 'NullLockManager',
];

/**
 * Initialise $wgLocalFileRepo from backwards-compatible settings
 */
if ( !$wgLocalFileRepo ) {
	$wgLocalFileRepo = [
		'class' => 'LocalRepo',
		'name' => 'local',
		'directory' => $wgUploadDirectory,
		'scriptDirUrl' => $wgScriptPath,
		'scriptExtension' => '.php',
		'url' => $wgUploadBaseUrl ? $wgUploadBaseUrl . $wgUploadPath : $wgUploadPath,
		'hashLevels' => $wgHashedUploadDirectory ? 2 : 0,
		'thumbScriptUrl' => $wgThumbnailScriptPath,
		'transformVia404' => !$wgGenerateThumbnailOnParse,
		'deletedDir' => $wgDeletedDirectory,
		'deletedHashLevels' => $wgHashedUploadDirectory ? 3 : 0
	];
}
/**
 * Initialise shared repo from backwards-compatible settings
 */
if ( $wgUseSharedUploads ) {
	if ( $wgSharedUploadDBname ) {
		$wgForeignFileRepos[] = [
			'class' => 'ForeignDBRepo',
			'name' => 'shared',
			'directory' => $wgSharedUploadDirectory,
			'url' => $wgSharedUploadPath,
			'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0,
			'thumbScriptUrl' => $wgSharedThumbnailScriptPath,
			'transformVia404' => !$wgGenerateThumbnailOnParse,
			'dbType' => $wgDBtype,
			'dbServer' => $wgDBserver,
			'dbUser' => $wgDBuser,
			'dbPassword' => $wgDBpassword,
			'dbName' => $wgSharedUploadDBname,
			'dbFlags' => ( $wgDebugDumpSql ? DBO_DEBUG : 0 ) | DBO_DEFAULT,
			'tablePrefix' => $wgSharedUploadDBprefix,
			'hasSharedCache' => $wgCacheSharedUploads,
			'descBaseUrl' => $wgRepositoryBaseUrl,
			'fetchDescription' => $wgFetchCommonsDescriptions,
		];
	} else {
		$wgForeignFileRepos[] = [
			'class' => 'FileRepo',
			'name' => 'shared',
			'directory' => $wgSharedUploadDirectory,
			'url' => $wgSharedUploadPath,
			'hashLevels' => $wgHashedSharedUploadDirectory ? 2 : 0,
			'thumbScriptUrl' => $wgSharedThumbnailScriptPath,
			'transformVia404' => !$wgGenerateThumbnailOnParse,
			'descBaseUrl' => $wgRepositoryBaseUrl,
			'fetchDescription' => $wgFetchCommonsDescriptions,
		];
	}
}
if ( $wgUseInstantCommons ) {
	$wgForeignFileRepos[] = [
		'class' => 'ForeignAPIRepo',
		'name' => 'wikimediacommons',
		'apibase' => 'https://commons.wikimedia.org/w/api.php',
		'url' => 'https://upload.wikimedia.org/wikipedia/commons',
		'thumbUrl' => 'https://upload.wikimedia.org/wikipedia/commons/thumb',
		'hashLevels' => 2,
		'transformVia404' => true,
		'fetchDescription' => true,
		'descriptionCacheExpiry' => 43200,
		'apiThumbCacheExpiry' => 86400,
	];
}
/*
 * Add on default file backend config for file repos.
 * FileBackendGroup will handle initializing the backends.
 */
if ( !isset( $wgLocalFileRepo['backend'] ) ) {
	$wgLocalFileRepo['backend'] = $wgLocalFileRepo['name'] . '-backend';
}
foreach ( $wgForeignFileRepos as &$repo ) {
	if ( !isset( $repo['directory'] ) && $repo['class'] === 'ForeignAPIRepo' ) {
		$repo['directory'] = $wgUploadDirectory; // b/c
	}
	if ( !isset( $repo['backend'] ) ) {
		$repo['backend'] = $repo['name'] . '-backend';
	}
}
unset( $repo ); // no global pollution; destroy reference

$rcMaxAgeDays = $wgRCMaxAge / ( 3600 * 24 );
if ( $wgRCFilterByAge ) {
	// Trim down $wgRCLinkDays so that it only lists links which are valid
	// as determined by $wgRCMaxAge.
	// Note that we allow 1 link higher than the max for things like 56 days but a 60 day link.
	sort( $wgRCLinkDays );

	// @codingStandardsIgnoreStart Generic.CodeAnalysis.ForLoopWithTestFunctionCall.NotAllowed
	for ( $i = 0; $i < count( $wgRCLinkDays ); $i++ ) {
		// @codingStandardsIgnoreEnd
		if ( $wgRCLinkDays[$i] >= $rcMaxAgeDays ) {
			$wgRCLinkDays = array_slice( $wgRCLinkDays, 0, $i + 1, false );
			break;
		}
	}
}
// Ensure that default user options are not invalid, since that breaks Special:Preferences
$wgDefaultUserOptions['rcdays'] = min(
	$wgDefaultUserOptions['rcdays'],
	ceil( $rcMaxAgeDays )
);
$wgDefaultUserOptions['watchlistdays'] = min(
	$wgDefaultUserOptions['watchlistdays'],
	ceil( $rcMaxAgeDays )
);
unset( $rcMaxAgeDays );

if ( $wgSkipSkin ) {
	$wgSkipSkins[] = $wgSkipSkin;
}

$wgSkipSkins[] = 'fallback';
$wgSkipSkins[] = 'apioutput';

if ( $wgLocalInterwiki ) {
	array_unshift( $wgLocalInterwikis, $wgLocalInterwiki );
}

// Set default shared prefix
if ( $wgSharedPrefix === false ) {
	$wgSharedPrefix = $wgDBprefix;
}

// Set default shared schema
if ( $wgSharedSchema === false ) {
	$wgSharedSchema = $wgDBmwschema;
}

if ( !$wgCookiePrefix ) {
	if ( $wgSharedDB && $wgSharedPrefix && in_array( 'user', $wgSharedTables ) ) {
		$wgCookiePrefix = $wgSharedDB . '_' . $wgSharedPrefix;
	} elseif ( $wgSharedDB && in_array( 'user', $wgSharedTables ) ) {
		$wgCookiePrefix = $wgSharedDB;
	} elseif ( $wgDBprefix ) {
		$wgCookiePrefix = $wgDBname . '_' . $wgDBprefix;
	} else {
		$wgCookiePrefix = $wgDBname;
	}
}
$wgCookiePrefix = strtr( $wgCookiePrefix, '=,; +."\'\\[', '__________' );

if ( $wgEnableEmail ) {
	$wgUseEnotif = $wgEnotifUserTalk || $wgEnotifWatchlist;
} else {
	// Disable all other email settings automatically if $wgEnableEmail
	// is set to false. - bug 63678
	$wgAllowHTMLEmail = false;
	$wgEmailAuthentication = false; // do not require auth if you're not sending email anyway
	$wgEnableUserEmail = false;
	$wgEnotifFromEditor = false;
	$wgEnotifImpersonal = false;
	$wgEnotifMaxRecips = 0;
	$wgEnotifMinorEdits = false;
	$wgEnotifRevealEditorAddress = false;
	$wgEnotifUseRealName = false;
	$wgEnotifUserTalk = false;
	$wgEnotifWatchlist = false;
	unset( $wgGroupPermissions['user']['sendemail'] );
	$wgUseEnotif = false;
	$wgUserEmailUseReplyTo = false;
	$wgUsersNotifiedOnAllChanges = [];
}

if ( $wgMetaNamespace === false ) {
	$wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
}

// Default value is 2000 or the suhosin limit if it is between 1 and 2000
if ( $wgResourceLoaderMaxQueryLength === false ) {
	$suhosinMaxValueLength = (int)ini_get( 'suhosin.get.max_value_length' );
	if ( $suhosinMaxValueLength > 0 && $suhosinMaxValueLength < 2000 ) {
		$wgResourceLoaderMaxQueryLength = $suhosinMaxValueLength;
	} else {
		$wgResourceLoaderMaxQueryLength = 2000;
	}
	unset( $suhosinMaxValueLength );
}

// Ensure the minimum chunk size is less than PHP upload limits or the maximum
// upload size.
$wgMinUploadChunkSize = min(
	$wgMinUploadChunkSize,
	UploadBase::getMaxUploadSize( 'file' ),
	UploadBase::getMaxPhpUploadSize(),
	( wfShorthandToInteger(
		ini_get( 'post_max_size' ) ?: ini_get( 'hhvm.server.max_post_size' ),
		PHP_INT_MAX
	) ?: PHP_INT_MAX ) - 1024 // Leave some room for other POST parameters
);

/**
 * Definitions of the NS_ constants are in Defines.php
 * @private
 */
$wgCanonicalNamespaceNames = [
	NS_MEDIA            => 'Media',
	NS_SPECIAL          => 'Special',
	NS_TALK             => 'Talk',
	NS_USER             => 'User',
	NS_USER_TALK        => 'User_talk',
	NS_PROJECT          => 'Project',
	NS_PROJECT_TALK     => 'Project_talk',
	NS_FILE             => 'File',
	NS_FILE_TALK        => 'File_talk',
	NS_MEDIAWIKI        => 'MediaWiki',
	NS_MEDIAWIKI_TALK   => 'MediaWiki_talk',
	NS_TEMPLATE         => 'Template',
	NS_TEMPLATE_TALK    => 'Template_talk',
	NS_HELP             => 'Help',
	NS_HELP_TALK        => 'Help_talk',
	NS_CATEGORY         => 'Category',
	NS_CATEGORY_TALK    => 'Category_talk',
];

/// @todo UGLY UGLY
if ( is_array( $wgExtraNamespaces ) ) {
	$wgCanonicalNamespaceNames = $wgCanonicalNamespaceNames + $wgExtraNamespaces;
}

// These are now the same, always
// To determine the user language, use $wgLang->getCode()
$wgContLanguageCode = $wgLanguageCode;

// Easy to forget to falsify $wgDebugToolbar for static caches.
// If file cache or CDN cache is on, just disable this (DWIMD).
if ( $wgUseFileCache || $wgUseSquid ) {
	$wgDebugToolbar = false;
}

// We always output HTML5 since 1.22, overriding these is no longer supported
// we set them here for extensions that depend on its value.
$wgHtml5 = true;
$wgXhtmlDefaultNamespace = 'http://www.w3.org/1999/xhtml';
$wgJsMimeType = 'text/javascript';

// Blacklisted file extensions shouldn't appear on the "allowed" list
$wgFileExtensions = array_values( array_diff( $wgFileExtensions, $wgFileBlacklist ) );

if ( $wgInvalidateCacheOnLocalSettingsChange ) {
	MediaWiki\suppressWarnings();
	$wgCacheEpoch = max( $wgCacheEpoch, gmdate( 'YmdHis', filemtime( "$IP/LocalSettings.php" ) ) );
	MediaWiki\restoreWarnings();
}

if ( $wgNewUserLog ) {
	// Add a new log type
	$wgLogTypes[] = 'newusers';
	$wgLogNames['newusers'] = 'newuserlogpage';
	$wgLogHeaders['newusers'] = 'newuserlogpagetext';
	$wgLogActionsHandlers['newusers/newusers'] = 'NewUsersLogFormatter';
	$wgLogActionsHandlers['newusers/create'] = 'NewUsersLogFormatter';
	$wgLogActionsHandlers['newusers/create2'] = 'NewUsersLogFormatter';
	$wgLogActionsHandlers['newusers/byemail'] = 'NewUsersLogFormatter';
	$wgLogActionsHandlers['newusers/autocreate'] = 'NewUsersLogFormatter';
}

if ( $wgPageLanguageUseDB ) {
	$wgLogTypes[] = 'pagelang';
	$wgLogActionsHandlers['pagelang/pagelang'] = 'PageLangLogFormatter';
}

if ( $wgCookieSecure === 'detect' ) {
	$wgCookieSecure = ( WebRequest::detectProtocol() === 'https' );
}

if ( $wgProfileOnly ) {
	$wgDebugLogGroups['profileoutput'] = $wgDebugLogFile;
	$wgDebugLogFile = '';
}

// Disable AuthManager API modules if $wgDisableAuthManager
if ( $wgDisableAuthManager ) {
	$wgAPIModules += [
		'clientlogin' => 'ApiDisabled',
		'createaccount' => 'ApiCreateAccount', // Use the non-AuthManager version
		'linkaccount' => 'ApiDisabled',
		'unlinkaccount' => 'ApiDisabled',
		'changeauthenticationdata' => 'ApiDisabled',
		'removeauthenticationdata' => 'ApiDisabled',
		'resetpassword' => 'ApiDisabled',
	];
	$wgAPIMetaModules += [
		'authmanagerinfo' => 'ApiQueryDisabled',
	];
}

// Backwards compatibility with old password limits
if ( $wgMinimalPasswordLength !== false ) {
	$wgPasswordPolicy['policies']['default']['MinimalPasswordLength'] = $wgMinimalPasswordLength;
}

if ( $wgMaximalPasswordLength !== false ) {
	$wgPasswordPolicy['policies']['default']['MaximalPasswordLength'] = $wgMaximalPasswordLength;
}

// Backwards compatibility warning
if ( !$wgSessionsInObjectCache && !$wgSessionsInMemcached ) {
	wfDeprecated( '$wgSessionsInObjectCache = false', '1.27' );
	if ( $wgSessionHandler ) {
		wfDeprecated( '$wgSessionsHandler', '1.27' );
	}
	$cacheType = get_class( ObjectCache::getInstance( $wgSessionCacheType ) );
	wfDebugLog(
		'caches',
		"Session data will be stored in \"$cacheType\" cache with " .
			"expiry $wgObjectCacheSessionExpiry seconds"
	);
}
$wgSessionsInObjectCache = true;

if ( $wgPHPSessionHandling !== 'enable' &&
	$wgPHPSessionHandling !== 'warn' &&
	$wgPHPSessionHandling !== 'disable'
) {
	$wgPHPSessionHandling = 'warn';
}
if ( defined( 'MW_NO_SESSION' ) ) {
	// If the entry point wants no session, force 'disable' here unless they
	// specifically set it to the (undocumented) 'warn'.
	$wgPHPSessionHandling = MW_NO_SESSION === 'warn' ? 'warn' : 'disable';
}

Profiler::instance()->scopedProfileOut( $ps_default );

// Disable MWDebug for command line mode, this prevents MWDebug from eating up
// all the memory from logging SQL queries on maintenance scripts
global $wgCommandLineMode;
if ( $wgDebugToolbar && !$wgCommandLineMode ) {
	MWDebug::init();
}

if ( !class_exists( 'AutoLoader' ) ) {
	require_once "$IP/includes/AutoLoader.php";
}

// Reset the global service locator, so any services that have already been created will be
// re-created while taking into account any custom settings and extensions.
MediaWikiServices::resetGlobalInstance( new GlobalVarConfig(), 'quick' );

// Define a constant that indicates that the bootstrapping of the service locator
// is complete.
define( 'MW_SERVICE_BOOTSTRAP_COMPLETE', 1 );

// Install a header callback to prevent caching of responses with cookies (T127993)
if ( !$wgCommandLineMode ) {
	header_register_callback( function () {
		$headers = [];
		foreach ( headers_list() as $header ) {
			list( $name, $value ) = explode( ':', $header, 2 );
			$headers[strtolower( trim( $name ) )][] = trim( $value );
		}

		if ( isset( $headers['set-cookie'] ) ) {
			$cacheControl = isset( $headers['cache-control'] )
				? implode( ', ', $headers['cache-control'] )
				: '';

			if ( !preg_match( '/(?:^|,)\s*(?:private|no-cache|no-store)\s*(?:$|,)/i', $cacheControl ) ) {
				header( 'Expires: Thu, 01 Jan 1970 00:00:00 GMT' );
				header( 'Cache-Control: private, max-age=0, s-maxage=0' );
				MediaWiki\Logger\LoggerFactory::getInstance( 'cache-cookies' )->warning(
					'Cookies set on {url} with Cache-Control "{cache-control}"', [
						'url' => WebRequest::getGlobalRequestURL(),
						'cookies' => $headers['set-cookie'],
						'cache-control' => $cacheControl ?: '<not set>',
					]
				);
			}
		}
	} );
}

MWExceptionHandler::installHandler();

require_once "$IP/includes/compat/normal/UtfNormalUtil.php";

$ps_validation = Profiler::instance()->scopedProfileIn( $fname . '-validation' );

// T48998: Bail out early if $wgArticlePath is non-absolute
foreach ( [ 'wgArticlePath', 'wgVariantArticlePath' ] as $varName ) {
	if ( $$varName && !preg_match( '/^(https?:\/\/|\/)/', $$varName ) ) {
		throw new FatalError(
			"If you use a relative URL for \$$varName, it must start " .
			'with a slash (/).

See ' .
			"" .
			"https://www.mediawiki.org/wiki/Manual:\$$varName."
		);
	}
}

Profiler::instance()->scopedProfileOut( $ps_validation );

$ps_default2 = Profiler::instance()->scopedProfileIn( $fname . '-defaults2' );

if ( $wgCanonicalServer === false ) {
	$wgCanonicalServer = wfExpandUrl( $wgServer, PROTO_HTTP );
}

// Set server name
$serverParts = wfParseUrl( $wgCanonicalServer );
if ( $wgServerName !== false ) {
	wfWarn( '$wgServerName should be derived from $wgCanonicalServer, '
		. 'not customized. Overwriting $wgServerName.' );
}
$wgServerName = $serverParts['host'];
unset( $serverParts );

// Set defaults for configuration variables
// that are derived from the server name by default
// Note: $wgEmergencyContact and $wgPasswordSender may be false or empty string (T104142)
if ( !$wgEmergencyContact ) {
	$wgEmergencyContact = 'wikiadmin@' . $wgServerName;
}
if ( !$wgPasswordSender ) {
	$wgPasswordSender = 'apache@' . $wgServerName;
}
if ( !$wgNoReplyAddress ) {
	$wgNoReplyAddress = $wgPasswordSender;
}

if ( $wgSecureLogin && substr( $wgServer, 0, 2 ) !== '//' ) {
	$wgSecureLogin = false;
	wfWarn( 'Secure login was enabled on a server that only supports '
		. 'HTTP or HTTPS. Disabling secure login.' );
}

$wgVirtualRestConfig['global']['domain'] = $wgCanonicalServer;

// Now that GlobalFunctions is loaded, set defaults that depend on it.
if ( $wgTmpDirectory === false ) {
	$wgTmpDirectory = wfTempDir();
}

// We don't use counters anymore. Left here for extensions still
// expecting this to exist. Should be removed sometime 1.26 or later.
if ( !isset( $wgDisableCounters ) ) {
	$wgDisableCounters = true;
}

if ( $wgMainWANCache === false ) {
	// Setup a WAN cache from $wgMainCacheType with no relayer.
	// Sites using multiple datacenters can configure a relayer.
	$wgMainWANCache = 'mediawiki-main-default';
	$wgWANObjectCaches[$wgMainWANCache] = [
		'class'    => 'WANObjectCache',
		'cacheId'  => $wgMainCacheType,
		'channels' => [ 'purge' => 'wancache-main-default-purge' ]
	];
}

Profiler::instance()->scopedProfileOut( $ps_default2 );

$ps_misc = Profiler::instance()->scopedProfileIn( $fname . '-misc1' );

// Raise the memory limit if it's too low
wfMemoryLimit();

/**
 * Set up the timezone, suppressing the pseudo-security warning in PHP 5.1+
 * that happens whenever you use a date function without the timezone being
 * explicitly set. Inspired by phpMyAdmin's treatment of the problem.
 */
if ( is_null( $wgLocaltimezone ) ) {
	MediaWiki\suppressWarnings();
	$wgLocaltimezone = date_default_timezone_get();
	MediaWiki\restoreWarnings();
}

date_default_timezone_set( $wgLocaltimezone );
if ( is_null( $wgLocalTZoffset ) ) {
	$wgLocalTZoffset = date( 'Z' ) / 60;
}

if ( !$wgDBerrorLogTZ ) {
	$wgDBerrorLogTZ = $wgLocaltimezone;
}

// initialize the request object in $wgRequest
$wgRequest = RequestContext::getMain()->getRequest(); // BackCompat

// Useful debug output
if ( $wgCommandLineMode ) {
	wfDebug( "\n\nStart command line script $self\n" );
} else {
	$debug = "\n\nStart request {$wgRequest->getMethod()} {$wgRequest->getRequestURL()}\n";

	if ( $wgDebugPrintHttpHeaders ) {
		$debug .= "HTTP HEADERS:\n";

		foreach ( $wgRequest->getAllHeaders() as $name => $value ) {
			$debug .= "$name: $value\n";
		}
	}
	wfDebug( $debug );
}

Profiler::instance()->scopedProfileOut( $ps_misc );
$ps_memcached = Profiler::instance()->scopedProfileIn( $fname . '-memcached' );

$wgMemc = wfGetMainCache();
$messageMemc = wfGetMessageCacheStorage();
$parserMemc = wfGetParserCacheStorage();

wfDebugLog( 'caches',
	'cluster: ' . get_class( $wgMemc ) .
	', WAN: ' . $wgMainWANCache .
	', stash: ' . $wgMainStash .
	', message: ' . get_class( $messageMemc ) .
	', parser: ' . get_class( $parserMemc ) );

Profiler::instance()->scopedProfileOut( $ps_memcached );

// Most of the config is out, some might want to run hooks here.
Hooks::run( 'SetupAfterCache' );

$ps_globals = Profiler::instance()->scopedProfileIn( $fname . '-globals' );

/**
 * @var Language $wgContLang
 */
$wgContLang = Language::factory( $wgLanguageCode );
$wgContLang->initEncoding();
$wgContLang->initContLang();

// Now that variant lists may be available...
$wgRequest->interpolateTitle();

if ( !is_object( $wgAuth ) ) {
	$wgAuth = $wgDisableAuthManager ? new AuthPlugin : new MediaWiki\Auth\AuthManagerAuthPlugin;
	Hooks::run( 'AuthPluginSetup', [ &$wgAuth ] );
}
if ( !$wgDisableAuthManager &&
	$wgAuth && !$wgAuth instanceof MediaWiki\Auth\AuthManagerAuthPlugin
) {
	MediaWiki\Auth\AuthManager::singleton()->forcePrimaryAuthenticationProviders( [
		new MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider( [
			'authoritative' => false,
		] ),
		new MediaWiki\Auth\AuthPluginPrimaryAuthenticationProvider( $wgAuth ),
		new MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider( [
			'authoritative' => true,
		] ),
	], '$wgAuth is ' . get_class( $wgAuth ) );
}

// Set up the session
$ps_session = Profiler::instance()->scopedProfileIn( $fname . '-session' );
/**
 * @var MediaWiki\Session\SessionId|null $wgInitialSessionId The persistent
 * session ID (if any) loaded at startup
 */
$wgInitialSessionId = null;
if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
	// If session.auto_start is there, we can't touch session name
	if ( $wgPHPSessionHandling !== 'disable' && !wfIniGetBool( 'session.auto_start' ) ) {
		session_name( $wgSessionName ? $wgSessionName : $wgCookiePrefix . '_session' );
	}

	// Create the SessionManager singleton and set up our session handler,
	// unless we're specifically asked not to.
	if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) {
		MediaWiki\Session\PHPSessionHandler::install(
			MediaWiki\Session\SessionManager::singleton()
		);
	}

	// Initialize the session
	try {
		$session = MediaWiki\Session\SessionManager::getGlobalSession();
	} catch ( OverflowException $ex ) {
		if ( isset( $ex->sessionInfos ) && count( $ex->sessionInfos ) >= 2 ) {
			// The exception is because the request had multiple possible
			// sessions tied for top priority. Report this to the user.
			$list = [];
			foreach ( $ex->sessionInfos as $info ) {
				$list[] = $info->getProvider()->describe( $wgContLang );
			}
			$list = $wgContLang->listToText( $list );
			throw new HttpError( 400,
				Message::newFromKey( 'sessionmanager-tie', $list )->inLanguage( $wgContLang )->plain()
			);
		}

		// Not the one we want, rethrow
		throw $ex;
	}

	if ( $session->isPersistent() ) {
		$wgInitialSessionId = $session->getSessionId();
	}

	$session->renew();
	if ( MediaWiki\Session\PHPSessionHandler::isEnabled() &&
		( $session->isPersistent() || $session->shouldRememberUser() )
	) {
		// Start the PHP-session for backwards compatibility
		session_id( $session->getId() );
		MediaWiki\quietCall( 'session_start' );
	}

	unset( $session );
} else {
	// Even if we didn't set up a global Session, still install our session
	// handler unless specifically requested not to.
	if ( !defined( 'MW_NO_SESSION_HANDLER' ) ) {
		MediaWiki\Session\PHPSessionHandler::install(
			MediaWiki\Session\SessionManager::singleton()
		);
	}
}
Profiler::instance()->scopedProfileOut( $ps_session );

/**
 * @var User $wgUser
 */
$wgUser = RequestContext::getMain()->getUser(); // BackCompat

/**
 * @var Language $wgLang
 */
$wgLang = new StubUserLang;

/**
 * @var OutputPage $wgOut
 */
$wgOut = RequestContext::getMain()->getOutput(); // BackCompat

/**
 * @var Parser $wgParser
 */
$wgParser = new StubObject( 'wgParser', $wgParserConf['class'], [ $wgParserConf ] );

/**
 * @var Title $wgTitle
 */
$wgTitle = null;

Profiler::instance()->scopedProfileOut( $ps_globals );
$ps_extensions = Profiler::instance()->scopedProfileIn( $fname . '-extensions' );

// Extension setup functions
// Entries should be added to this variable during the inclusion
// of the extension file. This allows the extension to perform
// any necessary initialisation in the fully initialised environment
foreach ( $wgExtensionFunctions as $func ) {
	// Allow closures in PHP 5.3+
	if ( is_object( $func ) && $func instanceof Closure ) {
		$profName = $fname . '-extensions-closure';
	} elseif ( is_array( $func ) ) {
		if ( is_object( $func[0] ) ) {
			$profName = $fname . '-extensions-' . get_class( $func[0] ) . '::' . $func[1];
		} else {
			$profName = $fname . '-extensions-' . implode( '::', $func );
		}
	} else {
		$profName = $fname . '-extensions-' . strval( $func );
	}

	$ps_ext_func = Profiler::instance()->scopedProfileIn( $profName );
	call_user_func( $func );
	Profiler::instance()->scopedProfileOut( $ps_ext_func );
}

// If the session user has a 0 id but a valid name, that means we need to
// autocreate it.
if ( !defined( 'MW_NO_SESSION' ) && !$wgCommandLineMode ) {
	$sessionUser = MediaWiki\Session\SessionManager::getGlobalSession()->getUser();
	if ( $sessionUser->getId() === 0 && User::isValidUserName( $sessionUser->getName() ) ) {
		$ps_autocreate = Profiler::instance()->scopedProfileIn( $fname . '-autocreate' );
		if ( $wgDisableAuthManager ) {
			$res = MediaWiki\Session\SessionManager::autoCreateUser( $sessionUser );
		} else {
			$res = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser(
				$sessionUser,
				MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_SESSION,
				true
			);
		}
		Profiler::instance()->scopedProfileOut( $ps_autocreate );
		\MediaWiki\Logger\LoggerFactory::getInstance( 'authmanager' )->info( 'Autocreation attempt', [
			'event' => 'autocreate',
			'status' => $res,
		] );
		unset( $res );
	}
	unset( $sessionUser );
}

wfDebug( "Fully initialised\n" );
$wgFullyInitialised = true;

Profiler::instance()->scopedProfileOut( $ps_extensions );
Profiler::instance()->scopedProfileOut( $ps_setup );


text:
Easy file upload and validations for Laravel.

### Installation

```sh
$ composer require "escapework/laravel-uploader:0.1.*"
```

redpajama_set_name: RedPajamaGithub


text:
package i5.las2peer.services.cdService.data.util.table;

import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;

import i5.las2peer.services.cdService.data.util.table.TableInterface;
import i5.las2peer.services.cdService.data.util.table.TableRow;

/**
 * A Table consisting of {@link TableRow}s. A {@link TablePrinter} can write the
 * table into a file.
 */
public class Table {

	private List<TableRow> rows;

	public Table() {
		rows = new ArrayList<>();
	}

	public List<TableRow> getTableRows() {
		return rows;
	}

	///// add /////

	/**
	 * Add a {@link TableRow} to the end of the Table
	 *
	 * @param tableRow
	 *            the TableRow
	 */
	public void add(TableRow tableRow) {
		rows.add(tableRow);
	}

	/**
	 * Add a object that implements the {@link TableInterface} to the end of the
	 * Table.
	 *
	 * @param tableRow
	 *            the TableRow
	 */
	public void add(TableInterface row) {
		add(row.toTableLine());
	}

	/**
	 * Creates a new TableRow consisting of one column of the given string
	 *
	 * @param tableRow
	 *            the TableRow
	 */
	public void add(String string) {
		rows.add(new TableRow().add(string));
	}

	///// append /////

	public void append(int rowId, TableRow tableRow) {

		if (rowId < 0 || rowId > rows())
			throw new IllegalArgumentException("invalid row id");

		getTableRows().get(rowId).add(tableRow);
	}

	public void append(int rowId, TableInterface tableInterface) {

		if (rowId < 0 || rowId > rows())
			throw new IllegalArgumentException("invalid row id");

		getTableRows().get(rowId).add(tableInterface);
	}

	public void append(int rowId, String row) {

		if (rowId < 0 || rowId > rows())
			throw new IllegalArgumentException("invalid row id");

		getTableRows().get(rowId).add(row);
	}

	///// size /////

	public int rows() {
		if (rows == null)
			return 0;
		return rows.size();
	}

	public int columns() {
		if (rows == null || rows.size() == 0)
			return 0;
		return rows.get(0).size();
	}

	///// format /////

	public void format(Formatter formatter) {

		for (TableRow row : rows) {
			row.format(formatter);
		}
	}

	///// print /////

	public String print() {

		StringJoiner table = new StringJoiner("\n");
		for (TableRow row : rows) {
			table.add(row.print());
		}
		return table.toString();
	}
}


text:
<?php
chdir(__DIR__);

$returnStatus = null;
passthru('composer install --optimize-autoloader', $returnStatus);
if ($returnStatus !== 0) {
    exit(1);
}

$phpcs = './vendor/bin/phpcs --standard=' . __DIR__ . '/vendor/traderinteractive/coding-standard/DWS -n';
$phpcs .= ' src tests *.php';
passthru($phpcs, $returnStatus);
if ($returnStatus !== 0) {
    exit(1);
}

passthru('./vendor/bin/phpunit --coverage-clover clover.xml --coverage-html coverage tests', $returnStatus);
if ($returnStatus !== 0) {
    exit(1);
}

$xml = new SimpleXMLElement(file_get_contents('clover.xml'));
foreach ($xml->xpath('//file/metrics') as $metric) {
    if ((int)$metric['elements'] !== (int)$metric['coveredelements']) {
        file_put_contents('php://stderr', "Code coverage was NOT 100% but we need to get there ASAP\n");
        exit(0);
    }
}

echo "Code coverage was 100%\n";


text:
/**
 * @author Mariusz Rymarczyk
 * @license MIT
 * @version 0.1
 */

var Countdown = (function () {

    'use strict';

    /**
     * Adding preceding zeros
     * @param val int
     * @param n int ciphers in number
     */
    var fullFormat = function (val, n) {

        var len = ('' + val).length,
            zeros = n - len,
            tmp = '',
            i = 0;

        for ( ; i < zeros ; i++) {
            tmp += '0';
        }

        return tmp + val;
    };

    var Countdown = function (settings) {

        /* setInterval id */
        this._timerId = 0;
        /* days left */
        this._days = 0;
        /* hours left */
        this._hours = 0;
        /* minutes left */
        this._minutes = 0;
        /* seconds left */
        this._seconds = 0;
        /* miliseconds left */
        this._miliseconds = 0;
        /* start date Object */
        this._startDate = null;
        /* end date Object */
        this._endDate = null;
        /* how the date will be shown on page */
        this._pattern = '%D days %HH hours %MM minutes %SS seconds %UU miliseconds';
        /* mode of countdown: 'date' or 'timer' */
        this._mode = '';
        /* element where remaining time will be placed */
        this._node = null;
        /* in seconds or miliseconds, depends on settings */
        this._timeLeft = null;
        /* time limit for timer mode */
        this._limit = 0;
        /* step of interval, the more the better */
        this._refreshRate = 50;
        /* speed ratio*/
        this._speed = 1;
        /* state */
        this._state = 'init';
        /* date before changing tab */
        this._before = null;
        /* initial settings */
        this._settings = settings;
        /* loop flag */
        this._stopLoop = false;

        /* private */
        var /* iteration var */
            i = 0,
            /* required settings */
            required;

        required = settings.mode === 'date' ? ['mode', 'endDate'] : ['mode', 'limit'];

        /* check required fields */
        for ( ; i < required.length ; i++) {

            if (!(required[i] in settings)) {

                console.error(required[i] + ' is required');
                return false;
            }
        }

        /* initialization */

        this._mode = settings.mode;

        this._speed = settings.speed || 1;

        this._refreshRate = ((settings.refreshRate && settings.refreshRate < 10) ? 10 : settings.refreshRate) || 100;

        this._pattern = settings.pattern || this._pattern;

        this._limit = settings.limit;

        this._endDate = settings.endDate;

        this._node = document.getElementById(settings.nodeId);

    };

    Countdown.prototype = {

        getTimerId : function () {
            return this._timerId;
        },

        getTime : function () {

            return {
                days : this._days,
                hours : this._hours,
                minutes : this._minutes,
                seconds : this._seconds,
                miliseconds : this._miliseconds
            };

        },

        getState : function () {
            return this._state;
        },

        setSpeed : function (val) {
            this._speed = val;
        },

        /**
         * Executed by setInterval
         * @param timeStep number not required
         */
        _tick : function (timeStep) {

            var elapsedTime = +new Date() - this._before;

            this._timeLeft -= elapsedTime * this._speed;

            if(this._timeLeft <= 0) {
                this._end();
                return;
            }

            this._count();
            this._show();

            this._settings.onTick && this._settings.onTick(this);

            this._before = new Date();
        },

        /* start counting */
        start : function () {

            if (this._mode === 'date') {

                this._startDate = this._settings.startDate || new Date();

                this._timeLeft = this._endDate - this._startDate;

            } else if (this._mode === 'timer') {

                if (this._timeLeft === null) {
                    this._timeLeft = this._limit;
                }
            }

            this._before = new Date();
            this._state = 'started';

            var self = this;

            self._stopLoop = false;

            if(this._state === 'init'){
               this._tick(0);
            }

            this.prev = +new Date();

            var loop = function (refreshRate) {

                setTimeout(function () {
                    if (!self._stopLoop) {
                        self._tick(refreshRate);
                        loop(refreshRate);
                    }
                }, refreshRate);
            };

            loop(this._refreshRate);
            this._tick(this._refreshRate);

            this._settings.onStart && this._settings.onStart(this);

            if(this._timeLeft <= 0){
                this._end();
            }
        },

        _count : function () {

            this._miliseconds = (this._timeLeft%1000)/10 | 0;
            this._seconds = ((this._timeLeft/1000) | 0) % 60;
            this._minutes = ((this._timeLeft/60000) | 0) % 60;
            this._hours = ((this._timeLeft/3600000) | 0) % 24;
            this._days = (this._timeLeft/86400000) | 0;

        },

        _show : function () {

            if (!this._node) { return; }

            var content = this._pattern;

            content = content.replace(/%HH/g, fullFormat(this._hours, 2));
            content = content.replace(/%MM/g, fullFormat(this._minutes, 2));
            content = content.replace(/%SS/g, fullFormat(this._seconds, 2));
            content = content.replace(/%UU/g, fullFormat(this._miliseconds, 2));

            content = content.replace(/%D/g, this._days);
            content = content.replace(/%H/g, this._hours);
            content = content.replace(/%M/g, this._minutes);
            content = content.replace(/%S/g, this._seconds);
            content = content.replace(/%U/g, this._miliseconds);

            this._node.innerHTML = content;
        },

        /* stop counting */
        stop : function () {
            this._stopLoop = true;
            this._state = 'stopped';
            this._settings.onStop && this._settings.onStop(this);
        },

        /* end */
        _end : function () {
            this._days = this._hours = this._minutes = this._seconds = this._miliseconds = 0;
            this._show();
            this._stopLoop = true;
            this._state = 'ended';
            this._settings.onEnd && this._settings.onEnd(this);
        },

        /* reset exists only for timer mode, reset to original time */
        reset : function () {

            if(this._mode === 'date'){ return; }

            this._state = null;
            this._timeLeft = this._limit;
            this._count();
            this._show();
            this.stop();
            this._settings.onReset && this._settings.onReset(this);
        }
    }

    return function (settings) {
        return new Countdown(settings);
    };

})();


text:
MQRedisSessionStorage
================

Zend Framework Module for storing sessions in Redis.

## Features
- Redis SessionSaveHandler support
- Uses Zend\Cache\StorageFactory
- Easy session configuration

## Setup

  1. Run `php composer.phar require milqmedia/mq-redis-session:dev-master`
  2. Add `MQRedisSessionStorage` to the enabled modules list
  3. Copy `vendor/milqmedia/mq-redis-session/config/redissession.global.php.dist` to `config/autoload/redissession.global.php`
  4. Configure the session options in `config/autoload/redissession.global.php`
  5. Session storage will be set by default. For more control set "set_storage_on_boot" to false in your config file and add the lines below in your project's main module or elsewhere:

    ```php
    $redisStorage = $sm->get('MQRedisSessionStorage\Storage\RedisStorage');
    $redisStorage->setSessionStorage();
    ```


text:
const CaseConverterUtils = require('../../utils/CaseConverterUtils');
const fs = require('fs-extra');
const path = require('path');
const PATHS = require('../../constants/paths');
const GRAMMAR_CONSTANTS = require('../../constants/grammars');
const shorthandIdentToLongHandPropertyMap = require('../../constants/shorthandIdentToLonghandPropertyMap.json');

// any nearley builtin grammars that we want to include
const BUILTIN_GRAMMARS = ['whitespace'];
const LEXER_HEADING = '@{%\n  const lexer = require("../../../constants/genericLexer");\n%}\n\n@lexer lexer\n';

/**
 * Class to format a JSON Grammar into an Nearley Grammar
 * @type {NearleyGrammarFormatter}
 */
module.exports = class NearleyGrammarFormatter {
  /**
   * Given a JSON grammar format it into an Nearley Grammar string. This function, recursively resolves grammar
   * rules defined in the given json grammar. Any intermediate grammar rules are prefixed with the file name in order
   * to avoid rule name collisions between recursively resolved grammar rules.
   *

   * @see {@link https://github.com/Hardmath123/nearley | Nearley Readme} for more information on
   * Nearley Syntax.
   *
   * @param {Array} jsonGrammar - json structure representing a grammar
   * @param {string} grammarName - the name of the property being converted to nearley form. For example, "rgba()"
   * @returns {string} - the formatted Ohm Grammar string
   */
  static format(jsonGrammar, grammarName) {
    NearleyGrammarFormatter._isGrammarValid(jsonGrammar);

    // Create a 2d array from a grammar name to its json grammar. All of these grammars need to be recursively resolved.
    // i.e. [["color", [<jsonGrammarForColor>]], "z-index", [<jsonGrammarForZIndex>]]
    // Then get the file name for each grammar that needs to be pulled into this grammar. Grab the files for those
    // jsonGrammars and pull in the rule definitions in those jsonGrammars.
    const recursivelyResolvedGrammars = NearleyGrammarFormatter
      ._getGrammarsToResolve(jsonGrammar)
      .map(fileToResolve => [
        fileToResolve,
        fs.readJsonSync(path.join(PATHS.GENERATED_JSON_GRAMMAR_PATH, `${fileToResolve}.json`)),
      ])
      .filter(([, json]) => NearleyGrammarFormatter._isGrammarValid(json))
      .map(([grammarName, jsonGrammar]) => (
        [grammarName, NearleyGrammarFormatter._prefixIntermediateGrammarRules(grammarName, jsonGrammar)]
      ))
      .map(([grammarName, json]) => json
        .filter(grammarPair => grammarPair.length === 2) // filter out any jsonGrammars that need resolution
        .map(([ruleName, ruleBody]) => (
          ruleName === GRAMMAR_CONSTANTS.BASE_GRAMMAR_RULE_NAME
            ? [CaseConverterUtils.formalSyntaxIdentToNearleyIdent(grammarName), ruleBody]
            : [ruleName, ruleBody]
        )));
    const [[, baseValue], ...otherRules] = NearleyGrammarFormatter
      ._prefixIntermediateGrammarRules(grammarName, jsonGrammar);
    // the base key for this grammar should be mapped to Base, then concat the rest of the rules and
    // format them into nearley syntax. i.e <ruleName> -> <ruleBody>.
    const nearleyGrammarBody = [[GRAMMAR_CONSTANTS.BASE_GRAMMAR_RULE_NAME, baseValue]]
      .concat(otherRules.filter(rule => rule.length === 2)) // add any rules that don't need to be resolved
      .concat(...recursivelyResolvedGrammars) // add all the rules we resolved
      .map(([ruleName, ruleBody]) => {
        const ruleBodyString = NearleyGrammarFormatter._formatJsonRuleBody(ruleBody);
        const postProcessorString = this._getPostProcessorString(grammarName, ruleName);

        return postProcessorString
          ? `${ruleName} -> ${ruleBodyString} ${postProcessorString}`
          : `${ruleName} -> ${ruleBodyString}`;
      })
      .join('\n');
    const builtinGrammarsHeader = BUILTIN_GRAMMARS
      .map(grammarName => `@builtin "${grammarName}.${GRAMMAR_CONSTANTS.GRAMMAR_FILE_EXTENSION}"`)
      .join('\n');

    return `${builtinGrammarsHeader}\n${LEXER_HEADING}\n\n${nearleyGrammarBody}`;
  }

  /**
   * Generate a postprocessing string for a given ruleName in the context of grammarName. This postprocessing string
   * is used in a nearley grammar to run code after a specific rule is parsed. We only need to create postprocessing
   * strings for longhand properties we intend to expand from a shorthand prop. All other properties will not have a
   * postprocessing string.
   *
   * @param {string} grammarName - the name of the grammar to generate the post processing string for. For example,
   *                               "border".
   * @param {string} ruleName - the rule name to get the postprocessing string for. For example, "Color".
   * @returns {String} - a string containing the postprocessing function for the given ruleName or an empty string if
   *                     no postprocessing is required
   * @private
   */
  static _getPostProcessorString(grammarName, ruleName) {
    // if its not a shorthand property we don't support, we don't need postprocessing, since we only use the grammar
    // for property validation
    if (!shorthandIdentToLongHandPropertyMap[grammarName]
      || Array.isArray(shorthandIdentToLongHandPropertyMap[grammarName])) {
      return '';
    }

    return Object.keys(shorthandIdentToLongHandPropertyMap[grammarName])
      .concat(GRAMMAR_CONSTANTS.BASE_GRAMMAR_RULE_NAME)
      .includes(ruleName)
      ? `{% function (data,location) { return { name: '${ruleName}', values: data.filter(Boolean), location }; } %}`
      : '';
  }

  /**
   * Given a json grammar recursively finds all additional jsonGrammars that the grammar depends on. Returns a set
   * of unique file names indicating which jsonGrammars need to be resolved.
   *
   * @param {Array} jsonGrammar - a json structure representing a grammar
   * @param {Array} [resolved=[]] - cached array of grammar names that have already been resolved. Caller does not
   *                                need to use this param, since it only used for recursive grammars.
   * @returns {Array} - a set of unique file names indicating which json grammars need to resolved.
   * @private
   */
  static _getGrammarsToResolve(jsonGrammar, resolved = []) {
    const resolutions = jsonGrammar
      .filter(grammarLine => grammarLine.length === 1)
      .map(([grammarName]) => GRAMMAR_CONSTANTS.R_GRAMMAR_IDENT.exec(grammarName)[1])
      .filter(grammarName => !resolved.includes(grammarName));

    if (resolutions.length === 0) {
      return [];
    }

    return [...new Set(resolutions.concat(
      ...resolutions
        .map(file => fs.readJsonSync(path.join(PATHS.GENERATED_JSON_GRAMMAR_PATH, `${file}.json`)))
        .map(grammar => NearleyGrammarFormatter._getGrammarsToResolve(grammar, resolved.concat(resolutions)))))];
  }

  /**
   * Given a grammarName and a json grammar, prefixes all the intermediate rule names with the grammar name.
   * This is necessary in order to prevent rule name conflicts when recursively resolving grammars.
   *

   * For example, two grammars 'a' and 'b' may contain a rule named 'foo'. If another grammar uses both 'a' and 'b'
   * we need to differentiate between the rule 'foo' defined in both 'a' and 'b'. Thus we prefix 'foo' for both grammars
   * and rename the rules 'a_foo' and 'b_foo'.
   *
   * @param {string} grammarName - the name of the given json grammar. This should be a camelCase name.
   * @param {Array} jsonGrammar - the json grammar to be prefixed
   * @returns {Array} - the prefixed json grammar
   * @private
   */
  static _prefixIntermediateGrammarRules(grammarName, jsonGrammar) {
    // prefix all rules that we don't need to recursively resolve and are not base rules
    const ruleNamesToPrefix = jsonGrammar
      .filter(rule => rule.length === 2)
      .filter(([ruleName]) => ruleName !== GRAMMAR_CONSTANTS.BASE_GRAMMAR_RULE_NAME)
      .map(([ruleName]) => (
        `(?:[^a-z"](${ruleName})$|^(${ruleName})[^a-z"]|^(${ruleName})$|[^a-z"](${ruleName})[^a-z"])`
      ));

    // iterate through all the rules and replace rule name/rule body with prefixed rule names
    if (ruleNamesToPrefix.length) {
      const ruleNamesToPrefixRegex = new RegExp(`${ruleNamesToPrefix.join('|')}`, 'g');

      return jsonGrammar
        .filter(rule => rule.length === 2)
        .map(rule => rule.map(rulePart => rulePart
          .split(' ')
          .map(ruleExpression => ruleExpression
            .replace(ruleNamesToPrefixRegex, (completeMatch, ...ruleNameMatches) => {
              const ruleName = ruleNameMatches.find(Boolean);

              return completeMatch
                .replace(ruleName, NearleyGrammarFormatter._prefixRuleName(grammarName, ruleName));
            }))
          .join(' ')));
    }

    return jsonGrammar;
  }

  /**
   * Prefixes the given rule name with the grammar name.
   * @param {string} grammarName - the grammar name
   * @param {string} ruleName - the rule name
   * @returns {string} - the prefixed rule name
   * @private
   */
  static _prefixRuleName(grammarName, ruleName) {
    return `${CaseConverterUtils.formalSyntaxIdentToNearleyIdent(grammarName)}_${ruleName}`;
  }

  /**
   * Formats the given rule body into a string that is compatible with Nearley.
   *
   * @param {string} ruleBody - the JSON grammar body
   * @returns {string} - the formatted rule body
   * @private
   */
  static _formatJsonRuleBody(ruleBody) {
    return ruleBody.replace(GRAMMAR_CONSTANTS.R_GRAMMAR_IDENT_GLOBAL, (fullMatch, innerIdent, identName, parens) => {
      const nearleyIdent = CaseConverterUtils.formalSyntaxIdentToNearleyIdent(identName);

      return `${nearleyIdent}${parens ? 'Func' : ''}`;
    });
  }

  /**
   * Given a grammar json, checks if the grammar is valid.
   *
   * @param {Object} jsonGrammar - a json structure representing a grammar.
   * @returns {boolean} - returns true if given grammar is valid, else throws an error
   * @throws {Error} - error indicating why the grammar is invalid
   * @private
   */
  static _isGrammarValid(jsonGrammar) {
    if (!Array.isArray(jsonGrammar)) {
      throw new Error(`Invalid grammar. Grammar must be a 2-dimensional array:\n${jsonGrammar}`);
    } else if (!jsonGrammar.length) {
      throw new Error(`Invalid grammar. Grammar must be of length >= 1:\n${jsonGrammar}`);
    } else if (!jsonGrammar[0][0] === GRAMMAR_CONSTANTS.BASE_GRAMMAR_RULE_NAME) {
      throw new Error(
        `Invalid grammar. Grammar must have base key: ${GRAMMAR_CONSTANTS.BASE_GRAMMAR_RULE_NAME}\n${jsonGrammar}`
      );
    }

    return true;
  }
};


text:
'**the *donga***' is Australian for out in the middle of nowhere; which is a suitable place to let my weird ideas out for play.

Stuff originating or coming from *the donga*, literally comes from nowwhere.

#  overview

##  process

I liked the outline given by Pieter Hintjens in this presentation -- I want to see how it goes  in the world of design and engineering; also I reckon the approach  resonantes with an *its-up-to-you* attitude and the '*first few*' notions I want to see survive the donga

* http://www.infoq.com/presentations/trick-better-software

The *trick* is to frame all commits as ... a *problem* with a *solution*.  So a commit becomes a solution response to an problem, need or issue.  Not a "want".

##  marketing myopia

**problem**:

Why?  I've cited Levitt (1960) paper enough times now that I remember the date.  My version of the whole thing is this;  people designing and specifying things endlessly make the same basic mistakes by focusing on the idea instead of the '*customer*' and *the market* (competition).

*  https://hbr.org/2004/07/marketing-myopia, Theodore Levitt, 1960, HBR

There's different ways folk act out their myopia, *imho*.  You will recognise some common software project behavious like make it clever, keep-it-simple then add extras (no longer simple), remain committed to "the plan", just making it up, build to a date/limitation; to name a few.

How do you resolve that in a software and systems context?  I suppose that's where the crazy ideas come from.

##  responsive design

**solution** (01):

A '*responsive design*', to me, is a design that can quickly and flexibly respond to the business-needs of the moment.  This view evolved over time working with 4 or 5 softwares, middlewares and tools that could/did implement responsive solutions.  Part of the design is to be responsive to change requests, new features, allowing switching between (conflicting) options and blending of mixed options.  So the product (artefact, the software) responds at a functional level.  Not just a mixure few layout, content and resize changes -- I'd call that *responsive ux*.

**solution** (02):

Computerise.

Software people need to let go of the 10th Century artisan approach to code.  In most software factories, people still make code the time-honoured way, by hand.  When you are not the one doing the work, things that make your architecture or structure *responsive* are less 'hard work' and more like a *why not* idea.

Bed time (to be continued ...)


text:
<?php
/*
 * API_NAME: Feedback Message Update
 * API_DESCRIPTION: Method for change feedback text
 * API_ACCESS: admin only
 * API_INPUT: id - integer, feedback message id
 * API_INPUT: text - string, text message
 * API_INPUT: token - string, token
 */

$curdir_events_insert = dirname(__FILE__);
include_once ($curdir_events_insert."/../api.lib/api.helpers.php");
include_once ($curdir_events_insert."/../../config/config.php");
include_once ($curdir_events_insert."/../api.lib/api.base.php");

$response = APIHelpers::startpage($config);
APIHelpers::checkAuth();

if(!APISecurity::isAdmin())
  APIHelpers::showerror(1275, 'access denie. you must be admin.');

if (!APIHelpers::issetParam('id'))
  APIHelpers::showerror(1276, 'not found parameter id');

if (!APIHelpers::issetParam('text'))
  APIHelpers::showerror(1278, 'not found parameter text');

$id = APIHelpers::getParam('id', 0);
$text = APIHelpers::getParam('text', '');

if (!is_numeric($id))
  APIHelpers::showerror(1279, 'Parameter id must be integer');

$id = intval($id);

$conn = APIHelpers::createConnection($config);

try {
 	$stmt = $conn->prepare('UPDATE feedback_msg SET text = ? WHERE id = ?');
 	$stmt->execute(array($text, intval($id)));
 	$response['result'] = 'ok';
} catch(PDOException $e) {
 	APIHelpers::showerror(1277, $e->getMessage());
}

APIHelpers::endpage($response);


text:
package pl.appformation.smash.requests;

import org.json.JSONArray;
import org.json.JSONException;
import java.io.IOException;
import okio.Okio;
import pl.appformation.smash.SmashNetworkData;
import pl.appformation.smash.SmashRequest;
import pl.appformation.smash.SmashResponse;
import pl.appformation.smash.SmashResponse.FailedListener;
import pl.appformation.smash.SmashResponse.SuccessListener;
import pl.appformation.smash.errors.SmashError;

public class SmashJsonArrayRequest extends SmashRequest<JSONArray>
{

    public SmashJsonArrayRequest(@MethodRes int method, SuccessListener<JSONArray> successListener, FailedListener failedListener)
    {
        super(method, successListener, failedListener);
    }

    public SmashJsonArrayRequest(@MethodRes int method, String url, SuccessListener<JSONArray> successListener, FailedListener failedListener)
    {
        super(method, url, successListener, failedListener);
    }

    protected SmashResponse<JSONArray> parseResponse(SmashNetworkData data)
    {
        try
        {
            JSONArray json = new JSONArray(Okio.buffer(data.source).readUtf8());
            return SmashResponse.success(json);
        }
        catch (JSONException | IOException e)
        {
            return SmashResponse.failed(new SmashError(e));
        }
    }

}


text:
const MockServer = require('./MockServer.js');

let server = new MockServer();

console.log(process.argv);
let port = 8080;
let publicPath = './dist';
for(let i=0; i < process.argv.length; i++) {
  if(process.argv[i] == '--port') {
    i++
    port = process.argv[i];
  }
  if(process.argv[i] == '--www') {
    i++
    publicPath = process.argv[i];
  }
}

server.start({
  port: port,
  public: publicPath,
  authorized: false,
  serverDelay: 100,
  rootUrl: '/'
});


text:
define( [ 'angular', '../module' ], function( ng ) {
  'use strict';

  ng
  .module( 'auth.services' )
  .factory( 'AccountService', function( AccountModel, UserModel ) {
    var AccountService = {
      model: AccountModel,

      data    : null,

      list    : function( findOptions ) {
        return AccountModel.list( findOptions ).$promise.then( function( accounts ) {
          AccountService.data = accounts;
          return AccountService.data;
        });
      },

      get: function( findOptions ) {
        return AccountModel.get( findOptions ).$promise;
      },

      create: function( data ) {
        return AccountModel.create( data ).$promise;
      },

      confirm: function( data ) {
        return UserModel.confirm( data ).$promise;
      }
    };

    return AccountService;
  });
});


text:
// Copyright 2014 Technical Machine, Inc. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Portions Copyright Joyent, Inc. and other Node contributors

/**
 * util.inherits
 */

function inherits (A, B) {
  var f = function () { };
  f.prototype = B.prototype;
  A.prototype = new f();
  A.super_ = B;
}

function objectToString(o) {
  return Object.prototype.toString.call(o);
}

function deprecate (fn) {
  return fn;
}

function isString (str) {
  return typeof str == 'string';
}

function isBuffer (arg) {
  return Buffer.isBuffer(arg);
}

function isNumber (arg) {
  return typeof arg == 'number';
}

function isNull (arg) {
  return arg == null;
}

function isObject (arg) {
  return typeof arg == 'object';
}

function isBoolean(arg) {
  return typeof arg == 'boolean';
}

function isArray (arg) {
  return Array.isArray(arg);
}

function isFunction(arg) {
  return typeof arg === 'function';
}

function isNullOrUndefined(arg) {
  return arg == null;
}

function isDate(arg) {
  return isObject(d) && objectToString(d) === '[object Date]';
}

function isRegExp(arg) {
  return isObject(re) && objectToString(re) === '[object RegExp]';
}

var debugs = {};
var debugEnviron = process.env.NODE_DEBUG || '';

function debuglog(set) {
  set = set.toUpperCase();
  if (!debugs[set]) {
    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
      var pid = process.pid;
      debugs[set] = function() {
        var msg = util.format.apply(exports, arguments);
        console.error('%s %d: %s', set, pid, msg);
      };
    } else {
      debugs[set] = function() {};
    }
  }
  return debugs[set];
};

// TODO: Make it work like Node's inspect
function inspect(object) {
  console.log(object);
}

function extend(origin, add) {
  // Don't do anything if add isn't an object
  if (!add || typeof add !== 'object') return origin;

  var keys = Object.keys(add);
  var i = keys.length;
  while (i--) {
    origin[keys[i]] = add[keys[i]];
  }
  return origin;
}

/**
 * Public API
 */

exports.inherits = inherits;
exports.deprecate = deprecate;
exports.isString = isString;
exports.isBuffer = isBuffer;
exports.isBoolean = isBoolean;
exports.isNumber = isNumber;
exports.isNull = isNull;
exports.isObject = isObject;
exports.isArray = isArray;
exports.isFunction = isFunction;
exports.isDate = isDate;
exports.isRegExp = isRegExp;
exports.dir = exports.inspect = inspect;
exports.isNullOrUndefined = isNullOrUndefined;
exports.debuglog = debuglog;

/**
 * Non-public API (but that doesn't stop some people)
 */

exports._extend = extend;


text:
/**
 *  Include guard
 */
#pragma once

/**
 *  Dependencies
 */
#include <cstdint>
#include <string>
#include "stringfield.h"
#include "booleanset.h"
#include "decimalfield.h"
#include "numericfield.h"

/**
 *  Set up namespace
 */
namespace AMQP {

/**
 *  Forward declarations
 */
class Table;
class Array;
class Field;

/**
 *  Class implementation
 */
template <typename T, typename I>
class FieldProxy
{
private:
    /**
     *  The table or array possibly holding the requested field
     */
    T *_source;

    /**
     *  The key in the table
     */
    I _index;

public:
    /**
     *  Construct the field proxy
     *
     *  @param  table   the table possibly holding the field
     *  @oaram  index   key in table map
     */
    FieldProxy(T *source, I index) :
        _source(source),
        _index(index)
    {}

    /**
     *  Assign a boolean value
     *
     *  @param  value
     */
    FieldProxy& operator=(bool value)
    {
        // assign value and allow chaining
        _source->set(_index, BooleanSet(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(uint8_t value)
    {
        // assign value and allow chaining
        _source->set(_index, UOctet(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(int8_t value)
    {
        // assign value and allow chaining
        _source->set(_index, Octet(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(uint16_t value)
    {
        // assign value and allow chaining
        _source->set(_index, UShort(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(int16_t value)
    {
        // assign value and allow chaining
        _source->set(_index, Short(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(uint32_t value)
    {
        // assign value and allow chaining
        _source->set(_index, ULong(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(int32_t value)
    {
        // assign value and allow chaining
        _source->set(_index, Long(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(uint64_t value)
    {
        // assign value and allow chaining
        _source->set(_index, ULongLong(value));
        return *this;
    }

    /**
     *  Assign a numeric value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(int64_t value)
    {
        // assign value and allow chaining
        _source->set(_index, LongLong(value));
        return *this;
    }

    /**
     *  Assign a decimal value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy& operator=(const DecimalField &value)
    {
        // assign value and allow chaining
        _source->set(_index, DecimalField(value));
        return *this;
    }

    /**
     *  Assign a string value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy &operator=(const std::string &value)
    {
        // in theory we should make a distinction between short and long string,
        // but in practive only long strings are accepted
        _source->set(_index, LongString(value));

        // allow chaining
        return *this;
    }

    /**
     *  Assign a string value
     *
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy &operator=(const char *value)
    {
        // cast to a string
        return operator=(std::string(value));
    }

    /**
     *  Assign an array value
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy &operator=(const Array &value)
    {
        // assign value and allow chaining
        _source->set(_index, value);
        return *this;
    }

    /**
     *  Assign a table value
     *  @param  value
     *  @return FieldProxy
     */
    FieldProxy &operator=(const Table &value)
    {
        // assign value and allow chaining
        _source->set(_index, value);
        return *this;
    }

    /**
     *  Get the underlying field
     *  @return Field
     */
    const Field &get() const
    {
        return _source->get(_index);
    }

    /**
     *  Get a boolean
     *  @return bool
     */
    template <typename TARGET>
    operator TARGET () const
    {
        // retrieve the value
        return _source->get(_index);
    }
};

// define types for array- and table-based field proxy
using AssociativeFieldProxy = FieldProxy<Table, std::string>;
using ArrayFieldProxy       = FieldProxy<Array, uint8_t>;

/**
 *  end namespace
 */
}


text:
package evasion.input;

import com.badlogic.gdx.Input.*;
import com.badlogic.gdx.InputProcessor;
import evasion.game.GameWorld;

public class InputHandler implements InputProcessor {

    private final GameWorld world;

    public InputHandler (final GameWorld world) {
        this.world = world;
    }

    @Override
    public boolean keyDown(int keycode) {
        switch (keycode) {
            case Keys.LEFT:
                world.getPlayer().setMovingLeft(true);
                break;
            case Keys.RIGHT:
                world.getPlayer().setMovingRight(true);
                break;
            case Keys.A:
                world.getPlayer().setMovingLeft(true);
                break;
            case Keys.D:
                world.getPlayer().setMovingRight(true);
                break;
            case Keys.SPACE:
                world.setFiring(true);
                break;
        }
        return true;
    }

    @Override
    public boolean keyUp(int keycode) {
        switch (keycode) {
            case Keys.LEFT:
                world.getPlayer().setMovingLeft(false);
                break;
            case Keys.RIGHT:
                world.getPlayer().setMovingRight(false);
                break;
            case Keys.A:
                world.getPlayer().setMovingLeft(false);
                break;
            case Keys.D:
                world.getPlayer().setMovingRight(false);
                break;
            case Keys.SPACE:
                world.setFiring(false);
                break;
        }

        return true;
    }

    @Override
    public boolean keyTyped(char character) {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        world.setFiring(true);
        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        world.setFiring(false);
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <groupId>net.barik</groupId>
  <artifactId>poi</artifactId>
  <versioning>
    <release>3.11</release>
    <versions>
      <version>3.11</version>
    </versions>
    <lastUpdated>20150222205416</lastUpdated>
  </versioning>
</metadata>


text:
The view `pg_roles` provides access to information about database roles. This is simply a publicly readable view of [pg\_authid](pg_authid.html) that blanks out the password field. This view explicitly exposes the OID column of the underlying table, since that is needed to do joins to other catalogs.

|column|type|references|description|
|------|----|----------|-----------|
|`rolname`|name| |Role name|
|`rolsuper`|bool| |Role has superuser privileges|
|`rolinherit`|bool| |Role automatically inherits privileges of roles it is a member of|
|`rolcreaterole`|bool| |Role may create more roles|
|`rolcreatedb`|bool| |Role may create databases|
|`rolcatupdate`|bool| |Role may update system catalogs directly. \(Even a superuser may not do this unless this column is true.\)|
|`rolcanlogin`|bool| |Role may log in. That is, this role can be given as the initial session authorization identifier|
|`rolconnlimit`|int4| |For roles that can log in, this sets maximum number of concurrent connections this role can make. -1 means no limit|
|`rolpassword`|text| |Not the password \(always reads as \*\*\*\*\*\*\*\*\)|
|`rolvaliduntil`|timestamptz| |Password expiry time \(only used for password authentication\); NULL if no expiration|
|`rolconfig`|text\[\]| |Role-specific defaults for run-time configuration variables|
|`rolresqueue`|oid|pg\_resqueue.oid|Object ID of the resource queue this role is assigned to.|
|`oid`|oid|pg\_authid.oid|Object ID of role|
|`rolcreaterextgpfd`|bool| |Role may create readable external tables that use the gpfdist protocol.|
|`rolcreaterexthttp`|bool| |Role may create readable external tables that use the http protocol.|
|`rolcreatewextgpfd`|bool| |Role may create writable external tables that use the gpfdist protocol.|
|`rolresgroup`|oid|pg\_resgroup.oid|Object ID of the resource group to which this role is assigned.|

**Parent topic:** [System Catalogs Definitions](../system_catalogs/catalog_ref-html.html)


text:
package com.amazonaws.services.config.model.transform;

import static com.amazonaws.util.StringUtils.UTF8;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import java.util.List;

import com.amazonaws.AmazonClientException;
import com.amazonaws.services.config.model.*;
import com.amazonaws.transform.Marshaller;
import com.amazonaws.util.BinaryUtils;
import com.amazonaws.util.StringUtils;
import com.amazonaws.util.StringInputStream;
import com.amazonaws.util.json.*;

/**
 * ConfigStreamDeliveryInfoMarshaller
 */
public class ConfigStreamDeliveryInfoJsonMarshaller {

    /**
     * Marshall the given parameter object, and output to a JSONWriter
     */
    public void marshall(ConfigStreamDeliveryInfo configStreamDeliveryInfo,
            JSONWriter jsonWriter) {
        if (configStreamDeliveryInfo == null) {
            throw new AmazonClientException(
                    "Invalid argument passed to marshall(...)");
        }

        try {
            jsonWriter.object();

            if (configStreamDeliveryInfo.getLastStatus() != null) {
                jsonWriter.key("lastStatus").value(
                        configStreamDeliveryInfo.getLastStatus());
            }

            if (configStreamDeliveryInfo.getLastErrorCode() != null) {
                jsonWriter.key("lastErrorCode").value(
                        configStreamDeliveryInfo.getLastErrorCode());
            }

            if (configStreamDeliveryInfo.getLastErrorMessage() != null) {
                jsonWriter.key("lastErrorMessage").value(
                        configStreamDeliveryInfo.getLastErrorMessage());
            }

            if (configStreamDeliveryInfo.getLastStatusChangeTime() != null) {
                jsonWriter.key("lastStatusChangeTime").value(
                        configStreamDeliveryInfo.getLastStatusChangeTime());
            }

            jsonWriter.endObject();
        } catch (Throwable t) {
            throw new AmazonClientException(
                    "Unable to marshall request to JSON: " + t.getMessage(), t);
        }
    }

    private static ConfigStreamDeliveryInfoJsonMarshaller instance;

    public static ConfigStreamDeliveryInfoJsonMarshaller getInstance() {
        if (instance == null)
            instance = new ConfigStreamDeliveryInfoJsonMarshaller();
        return instance;
    }

}


text:
import rb, { Component } from '../core';
import './itemscroller';

const regSizes = /(\(\s*(min|max)(-width)?\s*:\s*(\d+\.*\d*)(px)?\)\s*)?(\d+\.*\d*)(px|%)?/g;

const createConditions = rb.memoize(function (value) {

    var match, size;

    var sizes = [];

    while((match = regSizes.exec(value))){
        size = {
            condition: parseFloat(match[4]),
            type: match[2],
            str: match[0],
            value: parseFloat(match[6]),
            unit: match[7] || 'px',
        };

        size.css = size.value + size.unit;

        sizes.push(size);
    }

    return sizes;
}, true);

class ItemScrollerQueries extends rb.components.itemscroller {
    /**
     * @static
     * @mixes rb.components.itemscroller.defaults
     * @prop {String} queries="" Container queries configuration represented by a `sizes` like comma separated string. `"(max-width: 480px) cellWidthSize1(%|px), (max-width: 1024px) cellWidthSize2(%|px), defaultCellWidthSize(%|px)"` (i.e.: `"(max-width: 480px) 100%, (max-width: 1024px) 50%, 600px"`).
     * @prop {String} modifyUsePx=true Wether the `usePx` option should automatically changed.
     */
    static get defaults() {
        return {
            queries: '',
            modifyUsePx: true,
        };
    }

    beforeConstruct(){
        super.beforeConstruct();

        this.rAFs({batch: true}, '_setCurrentQuery');
    }

    _parseQueries() {
        const queries = this.options.queries;

        if (!queries) {
            this._parsedQueries = null;
            return;
        }
        if (this._parsedQueries && this._parsedQueries.queryString == queries) {
            return;
        }

        this._parsedQueries = createConditions(queries);
        this._parsedQueries.queryString = queries;
    }

    setOption(name, value, isSticky) {
        super.setOption(name, value, isSticky);

        if (name == 'queries') {
            this.calculateLayout();
        }
    }

    _getCellWidth(element) {
        return this._parsedQueries && this._parsedQueries.currentQuery ?
            this._parsedQueries.currentQuery.computedValue :
            super._getCellWidth(element)
        ;
    }

    _getCurrentQuery() {
        if (!this._parsedQueries) {
            return;
        }
        let currentQuery, i;

        for (i = 0; i < this._parsedQueries.length; i++) {
            currentQuery = this._parsedQueries[i];
            if(!currentQuery.condition ||
                !currentQuery.type ||
                (currentQuery.type == 'max' && this.viewportWidth <= currentQuery.condition) ||
                (currentQuery.type == 'min' && this.viewportWidth >= currentQuery.condition)){
                break;
            }
        }

        currentQuery.computedValue = currentQuery.unit == '%' ?
        this.viewportWidth * currentQuery.value / 100 :
            currentQuery.value
        ;

        if(this.options.modifyUsePx){
            this.options.usePx = currentQuery.unit == 'px';
        }

        if (currentQuery != this._parsedQueries.currentQuery) {
            this._parsedQueries.currentQuery = currentQuery;
            this._setCurrentQuery();
        }
    }

    _setCurrentQuery() {
        if (this._parsedQueries && this._parsedQueries.currentQuery) {
            this.$cells.css({width: this._parsedQueries.currentQuery.css});
        }
    }

    _switchOff() {
        const ret = super._switchOff();

        if (this._parsedQueries && this._parsedQueries.currentQuery) {
            this._parsedQueries.currentQuery = null;
            this.$cells.css({width: ''});
        }
        return ret;
    }

    _calculateCellLayout() {
        this._parseQueries();
        this._getCurrentQuery();

        return super._calculateCellLayout();
    }
}

Component.register('itemscroller', ItemScrollerQueries, true);

export default ItemScrollerQueries;


text:
layout: data_model
title: NeighborSolicitationType
this_version: 1.1.1
---

  Heads up! These docs are for STIX 1.1.1, which is not the latest version (1.2). View the latest!

NeighborSolicitationTypeNetwork Packet Object Schema

Nodes send Neighbor Solicitations to request the link-layer address of a target node while also providing their own link-layer address to the target. Neighbor Solicitations are multicast when the node needs to resolve an address and unicast when the node seeks to verify the reachability of a neighbor. (type=135; code=0).

      <form id="nav-version">
        <select>

            <option value="1.2" >STIX 1.2</option>

            <option value="1.1.1" selected="selected">STIX 1.1.1</option>

            <option value="1.1" >STIX 1.1</option>

            <option value="1.0.1" >STIX 1.0.1</option>

            <option value="1.0" >STIX 1.0</option>

        </select>
      </form>

Fields

      Field Name
      Type
      Description

      Target_IPv6_Addr0..1

          AddressObjectType

The IP address of the target of the solicitation.

      Options0..1

          NeighborSolicitationOptionsType

Neighbor Solicitation messages include zero or more options, some of which may appear multiple times in the same message.


text:
<?php

namespace PhpSpec\Runner\Maintainer;

use PhpSpec\Loader\Node\ExampleNode;
use PhpSpec\SpecificationInterface;
use PhpSpec\Runner\MatcherManager;
use PhpSpec\Runner\CollaboratorManager;

use PhpSpec\Wrapper\Collaborator;
use PhpSpec\Wrapper\Unwrapper;

use Prophecy\Prophet;

/**
 * Class CollaboratorsMaintainer
 * @package PhpSpec\Runner\Maintainer
 */
class CollaboratorsMaintainer implements MaintainerInterface
{
    /**
     * @var string
     */
    private static $docex = '#@param *([^ ]*) *\$([^ ]*)#';
    /**
     * @var \PhpSpec\Wrapper\Unwrapper
     */
    private $unwrapper;
    /**
     * @var Prophet
     */
    private $prophet;

    /**
     * @param Unwrapper $unwrapper
     */
    public function __construct(Unwrapper $unwrapper)
    {
        $this->unwrapper = $unwrapper;
    }

    /**
     * @param ExampleNode $example
     *
     * @return bool
     */
    public function supports(ExampleNode $example)
    {
        return true;
    }

    /**
     * @param ExampleNode            $example
     * @param SpecificationInterface $context
     * @param MatcherManager         $matchers
     * @param CollaboratorManager    $collaborators
     */
    public function prepare(ExampleNode $example, SpecificationInterface $context,
                            MatcherManager $matchers, CollaboratorManager $collaborators)
    {
        $this->prophet = new Prophet(null, $this->unwrapper, null);

        $classRefl = $example->getSpecification()->getClassReflection();

        if ($classRefl->hasMethod('let')) {
            $this->generateCollaborators($collaborators, $classRefl->getMethod('let'));
        }

        $this->generateCollaborators($collaborators, $example->getFunctionReflection());
    }

    /**
     * @param ExampleNode            $example
     * @param SpecificationInterface $context
     * @param MatcherManager         $matchers
     * @param CollaboratorManager    $collaborators
     */
    public function teardown(ExampleNode $example, SpecificationInterface $context,
                             MatcherManager $matchers, CollaboratorManager $collaborators)
    {
        $this->prophet->checkPredictions();
    }

    /**
     * @return int
     */
    public function getPriority()
    {
        return 50;
    }

    /**
     * @param CollaboratorManager         $collaborators
     * @param \ReflectionFunctionAbstract $function
     */
    private function generateCollaborators(CollaboratorManager $collaborators, \ReflectionFunctionAbstract $function)
    {
        if ($comment = $function->getDocComment()) {
            $comment = str_replace("\r\n", "\n", $comment);
            foreach (explode("\n", trim($comment)) as $line) {
                if (preg_match(self::$docex, $line, $match)) {
                    $collaborator = $this->getOrCreateCollaborator($collaborators, $match[2]);
                    $collaborator->beADoubleOf($match[1]);
                }
            }
        }

        foreach ($function->getParameters() as $parameter) {
            $collaborator = $this->getOrCreateCollaborator($collaborators, $parameter->getName());
            if (null !== $class = $parameter->getClass()) {
                $collaborator->beADoubleOf($class->getName());
            }
        }
    }

    /**
     * @param CollaboratorManager $collaborators
     * @param string              $name
     *
     * @return Collaborator
     */
    private function getOrCreateCollaborator(CollaboratorManager $collaborators, $name)
    {
        if (!$collaborators->has($name)) {
            $collaborator = new Collaborator($this->prophet->prophesize());
            $collaborators->set($name, $collaborator);
        }

        return $collaborators->get($name);
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->
<section xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5.0"
    xmlns:xl="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude"
    xsi:schemaLocation="http://docbook.org/ns/docbook ../../../content/dtd/docbook.xsd"
    xmlns="http://docbook.org/ns/docbook">
    <title>The Financial Account Edit Deposit Slip screen.</title>
    <para>This screen displays the details of a Payment Group and its transactions. The Deposit Slip
        for the Payment Group can be printed if required and the Payment Group itself can be
        updated.</para>
    <para>Details that can be updated include the name of the Payment Group itself and the addition,
        removal or update of transactions.</para>
    <para>NOTE: Any changes to the Payment Group will be automatically updated to the Deposit
        Slip.</para>
    <section>
        <title>How do I update a Deposit Slip?</title>
        <para>
            <orderedlist>
                <listitem>
                    <para>Select the Payment Group required</para>
                </listitem>
                <listitem>
                    <para>Update the 'Payment Group Name' if required</para>
                </listitem>
                <listitem>
                    <para>Use the lookup for 'Payment Id' to add new transactions to the Payment
                        Group if required</para>
                </listitem>
                <listitem>
                    <para>Use the 'Cancel' button next to a particular transaction to remove it from
                        the Payment Group</para>
                </listitem>
                <listitem>
                    <para>Press the 'Update' or 'Add' buttons as required</para>
                </listitem>
                <listitem>
                    <para>Press the 'Print Deposit Slip' button</para>
                </listitem>
            </orderedlist>
        </para>
        <para>The Deposit Slip will be displayed with the latest details of the transactions for the
            Payment Group</para>
    </section>
</section>


text:
/* ctgPos2.h was originally generated by the autoSql program, which also
 * generated ctgPos2.c and ctgPos2.sql.  This header links the database and
 * the RAM representation of objects. */

/* Copyright (C) 2004 The Regents of the University of California
 * See README in this or parent directory for licensing information. */

#ifndef CTGPOS2_H
#define CTGPOS2_H

#define CTGPOS2_NUM_COLS 6

struct ctgPos2
/* Where a contig is inside of a chromosome including contig type information. */
    {
    struct ctgPos2 *next;  /* Next in singly linked list. */
    char *contig;	/* Name of contig */
    unsigned size;	/* Size of contig */
    char *chrom;	/* Chromosome name */
    unsigned chromStart;	/* Start in chromosome */
    unsigned chromEnd;	/* End in chromosome */
    char type[2];	/* (W)GS contig, (F)inished, (P)redraft, (D)raft, (O)ther */
    };

void ctgPos2StaticLoad(char **row, struct ctgPos2 *ret);
/* Load a row from ctgPos2 table into ret.  The contents of ret will
 * be replaced at the next call to this function. */

struct ctgPos2 *ctgPos2Load(char **row);
/* Load a ctgPos2 from row fetched with select * from ctgPos2
 * from database.  Dispose of this with ctgPos2Free(). */

struct ctgPos2 *ctgPos2LoadAll(char *fileName);
/* Load all ctgPos2 from whitespace-separated file.
 * Dispose of this with ctgPos2FreeList(). */

struct ctgPos2 *ctgPos2LoadAllByChar(char *fileName, char chopper);
/* Load all ctgPos2 from chopper separated file.
 * Dispose of this with ctgPos2FreeList(). */

#define ctgPos2LoadAllByTab(a) ctgPos2LoadAllByChar(a, '\t');
/* Load all ctgPos2 from tab separated file.
 * Dispose of this with ctgPos2FreeList(). */

struct ctgPos2 *ctgPos2CommaIn(char **pS, struct ctgPos2 *ret);
/* Create a ctgPos2 out of a comma separated string.
 * This will fill in ret if non-null, otherwise will
 * return a new ctgPos2 */

void ctgPos2Free(struct ctgPos2 **pEl);
/* Free a single dynamically allocated ctgPos2 such as created
 * with ctgPos2Load(). */

void ctgPos2FreeList(struct ctgPos2 **pList);
/* Free a list of dynamically allocated ctgPos2's */

void ctgPos2Output(struct ctgPos2 *el, FILE *f, char sep, char lastSep);
/* Print out ctgPos2.  Separate fields with sep. Follow last field with lastSep. */

#define ctgPos2TabOut(el,f) ctgPos2Output(el,f,'\t','\n');
/* Print out ctgPos2 as a line in a tab-separated file. */

#define ctgPos2CommaOut(el,f) ctgPos2Output(el,f,',',',');
/* Print out ctgPos2 as a comma separated list including final comma. */

/* -------------------------------- End autoSql Generated Code -------------------------------- */

#endif /* CTGPOS2_H */


text:
<?php

namespace Herrera\Annotations\Exception;

/**
 * This exception is thrown if an invalid index is used.
 *
 * @author Kevin Herrera <kevin@herrera.io>
 */
class OutOfRangeException extends Exception
{
}


text:
Connectors define transport of data fields to/from external servers. Each
connector is linked with one Handler and specifies:
 * Communication protocol
 * Target endpoint, i.e server address and message topics
 * Encoding of the data fields

## Administration

To create a new connector you set:
 - **Connector Name**
 - **Application** that references a specific backend *Handler*
 - **Format** of the message payload, which can be:
   - **JSON** to encode data fields as [JSON](http://www.json.org) structures like `{"NameOne":ValueOne, "NameTwo":ValueTwo}`.
   - **Raw Data** to send just the binary content of the *data* field, without ant port numbers nor flags.
   - **Web Form** to encode fields in a query strings like `NameOne=ValueOne&NameTwo=ValueTwo`.
 - **URI** defines the target host, which can be
   - `ws:` (with no host:port) for Web Sockets
   - `http://` for HTTP POST or `https://` for HTTP/SSL or simply `http:` for input only
   - `mqtt://` for MQTT or `mqtts://` for MQTT/SSL
   - `amqp://` for AMQP or `amqp://` for AMQP/SSL
 - **Publish QoS** determines reliability of the publications.
 - **Publish Uplinks**, which is a server pattern for constructing the publication
   topic for uplink messages, e.g. `out/{devaddr}`. This can be used to include
   the actual DevEUI, DevAddr or other data field in the message topic.
 - **Publish Events**, which is a server pattern for constructing the publication
   topic for event messages.
 - **Subscribe QoS** determines reliability of the subscriptions.
 - **Subscribe**, which is a topic to be subscribed. It may include broker specific
   wildcards, e.g. `in/#`. The MQTT broker will then send messages with a matching
   topic to this connector.
 - **Received Topic**, which is a template for parsing the topic of received
   (subscribed) messages, e.g. `in/{devaddr}`. This can be used to retrieve the
   target DevEUI, DevAddr or App directly from the topic name.
 - **Enabled** flag that allows you to temporarily disable an existing connector.
 - **Failed** flag indicates what has failed. The Event list includes more
   details.
   - **badarg** when some of connector parameters is bad
   - **network** when the destination server cannot be reached
   - **topic** when the target broker configuration is wrong

If the Connector is *Enabled* the server will automatically connect to the
backend server and subscribe this topic.

When a *Failed* flag is raised, the connector is inactive and no connection is
established. To re-establish the connection after an error occurs, fix the
indicated root cause and then remove the flag to reactivate the connector.

On the Authentication tab:
 - **Client ID** is the MQTT parameter
 - **Auth** identifies the type of authentication:
   - **Username+Password** for a common server authentication
   - **Header+Token** for a token-based authentication. **Name** shall be set to
     the header name and **Password/Key** to the token, for example:
     - Name: `X-API-Key`, Password/Key: `abcdef12345`
     - Name: `Authorization`, Password/Key: `Bearer abcdef12345`
   - **Shared Access Signature** for Microsoft servers
 - **Name** and **Password/Key** for plain authentication
 - **User Certificate** and **Private Key** if SSL authentication is needed

On the Status tab you can view the status of established connections:
 - **URI** and **Cliend ID** used
 - **Subscriptions** made
 - **Status** of the connection: `disconnected`, `connecting` or `connected`

Please read the [Integration Guide](Integration.md) for detailed information on
how to connect to a specific IoT Platform like AWS IoT, IBM Watson IoT, MathWorks
ThingSpeak, Azure IoT Hub or Adafruit IO.

### Patterns

To include and extract node-specific attributes the Published and Received Topic
may include data field names in curly brackets, e.g. `{deveui}` or `{port}`
(see the *Uplink Fields* of Backend Handlers).

If you set *Published Topic* to `/device/{deveui}` and `#{deveui => "123456"}`,
then the topic `/device/123456` will be used for the particulat frame.

Similarly, if your *Received Topic* is `/device/{deveui}` and the backend
publishes a downlink to `/device/123456`, the field `#{deveui => "123456"}`
will be set and used for routing the downlink.

The data fields you use in your patterns must be included as *Uplink Fields*
of the respective Handler.

The MQTT connector allows the `{devaddr}` and `{appargs}` parameter also for the
*URI* and *Authentication* fields to create device-specific connections.

If you set *Client ID* to `{devaddr}` the server will create as many MQTT
connections as many devices you have, each using its `devaddr` as the ClientID.

The Received Topic may also include the `#` (hash), which matches zero or more
characters, including any '/' delimiters. It can be used to ignore the leading
or training characters in the topic.

### Certificates

You can generate a self-signed *User Certificate* (`cert.pem`) and corresponding
*Private Key* (`key.pem`) by:
```
openssl req -x509 -newkey rsa:4096 -keyout privkey.pem -out cert.pem -days 365
openssl rsa -in privkey.pem -out key.pem
```

## Web Sockets

The lorwan-server can act as a Web Socket server. Clients can connect, receive
uplinks and send downlinks.

To create a web socket connector you set:
 - **URI** to `ws:` (with no hostname)
 - **Publish Uplinks** to a URL pattern starting with a slash, e.g. '/ws/uplink/{devaddr}'
 - **Publish Events** to another URL pattern, e.g. '/ws/events/{devaddr}'

HTTP Basic authentication is supported. On the Authentication tab you may set the
*Name* and *Password/Key* that shall be verified by the server.

The patterns may have any structure (doesn't have to start with `/ws`), but must
be unique across the entire server, including the web-admin itself.

The patterns may contain uplink Fields of the corresponding [Handler](Handlers.md),
mainly `{deveui}`, `{devaddr}` or `{app}` corresponding to a group of devices with
the same application (Handler name).

The *Subscribe* and *Received Topic* fields are not used and can be left empty.

To connect to the WebSocket, then open URL to the path you defined, i.e.
`ws://server:8080/ws/uplink/<DevAddr>` or `ws://server:8080/ws/events/<DevAddr>`.

The URL is matched against the pattern to select the target device(s). For example,
`ws://127.0.0.1:8080/ws/events/11223344` connects to events from the DevAddr *11223344*.

Multiple parallel connections may be established to one URL.
When the device sends a frame, all connected clients will receive the application data.
Any of the clients may then send a response back. If multiple clients send data to
the device the frames will be enqueued and sent one by one. The enqueued *Downlinks*
can be viewed via the [Node Administration](Nodes.md) page.

### Keep-alive

By default, the WebSocket connection will be closed if the client (e.g. your web browser)
sends for 1 hour no data back to the server. This is to avoid stale connections.

To keep the connection open for a longer time:
 * You can adjust the `{websocket_timeout, 360000}` configuration parameter to a higher
   value (in milliseconds).
 * You can even set `{websocket_timeout, infinity}` to disable the session expiration.
 * Or the client (browser) needs to keep sending *ping* frames.

The **ping** frames may not be enabled by default. To enable *ping* frames in Firefox,
go to **about:config** and set **network.websocket.timeout.ping.request** to (for example)
120 (seconds).

### Demo page

Demo client is available at [`http://127.0.0.1:8080/admin/ws.html`](../priv/admin/ws.html).
Enter the desired URL path (e.g. `/ws/events/11223344`) and the desired format
(Raw or JSON) and then establish a WebSocket connection.
The page will display data received from the device and allow you to send data back.

In the *Raw* mode all information must be entered as a string of hexadecimal digits,
without any spaces.
Each byte is represented by exactly 2 digits. For example, "4849" represents ASCII string "01".

## HTTP/REST

The REST API works in both directions. The lorwan-server can send a HTTP PUT/POST
request upon receiving an uplink frame. It can also listen for incoming
HTTP PUT/POST requests and trigger downlink frames.

To create a HTTP connector you set:
 - **URI** to the target host either as `http://host:port` or `https://host:port.
   You also may include a common URL prefix `http://host:port/prefix`
 - **Publish Uplinks** to a URL pattern, e.g. '/uplink/{devaddr}'. If you leave
   this field empty, no message will be sent upon uplink.
 - **Publish Events** to another URL pattern, e.g. '/events/{devaddr}'. Leave it
   empty if you don't want any uplink upon events.
 - **Received Topic** is a template for parsing the topic of received downlink
   messages, e.g. `/in/{devaddr}`.

To define an input-only connector for downlinks, set **URI** to `http:` and leave
the **Publish Uplinks** and **Publish Events** blank.

Make sure that all URL paths start with a slash ('/'). The *Received Topic* must
be different to all Web Socket *Publish* patterns.

Every uplink will trigger a HTTP POST to `http://host:port/uplink/{devaddr}`.

To send a downlink request you should have a user with the
[*device:send* scope](Server.md#users) (or *unlimited*) and make a HTTP PUT or POST
to `http://yourserver:8080/in/{devaddr}`.
For example:

```bash
curl -v --digest -uadmin:admin -H "Content-Type: application/json" -X POST http://localhost:8080/in/11223344 -d "{\"data\":\"ABCDEFG\"}"
```

## Generic MQTT Servers

The lorawan-server can acts as a MQTT client, publish uplink frames and subscribe
for downlink frames. It can connect to any standard MQTT server (message broker),
e.g. the
[RabbitMQ](https://www.rabbitmq.com/mqtt.html) or
[Mosquitto](https://mosquitto.org).

First of all, make sure you understand the
[terminology and principles of messaging](http://www.rabbitmq.com/tutorials/tutorial-one-php.html)
and that the MQTT protocol [is enabled](https://www.rabbitmq.com/mqtt.html)
in your broker.

Open the lorawan-server web-administration and create a Backend Connector:
 - **URI** defines the target host either as `mqtt://host:port` or `mqtts://host:port`
 - **Publish QoS** and **Subscribe QoS** directly determine the QoS level.
 - **Publish Uplinks** is a pattern for constructing the message topic
   of uplinks, e.g. `out/{devaddr}`.
 - **Subscribe** is a downlink topic to be subscribed by the lorawan-server,
   e.g. `in/#`.
 - **Received Topic** is a template for parsing the topic of received downlink
   messages, e.g. `in/{devaddr}`.

On the Authentication tab:
 - **Auth** shall be set to *Username+Password*, even when the *Name* and
   *Password/Key* are empty.

Exclusively for MQTT, the *URI*, *Client ID*, *Name*, *Password/Key* and *Subscribe*
may also include patterns, but limited to `{devaddr}` and `{appargs}` only. This
can be used to create device-specific connections or subscriptions. Use with care:
creating too many connections may cause overload.

In order to consume the uplink messages sent by your devices you have to subscribe
at the message broker for the *Published Topic*, e.g. for `out/#` (or even just `#`) by:
```bash
mosquitto_sub -h 127.0.0.1 -p 1883 -t 'out/#' -u 'user' -P 'pass'
```

When using RabbitMQ, create a queue and then bind it to the `amq.topic` exchange
using the `out.#` (or `#`) binding key. Note that while MQTT uses slashes ("/") for
topic segment separators, RabbitMQ uses dots. RabbitMQ internally translates the two,
so for example the MQTT topic `cities/london` becomes in RabbitMQ `cities.london`.

To send a downlink message to one of your devices do e.g.
```bash
mosquitto_pub -h 127.0.0.1 -p 1883 -t 'in/00112233' -m '{"data":"00"}' -u 'user' -P 'pass'
```

## MongoDB

The lorawan-server can store the received uplinks directly to a
[MongoDB](https://www.mongodb.com).

Open the lorawan-server web-administration and create a Backend Connector:
 - **Format** is ignored, but should be set to *JSON*.
 - **URI** defines the target host `mongodb://host:port` or `mongodb://host1:port,host2:port`
   to list replica pairs/sets.
 - **Publish Uplinks** and **Publish Events** must be in the format *Database*/*Collection*.
   The *Database* is optional; if not provided, `local` is used by default.

On the Authentication tab you may set the *Name* and *Password/Key*.


text:
angular.module('initial_spi', ['ngRoute', 'initial_spi.controllers'])
.config(['$routeProvider', function($routeProvider){
	/*
	 * `when()` cuantas veces sea necesario
	 * `otherwise()` una sola vez "OJO"
	*/
	$routeProvider

	.when('/mobile', {
	    templateUrl : "views/mobile.html",
	    controller: 'mobileController'
	})

	.when('/smartphone', {
		templateUrl: "views/smartphone.html",
		controller: 'smartphoneController'
	})

	.otherwise({
	    redirectTo: '/',
	    templateUrl: 'otherwise.html'
	});
 }]);