text:
package org.apache.camel.component.aws.lambda;

import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.lambda.AWSLambda;
import com.amazonaws.services.lambda.model.CreateAliasRequest;
import com.amazonaws.services.lambda.model.CreateAliasResult;
import com.amazonaws.services.lambda.model.CreateEventSourceMappingRequest;
import com.amazonaws.services.lambda.model.CreateEventSourceMappingResult;
import com.amazonaws.services.lambda.model.CreateFunctionRequest;
import com.amazonaws.services.lambda.model.CreateFunctionResult;
import com.amazonaws.services.lambda.model.DeadLetterConfig;
import com.amazonaws.services.lambda.model.DeleteAliasRequest;
import com.amazonaws.services.lambda.model.DeleteAliasResult;
import com.amazonaws.services.lambda.model.DeleteEventSourceMappingRequest;
import com.amazonaws.services.lambda.model.DeleteEventSourceMappingResult;
import com.amazonaws.services.lambda.model.DeleteFunctionRequest;
import com.amazonaws.services.lambda.model.DeleteFunctionResult;
import com.amazonaws.services.lambda.model.Environment;
import com.amazonaws.services.lambda.model.FunctionCode;
import com.amazonaws.services.lambda.model.GetAliasRequest;
import com.amazonaws.services.lambda.model.GetAliasResult;
import com.amazonaws.services.lambda.model.GetFunctionRequest;
import com.amazonaws.services.lambda.model.GetFunctionResult;
import com.amazonaws.services.lambda.model.InvokeRequest;
import com.amazonaws.services.lambda.model.InvokeResult;
import com.amazonaws.services.lambda.model.ListAliasesRequest;
import com.amazonaws.services.lambda.model.ListAliasesResult;
import com.amazonaws.services.lambda.model.ListEventSourceMappingsRequest;
import com.amazonaws.services.lambda.model.ListEventSourceMappingsResult;
import com.amazonaws.services.lambda.model.ListFunctionsResult;
import com.amazonaws.services.lambda.model.ListTagsRequest;
import com.amazonaws.services.lambda.model.ListTagsResult;
import com.amazonaws.services.lambda.model.ListVersionsByFunctionRequest;
import com.amazonaws.services.lambda.model.ListVersionsByFunctionResult;
import com.amazonaws.services.lambda.model.PublishVersionRequest;
import com.amazonaws.services.lambda.model.PublishVersionResult;
import com.amazonaws.services.lambda.model.TagResourceRequest;
import com.amazonaws.services.lambda.model.TagResourceResult;
import com.amazonaws.services.lambda.model.TracingConfig;
import com.amazonaws.services.lambda.model.UntagResourceRequest;
import com.amazonaws.services.lambda.model.UntagResourceResult;
import com.amazonaws.services.lambda.model.UpdateFunctionCodeRequest;
import com.amazonaws.services.lambda.model.UpdateFunctionCodeResult;
import com.amazonaws.services.lambda.model.VpcConfig;
import com.amazonaws.util.IOUtils;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.support.DefaultProducer;
import org.apache.camel.util.CastUtils;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Producer which sends messages to the Amazon Web Service Lambda <a
 * href="https://aws.amazon.com/lambda/">AWS Lambda</a>
 */
public class LambdaProducer extends DefaultProducer {

    private static final Logger LOG = LoggerFactory.getLogger(LambdaProducer.class);

    public LambdaProducer(final Endpoint endpoint) {
        super(endpoint);
    }

    @Override
    public void process(final Exchange exchange) throws Exception {
        switch (determineOperation(exchange)) {
            case getFunction:
                getFunction(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case createFunction:
                createFunction(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case deleteFunction:
                deleteFunction(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case invokeFunction:
                invokeFunction(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case listFunctions:
                listFunctions(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case updateFunction:
                updateFunction(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case createEventSourceMapping:
                createEventSourceMapping(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case deleteEventSourceMapping:
                deleteEventSourceMapping(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case listEventSourceMapping:
                listEventSourceMapping(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case listTags:
                listTags(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case tagResource:
                tagResource(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case untagResource:
                untagResource(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case publishVersion:
                publishVersion(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case listVersions:
                listVersions(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case createAlias:
                createAlias(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case deleteAlias:
                deleteAlias(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case getAlias:
                getAlias(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            case listAliases:
                listAliases(getEndpoint().getAwsLambdaClient(), exchange);
                break;
            default:
                throw new IllegalArgumentException("Unsupported operation");
        }
    }

    private void getFunction(AWSLambda lambdaClient, Exchange exchange) {
        GetFunctionResult result;
        try {
            result = lambdaClient.getFunction(new GetFunctionRequest().withFunctionName(getEndpoint().getFunction()));
        } catch (AmazonServiceException ase) {
            LOG.trace("getFunction command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void deleteFunction(AWSLambda lambdaClient, Exchange exchange) {
        DeleteFunctionResult result;
        try {
            result = lambdaClient.deleteFunction(new DeleteFunctionRequest().withFunctionName(getEndpoint().getFunction()));
        } catch (AmazonServiceException ase) {
            LOG.trace("deleteFunction command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void listFunctions(AWSLambda lambdaClient, Exchange exchange) {
        ListFunctionsResult result;
        try {
            result = lambdaClient.listFunctions();
        } catch (AmazonServiceException ase) {
            LOG.trace("listFunctions command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void invokeFunction(AWSLambda lambdaClient, Exchange exchange) {
        InvokeResult result;
        try {
            InvokeRequest request = new InvokeRequest()
                    .withFunctionName(getEndpoint().getFunction())
                    .withPayload(exchange.getIn().getBody(String.class));
            result = lambdaClient.invoke(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("invokeFunction command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(StandardCharsets.UTF_8.decode(result.getPayload()).toString());
    }

    private void createFunction(AWSLambda lambdaClient, Exchange exchange) throws Exception {
        CreateFunctionResult result;

        try {
            CreateFunctionRequest request = new CreateFunctionRequest()
                    .withFunctionName(getEndpoint().getFunction());

            FunctionCode functionCode = new FunctionCode();
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_BUCKET))) {
                String s3Bucket = exchange.getIn().getHeader(LambdaConstants.S3_BUCKET, String.class);
                functionCode.withS3Bucket(s3Bucket);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_KEY))) {
                String s3Key = exchange.getIn().getHeader(LambdaConstants.S3_KEY, String.class);
                functionCode.withS3Key(s3Key);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_OBJECT_VERSION))) {
                String s3ObjectVersion = exchange.getIn().getHeader(LambdaConstants.S3_OBJECT_VERSION, String.class);
                functionCode.withS3ObjectVersion(s3ObjectVersion);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.ZIP_FILE))) {
                String zipFile = exchange.getIn().getHeader(LambdaConstants.ZIP_FILE, String.class);
                File fileLocalPath = new File(zipFile);
                try (FileInputStream inputStream = new FileInputStream(fileLocalPath)) {
                    functionCode.withZipFile(ByteBuffer.wrap(IOUtils.toByteArray(inputStream)));
                }
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getBody())) {
                functionCode.withZipFile(exchange.getIn().getBody(ByteBuffer.class));
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getBody())
                    || (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_BUCKET)) && ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_KEY)))) {
                request.withCode(functionCode);
            } else {
                throw new IllegalArgumentException("At least S3 bucket/S3 key or zip file must be specified");
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.ROLE))) {
                request.withRole(exchange.getIn().getHeader(LambdaConstants.ROLE, String.class));
            } else {
                throw new IllegalArgumentException("Role must be specified");
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.RUNTIME))) {
                request.withRuntime(exchange.getIn().getHeader(LambdaConstants.RUNTIME, String.class));
            } else {
                throw new IllegalArgumentException("Runtime must be specified");
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.HANDLER))) {
                request.withHandler(exchange.getIn().getHeader(LambdaConstants.HANDLER, String.class));
            } else {
                throw new IllegalArgumentException("Handler must be specified");
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.DESCRIPTION))) {
                String description = exchange.getIn().getHeader(LambdaConstants.DESCRIPTION, String.class);
                request.withDescription(description);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.TARGET_ARN))) {
                String targetArn = exchange.getIn().getHeader(LambdaConstants.TARGET_ARN, String.class);
                request.withDeadLetterConfig(new DeadLetterConfig().withTargetArn(targetArn));
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.MEMORY_SIZE))) {
                Integer memorySize = exchange.getIn().getHeader(LambdaConstants.MEMORY_SIZE, Integer.class);
                request.withMemorySize(memorySize);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.KMS_KEY_ARN))) {
                String kmsKeyARN = exchange.getIn().getHeader(LambdaConstants.KMS_KEY_ARN, String.class);
                request.withKMSKeyArn(kmsKeyARN);
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.PUBLISH))) {
                Boolean publish = exchange.getIn().getHeader(LambdaConstants.PUBLISH, Boolean.class);
                request.withPublish(publish);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.TIMEOUT, Integer.class);
                request.withTimeout(timeout);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.TRACING_CONFIG))) {
                String tracingConfigMode = exchange.getIn().getHeader(LambdaConstants.TRACING_CONFIG, String.class);
                request.withTracingConfig(new TracingConfig().withMode(tracingConfigMode));
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT, Integer.class);
                request.withSdkClientExecutionTimeout(timeout);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT, Integer.class);
                request.withSdkRequestTimeout(timeout);
            }

            Map<String, String> environmentVariables = CastUtils.cast(exchange.getIn().getHeader(LambdaConstants.ENVIRONMENT_VARIABLES, Map.class));
            if (environmentVariables != null) {
                request.withEnvironment(new Environment().withVariables(environmentVariables));
            }

            Map<String, String> tags = CastUtils.cast(exchange.getIn().getHeader(LambdaConstants.TAGS, Map.class));
            if (tags != null) {
                request.withTags(tags);
            }

            List<String> securityGroupIds = CastUtils.cast(exchange.getIn().getHeader(LambdaConstants.SECURITY_GROUP_IDS, (Class<List<String>>) (Object) List.class));
            List<String> subnetIds = CastUtils.cast(exchange.getIn().getHeader(LambdaConstants.SUBNET_IDS, (Class<List<String>>) (Object) List.class));
            if (securityGroupIds != null || subnetIds != null) {
                VpcConfig vpcConfig = new VpcConfig();
                if (securityGroupIds != null) {
                    vpcConfig.withSecurityGroupIds(securityGroupIds);
                }
                if (subnetIds != null) {
                    vpcConfig.withSubnetIds(subnetIds);
                }
                request.withVpcConfig(vpcConfig);
            }
            result = lambdaClient.createFunction(request);

        } catch (AmazonServiceException ase) {
            LOG.trace("createFunction command returned the error code {}", ase.getErrorCode());
            throw ase;
        }

        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void updateFunction(AWSLambda lambdaClient, Exchange exchange) throws Exception {
        UpdateFunctionCodeResult result;

        try {
            UpdateFunctionCodeRequest request = new UpdateFunctionCodeRequest()
                    .withFunctionName(getEndpoint().getFunction());

            FunctionCode functionCode = new FunctionCode();
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_BUCKET))) {
                String s3Bucket = exchange.getIn().getHeader(LambdaConstants.S3_BUCKET, String.class);
                functionCode.withS3Bucket(s3Bucket);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_KEY))) {
                String s3Key = exchange.getIn().getHeader(LambdaConstants.S3_KEY, String.class);
                functionCode.withS3Key(s3Key);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.S3_OBJECT_VERSION))) {
                String s3ObjectVersion = exchange.getIn().getHeader(LambdaConstants.S3_OBJECT_VERSION, String.class);
                functionCode.withS3ObjectVersion(s3ObjectVersion);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.ZIP_FILE))) {
                String zipFile = exchange.getIn().getHeader(LambdaConstants.ZIP_FILE, String.class);
                File fileLocalPath = new File(zipFile);
                try (FileInputStream inputStream = new FileInputStream(fileLocalPath)) {
                    functionCode.withZipFile(ByteBuffer.wrap(IOUtils.toByteArray(inputStream)));
                }
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getBody())) {
                functionCode.withZipFile(exchange.getIn().getBody(ByteBuffer.class));
            }

            if (ObjectHelper.isEmpty(exchange.getIn().getBody())
                    && (ObjectHelper.isEmpty(exchange.getIn().getHeader(LambdaConstants.S3_BUCKET)) && ObjectHelper.isEmpty(exchange.getIn().getHeader(LambdaConstants.S3_KEY)))) {
                throw new IllegalArgumentException("At least S3 bucket/S3 key or zip file must be specified");
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.PUBLISH))) {
                Boolean publish = exchange.getIn().getHeader(LambdaConstants.PUBLISH, Boolean.class);
                request.withPublish(publish);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT, Integer.class);
                request.withSdkClientExecutionTimeout(timeout);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT, Integer.class);
                request.withSdkRequestTimeout(timeout);
            }

            result = lambdaClient.updateFunctionCode(request);

        } catch (AmazonServiceException ase) {
            LOG.trace("updateFunction command returned the error code {}", ase.getErrorCode());
            throw ase;
        }

        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void createEventSourceMapping(AWSLambda lambdaClient, Exchange exchange) {
        CreateEventSourceMappingResult result;
        try {
            CreateEventSourceMappingRequest request = new CreateEventSourceMappingRequest().withFunctionName(getEndpoint().getFunction());
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.EVENT_SOURCE_ARN))) {
                request.withEventSourceArn(exchange.getIn().getHeader(LambdaConstants.EVENT_SOURCE_ARN, String.class));
            } else {
                throw new IllegalArgumentException("Event Source Arn must be specified");
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.EVENT_SOURCE_BATCH_SIZE))) {
                Integer batchSize = exchange.getIn().getHeader(LambdaConstants.EVENT_SOURCE_BATCH_SIZE, Integer.class);
                request.withBatchSize(batchSize);
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT, Integer.class);
                request.withSdkClientExecutionTimeout(timeout);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT, Integer.class);
                request.withSdkRequestTimeout(timeout);
            }
            result = lambdaClient.createEventSourceMapping(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("createEventSourceMapping command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void deleteEventSourceMapping(AWSLambda lambdaClient, Exchange exchange) {
        DeleteEventSourceMappingResult result;
        try {
            DeleteEventSourceMappingRequest request = new DeleteEventSourceMappingRequest();
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.EVENT_SOURCE_UUID))) {
                request.withUUID(exchange.getIn().getHeader(LambdaConstants.EVENT_SOURCE_UUID, String.class));
            } else {
                throw new IllegalArgumentException("Event Source Arn must be specified");
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT, Integer.class);
                request.withSdkClientExecutionTimeout(timeout);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT, Integer.class);
                request.withSdkRequestTimeout(timeout);
            }
            result = lambdaClient.deleteEventSourceMapping(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("deleteEventSourceMapping command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void listEventSourceMapping(AWSLambda lambdaClient, Exchange exchange) {
        ListEventSourceMappingsResult result;
        try {
            ListEventSourceMappingsRequest request = new ListEventSourceMappingsRequest().withFunctionName(getEndpoint().getFunction());
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_CLIENT_EXECUTION_TIMEOUT, Integer.class);
                request.withSdkClientExecutionTimeout(timeout);
            }

            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT))) {
                Integer timeout = exchange.getIn().getHeader(LambdaConstants.SDK_REQUEST_TIMEOUT, Integer.class);
                request.withSdkRequestTimeout(timeout);
            }
            result = lambdaClient.listEventSourceMappings(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("listEventSourceMapping command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void listTags(AWSLambda lambdaClient, Exchange exchange) {
        ListTagsResult result;
        try {
            ListTagsRequest request = new ListTagsRequest();
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.RESOURCE_ARN))) {
                String resource = exchange.getIn().getHeader(LambdaConstants.RESOURCE_ARN, String.class);
                request.withResource(resource);
            } else {
                throw new IllegalArgumentException("The resource ARN must be specified");
            }
            result = lambdaClient.listTags(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("listTags command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void tagResource(AWSLambda lambdaClient, Exchange exchange) {
        TagResourceResult result;
        try {
            TagResourceRequest request = new TagResourceRequest();
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.RESOURCE_ARN))) {
                String resource = exchange.getIn().getHeader(LambdaConstants.RESOURCE_ARN, String.class);
                request.withResource(resource);
            } else {
                throw new IllegalArgumentException("The resource ARN must be specified");
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.RESOURCE_TAGS))) {
                Map<String, String> tags = exchange.getIn().getHeader(LambdaConstants.RESOURCE_TAGS, Map.class);
                request.withTags(tags);
            } else {
                throw new IllegalArgumentException("The tags must be specified");
            }
            result = lambdaClient.tagResource(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("listTags command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void untagResource(AWSLambda lambdaClient, Exchange exchange) {
        UntagResourceResult result;
        try {
            UntagResourceRequest request = new UntagResourceRequest();
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.RESOURCE_ARN))) {
                String resource = exchange.getIn().getHeader(LambdaConstants.RESOURCE_ARN, String.class);
                request.withResource(resource);
            } else {
                throw new IllegalArgumentException("The resource ARN must be specified");
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.RESOURCE_TAG_KEYS))) {
                List<String> tagKeys = exchange.getIn().getHeader(LambdaConstants.RESOURCE_TAG_KEYS, List.class);
                request.withTagKeys(tagKeys);
            } else {
                throw new IllegalArgumentException("The tag keys must be specified");
            }
            result = lambdaClient.untagResource(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("untagResource command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void publishVersion(AWSLambda lambdaClient, Exchange exchange) {
        PublishVersionResult result;
        try {
            PublishVersionRequest request = new PublishVersionRequest().withFunctionName(getEndpoint().getFunction());
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.VERSION_DESCRIPTION))) {
                String description = exchange.getIn().getHeader(LambdaConstants.VERSION_DESCRIPTION, String.class);
                request.withDescription(description);
            }
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.VERSION_REVISION_ID))) {
                String revisionId = exchange.getIn().getHeader(LambdaConstants.VERSION_REVISION_ID, String.class);
                request.withRevisionId(revisionId);
            }
            result = lambdaClient.publishVersion(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("publishVersion command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void listVersions(AWSLambda lambdaClient, Exchange exchange) {
        ListVersionsByFunctionResult result;
        try {
            ListVersionsByFunctionRequest request = new ListVersionsByFunctionRequest().withFunctionName(getEndpoint().getFunction());
            result = lambdaClient.listVersionsByFunction(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("publishVersion command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void createAlias(AWSLambda lambdaClient, Exchange exchange) {
        CreateAliasResult result;
        try {
            CreateAliasRequest request = new CreateAliasRequest().withFunctionName(getEndpoint().getFunction());
            String version = exchange.getIn().getHeader(LambdaConstants.FUNCTION_VERSION, String.class);
            String aliasName = exchange.getIn().getHeader(LambdaConstants.FUNCTION_ALIAS_NAME, String.class);
            if (ObjectHelper.isEmpty(version) || ObjectHelper.isEmpty(aliasName)) {
                throw new IllegalArgumentException("Function Version and alias must be specified to create an alias");
            }
            request.setFunctionVersion(version);
            request.setName(aliasName);
            if (ObjectHelper.isNotEmpty(exchange.getIn().getHeader(LambdaConstants.FUNCTION_ALIAS_DESCRIPTION))) {
                String aliasDescription = exchange.getIn().getHeader(LambdaConstants.FUNCTION_ALIAS_DESCRIPTION, String.class);
                request.setDescription(aliasDescription);
            }
            result = lambdaClient.createAlias(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("createAlias command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void deleteAlias(AWSLambda lambdaClient, Exchange exchange) {
        DeleteAliasResult result;
        try {
            DeleteAliasRequest request = new DeleteAliasRequest().withFunctionName(getEndpoint().getFunction());
            String aliasName = exchange.getIn().getHeader(LambdaConstants.FUNCTION_ALIAS_NAME, String.class);
            if (ObjectHelper.isEmpty(aliasName)) {
                throw new IllegalArgumentException("Function alias must be specified to delete an alias");
            }
            request.setName(aliasName);
            result = lambdaClient.deleteAlias(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("deleteAlias command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void getAlias(AWSLambda lambdaClient, Exchange exchange) {
        GetAliasResult result;
        try {
            GetAliasRequest request = new GetAliasRequest().withFunctionName(getEndpoint().getFunction());
            String aliasName = exchange.getIn().getHeader(LambdaConstants.FUNCTION_ALIAS_NAME, String.class);
            if (ObjectHelper.isEmpty(aliasName)) {
                throw new IllegalArgumentException("Function alias must be specified to get an alias");
            }
            request.setName(aliasName);
            result = lambdaClient.getAlias(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("getAlias command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private void listAliases(AWSLambda lambdaClient, Exchange exchange) {
        ListAliasesResult result;
        try {
            ListAliasesRequest request = new ListAliasesRequest().withFunctionName(getEndpoint().getFunction());
            String version = exchange.getIn().getHeader(LambdaConstants.FUNCTION_VERSION, String.class);
            if (ObjectHelper.isEmpty(version)) {
                throw new IllegalArgumentException("Function Version must be specified to list aliases for a function");
            }
            request.withFunctionVersion(version);
            result = lambdaClient.listAliases(request);
        } catch (AmazonServiceException ase) {
            LOG.trace("listAliases command returned the error code {}", ase.getErrorCode());
            throw ase;
        }
        Message message = getMessageForResponse(exchange);
        message.setBody(result);
    }

    private LambdaOperations determineOperation(Exchange exchange) {
        LambdaOperations operation = exchange.getIn().getHeader(LambdaConstants.OPERATION, LambdaOperations.class);
        if (operation == null) {
            operation = getConfiguration().getOperation() == null ? LambdaOperations.invokeFunction : getConfiguration().getOperation();
        }
        return operation;
    }

    protected LambdaConfiguration getConfiguration() {
        return getEndpoint().getConfiguration();
    }

    @Override
    public LambdaEndpoint getEndpoint() {
        return (LambdaEndpoint) super.getEndpoint();
    }

    public static Message getMessageForResponse(final Exchange exchange) {
        return exchange.getMessage();
    }

}


text:
New Light on Fetal Origins of Adult Disease
Human prenatal development can be viewed as a program of genetic switches that turn on, in a highly regulated manner, at specific places and times. But a body of evidence is emerging that paints a less hardwired picture, one of responses to environmental challenges fostering changes early on that reverberate decades later, in the guise of cardiovascular disease and diabetes. A symposium at the American Society of Human Genetics annual meeting, held in Philadelphia Oct. 3-7, addressed the fetal o
Aerial shot of the HHMI's Maryland headquarters. On a pristine 23-acre campus in Maryland located just a few miles from the National Institutes of Health, a handful of scientists decides how America's richest privately held biomedical research organization should distribute more than $500 million in funding annually. But the Howard Hughes Medical Institute, perhaps America's most prestigious patron of biomedical research, has undergone a changing of the guard at its Chevy Chase headquarters in t
H-1B Visas Up, Quotas Down
On October 17, the "American Competitiveness in the Twenty-First Century Act of 2000" became law.1 President Bill Clinton signed the bill on the last day he could do so, during his flight back from the Middle East summit.2 The law's most publicized provision directs the Immigration and Naturalization Service (INS) to issue 70 percent more H-1B visas, which permit foreigners to work in the United States. But the law includes a host of more obscure changes that should help life scientists struggli
Posting Progress
In the beginning, there were no posters. Now, many scientific meetings have thousands of them. At the 50th meeting of the American Society of Human Genetics (ASHG) in Philadelphia, Oct. 4-7, scientists signed up for 2,147 posters, compared to 287 slide presentations. Douglas Marchuk, associate professor in the department of genetics at Duke University, and this year's head of the ASHG program committee, describes the poster evolution this way: "In l977 and l978 they were all slide sessions. In
GM Food Debate Gets Spicy
Whether sitting down to a relaxing dinner or grabbing fast food, people don't think about the origin of every ingredient in the food they eat. But as biotechnology applications in commercial agriculture increase, controversy over the risks versus the benefits also continues to rise. In mid-September, public citizen groups, including Genetically Engineered Food Alert and the Union of Concerned Scientists, requested a recall of taco shells that allegedly contained genetically engineered corn. Inde
T Awareness
The presidential campaign has focused heavily on topics such as taxes, health care, and the elderly. Yet there are other issues on which the presidential administration will have a significant impact as well. A recent Gallup survey shows that science and technology issues may influence Americans' presidential choice.1 The survey reveals that more than two-thirds of those polled support recent budget proposals to significantly increase federal spending for scientific research and development. Sev
From Freedom Ride to Gender-based Biology
Barbara Mikulski If there is more "bullwhip and buzz saw" than "serenade by starlight" in the persona of U.S. Sen. Barbara A. Mikulski (D-Md.), it's because she isn't afraid to batter feelings in fighting for what she believes in. Certainly, not everyone likes the outspoken way she cuts through business-as-usual in pursuit of her goals. "Barbara, you just don't have a therapeutic personality," is how one of her teachers once put it, and Mikulski proudly declares that Ronald Reagan, George Bush,
Defining Genetics On Oct. 3, in a prelude to the 50th meeting of the American Society of Human Genetics in Philadelphia, several hundred geneticists attended a one-day international conference on the genetics of complex diseases. Organized by the National Disease Research Interchange, a Philadelphia-based nonprofit coordinating organization, the agenda included sessions on the genetics of thyroid disease, type I diabetes, and autism. The first session, "Defining the Genetics of Complex Disease
Koch's Postulates Revisited
In his criticism of scientists who find Koch's postulates obsolete,1 Todd Miller overlooks one important point. Recruiting volunteers to apply Koch's postulates to diseases such as Ebola fever and AIDS has been somewhat difficult of late. There was a time when prisoners would do, but we've outgrown that practice. Koch's postulates may or may not be obsolete, but they are not universal. David Carlberg, Ph.D. Professor Department of Biological Sciences California State University Long Beach,
The Global Agenda
In his commentary on science and the global agenda,1 Bruce Alberts pointed out the distressing disregard for science prevalent in many parts of the world in relation to evolution, genetically altered foods, and AIDS. He emphasized that to counter these anti-scientific attitudes and contribute to solutions for the serious problems associated with rapid growth of the world population, scientific societies "must take a more active role in helping political leaders and the public make informed decis
Are reviewers biased against unconventional therapies?
The peer-review process can be seen as a method of quality assessment, so my colleagues and I tested the hypothesis that this method is prone to bias.1 Specifically, our hypothesis was that journal reviewers would be more critical toward a manuscript relating to a study of an unconventional therapy as compared to a study of conventional treatment. Two versions were produced (A and B) of a 'short report' that related to treatments of obesity, identical except for the nature of the interven
Genetic Responses to Drought
A consensus grass comparative map shows how grass genomes line up. When the well's dry, we know the worth of water," wrote Benjamin Franklin under his Poor Richard alias. Not much has changed in 250 years as the United States, suffering one of the most devastating droughts in 90 years, painfully learns water's worth. The situation is gravest in the Southwest, which is enduring its fourth year of drought in five years. The U.S. Department of Agriculture continues to add more counties to its list
The Jury is Still Out on Soy In the search for a breast cancer preventive, soy has been considered a promising candidate. But a review of research on soy's phytoestrogen genistein (K.B. Bouker, L. Hilakivi-Clarke, "Genistein: Does it prevent or promote breast cancer," Environmental Health Perspectives, 108:70-8, August 2000) is lukewarm on the compound's preventative capabilities. "There is no strong evidence that genistein would actually prevent breast cancer, but there is no strong evidence
The Biological Basis for Atherosclerosis
For this article, Jennifer Fisher Wilson interviewed Ronald M. Evans, Howard Hughes Medical Institute investigator and director of the Gene Expression Laboratory at the Salk Institute for Biological Studies in La Jolla, Calif., and Peter Tontonoz, now assistant HHMI investigator and assistant professor in the pathology and laboratory medicine department at University of California, Los Angeles. Data from the Web of Science (ISI, Philadelphia) show that Hot Papers are cited 50 to 100 times more o
Web of Information
LabVelocity's Home Page In the fast-paced world of biotechnology and drug discovery, efficiency is key; as a time-saving resource, the Internet has been a widely used tool for expediting the collection of information needed to drive the research process. According to a recent survey, researchers spend an average of 66 minutes a day using the Internet at work.1 Much of this time is spent either looking for product and technical information or making online purchases of research supplies.
A Quantum Leap in mRNA Quantitation
Cytokines, unique growth factors that are secreted by various cells of the body, include interleukins (ILs), interferons (IFNs), and tumor necrosis factors (TNFs). These proteins bind to target cell surface receptors and activate cell proliferation and/or differentiation. Until recently, research that quantifies levels of cytokine-specific mRNA using traditional methods such as the northern blot, slot blot, quantitative RT-PCR, and ribonuclease protection assay (RPA) has been labor-intensive and
Stand and Be Counted
Until recently, researchers interested in analyzing their arrays or gels had to rely on complex software packages or manual analysis subject to human error. NonLinear Dynamics Ltd. of Newcastle upon Tyne, U.K., known to the research community for its Phoretix software, now offers TotalLab image analysis software, which combines the analyzing power of pre-existing Phoretix products with a user-friendly interface. Instead of requiring users to invest a considerable amount of time to learn the soft
Array of Assays
Protein Assay Manufacturers and Products From the decades-old biuret reaction to the use of complicated fluorescent molecules, the search for an easy, reliable, and stable method for the quantitation of total protein in solution has gone on for more than 80 years. Although several famous, innovative, and useful techniques were developed over that time, the search continues. Bob Vigna, marketing manager for industry leader Pierce Chemical Co. of Rockford, Ill., confirms this observation. "The u
Taking It Higher
Nuclear Magnetic Resonance (NMR) spectroscopy has become an extremely familiar analytical tool in chemistry and biochemistry laboratories. Even researchers with little exposure to the technique recognize that NMR can provide a great deal of information about everything from the acetone content of a poorly prepared undergraduate chemistry lab sample to the structure and dynamics of complex biomolecules. In recent years the analytical potential of NMR has expanded, offering researchers a growing a
Winning, Managing, and Renewing Grants
They say it's a publish-or-perish world in science, but how can you stay alive if you don't have any support? With grant proposal return rates at all-time highs for many granting bodies, how can you make your proposals pass muster, let alone sing? "It's the very simple things that can cause an application to fail," says Jackie Roberts, manager of career resources at the Federation of American Societies of Experimental Biology. "Read the instructions. Read the instructions. Read the instructions.
With this issue, The Scientist introduces a new regular feature. "Funding Opportunities in the Life Sciences" will list a selection of sources who are offering funding for life science research. Organizations are welcome to submit information for future listings by contacting kdevine@the-scientist.com Click to view the PDF file: Funding Opportunities in the Life Sciences
Stamp of Approval Thirty-two researchers at institutions located in 15 states plus Australia and Israel have received grants that were funded through the sale of postage stamps. The National Cancer Institute (NCI) recently awarded the grants under the Insight Awards to Stamp Out Breast Cancer program. A 1997 law set up the program, which allows for contributions to breast cancer research funding to come from the sale of a first-class stamp for 40 cents. The funding is divided between the Nation
Research Assessment and Citation Analysis
Research Assessment Exercises (RAE) were conducted in the United Kingdom in 1992 and 1996. The grades obtained by university departments determined the ratios with which public funds were to be distributed to universities to support research infrastructure, within a centralized and publicly funded university system. Other geopolitical regions would have comparable exercises, although with different approaches to research evaluation, and initial information about specific criteria and procedures

redpajama_set_name: RedPajamaCommonCrawl


As anyone familiar with this blog knows, I homeschool my kids. I'm really not a fanatic about homeschooling, in general. It's something we do for many, many reasons, but I wouldn't presume to tell other people what they should do. I'm perfectly willing to accept the idea that public schools are the best choice for many families. However, like many homeschoolers, I sometimes find myself completely dumbfounded at the fact that many people and their kids go through horrific things in schools – and keep sending their kids back!
I know that my perspective is different because I do homeschool and it's for reasons far less pressing than protecting my kids from violence or sexual abuse or something like that. So I suppose that having taken the step of removing my kids from the school system for relatively benign reasons it is hard for me to fathom why the parents keep sending their kids back to schools where there children are exposed to violence, educational malfeasance or damage done to children by the mind boggling lack of common sense sometimes demonstrated by schools.
A boy who has required repeated medical treatment due to ongoing bullying.
Children as young as four being labeled sexual predators.
Schools where violent assaults and robbery are daily events.
Students who spend 12 years in school without mastering 8th grade math.
Strip searching a 13 year old honors student to search for ibuprofen.
I could find more, but these are just the ones I happened across today. I know that these sorts of things don't happen everywhere, but when they do, why do parents continue to send their kids to the school? I know people have jobs, but in some of these cases, you're talking about things which go on for years – more than enough time to find a job on the swing shift or with flex time or whatever. But to allow your child to be bullied for years and keep sending him or her back? And if your kid's not being taught reading and math at school – how much worse can you really do with them at home? Or having your 4 year old labeled a sexual predator because he put his face in his teacher's chest while getting a hug – and you trust these people with your child day after day and year after year? I just don't get it.
« Older Post Raising Christian Evolutionists	» Newer Post Ain't that the truth?
Neither do I. How long would would an adult stay at a job where things like that happened? Unfortunately, I think many people have been conditioned to think that they have no choice.


text:
Why Partner With Us
Organisations may want to work with Queen Margaret University to develop teaching partnerships for various reasons:
Institutions without degree-awarding powers may want to offer their students a recognised academic qualification.
Institutions who do have degree-awarding powers in their own country may want to offer a joint or dual award that gives their students an international experience and is more easily transportable around the world.
Institutions may want to share their expertise with ours in order to deliver a degree that neither partner could fully support on its own.
Here at QMU we have been working with partners since the 1990s. Our earliest partnerships were with St Columba's Hospice, local NHS trusts and private education providers in India and Greece. Over the years we have developed considerable expertise in supporting partner organisations and have well-established procedures for quality assurance and staff development.
The Quality Assurance Agency has included QMU's collaborative provision in its reviews and concluded that QMU has "... an effective set of arrangements that meet sector expectations and are underpinned by robust policies and procedures, in particular programme approval, annual monitoring and review, and thorough processes for the quality assurance of assessment. Partnerships are well supported through Academic Link staff, the operation of Joint Boards of Study, a range of useful guidance and extensive development opportunities."
More information about the different ways in which we work with partners is set out below.
Teaching Collaboration
A partner may work with QMU to offer a taught degree. Normally the degree will be delivered by the partner with QMU providing academic guidance and quality assurance. Graduates would receive a QMU degree certificate. Partners who have degree awarding powers of their own may wish to develop a joint or dual award.
QMU also collaborates with external partners to deliver and quality assure short programmes (shorter than a full degree but assessed at degree level).
For more information see the QMU collaborative model.
Please note that we will only consider partnerships in subject areas where we have the academic expertise to support the programme. Please review our list of subjects and degree programmes to confirm whether the programme you want to develop fits with our portfolio.
Formal articulation agreements may be made, whereby QMU recognises another institution's qualification as conferring eligibility for entry with advanced standing to a QMU programme. For instance, QMU may allow graduates of an institution's Diploma to enter directly into the third year of an undergraduate degree. We would need to confirm that the curriculum of the partner's diploma matched with the related QMU degree. We may also ask for evidence of the academic level of the diploma in order to map it against the Scottish Credit and Qualifications Framework.
Third Party Credit Rating
Organisations may ask QMU to undertake credit rating of their programmes. This means that QMU will make a judgement as to how many credits the programme is worth within the Scottish Credit and Qualifications Framework. QMU will not play a major role in the day-to-day quality assurance of the programme and students will not matriculate with the University. The partner may issue certificates with an award of credit but QMU will not award credit directly.
This option is normally suitable for short programmes, as opposed to full degrees or diplomas.
Local Support Centre
An overseas organisation may provide support services for students undertaking a distance learning programme from QMU. Normally the services will extend to the provision of facilities and assistance with admissions, although some academic tutorial support may also be agreed. Only a limited number of QMU programmes are suitable for distance learning delivery – check the QMU list of programmes.
Staff and student exchanges may be possible in shared disciplines. Exchanges are normally only suitable for programmes which are delivered in English. Contact the International Office for more information.
QMU staff may wish to collaborate with other institutions on specific research projects. Such projects would normally be set up through direct links between researchers.
Joint PhDs are possible. In some cases there will be an informal arrangement to share supervision. For an award which is made jointly by both institutions, formal governance and shared regulation agreements need to be made. Contact the QMU Graduate School if you want to explore this option.
Do you have a partnership proposal? Please read the information above to confirm whether Queen Margaret University looks like the right type of partner for you. Then contact partnerships@qmu.ac.uk with the specifics of your proposal.
Collaborations and Partnership Development
Sheila Adamson Partnership Development Manager
A proud participant of the QE-TNE Scheme
@QMUniversity tweeted 23 hour(s) ago


Experience all the Garden Route has to offer by making Hunters Country House your home as you explore this magnificent part of South Africa.
Hunters Country House is the perfect family getaway. It is a fun, secure place for children of all ages to play and have a holiday where even the youngest of guests is pampered. We make sure children feel like they have come home to 5 star luxury, surrounded by the forest and beautiful grounds.
For the younger children Cubs Corner is a designated area with a small paddling pool, climbing frames, sand pit and the Cubhouse, where they can watch videos, paint, draw and play games. Cubs Corner caters for children 0 – 6 years. Should parents wish to have their children looked after at Cubs Corner or require baby sitting facilities this can be pre-arranged prior to their arrival.
Hunters Country House will ensure that children of all ages are catered for from a dining perspective with a children's menu available for lunch.
The opportunity for children to experience a holiday in South Africa and especially on the Garden Route is a treat and we want to ensure that when they stay with us they are pampered and kept entertained, making their holiday a special one, which they will want to repeat.
Your wedding day is unquestionably the most important day of your lives together, knowing this, we tailor make all arrangements to ensure special attention is paid to every detail making it seamless and memorable.
Our intimate "Chapel in the Forest" is the perfect setting. Vows are proclaimed while being framed by floor to ceiling windows overlooking the valley of indigenous forest. The "Chapel in the Forest" can seat up to 50 guests to share this moment with you.
For the reception, Tsala's unique dining room or Zinzi Restaurant offer 2 bespoke venues that can be transformed into the reception venue of your dreams.
Hunters Country House's team believe that every bride and groom deserve to have their dream wedding become a reality and thus every details of your wedding can be arranged for you or only the relevant venues be provided all depending on what you wish your day to be like.
Your weddings requirements will be tailor-made by our wedding planner to suit your specific needs. Please contact her directly by email weddings@hunterhotels.com or at our Head Office on +27 (0) 44 501 1111 to arrange a consultation.
Nothing says romance quite like a crystal infinity pool, champagne on a private deck overlooking the forest, a cosy fireplace to snuggle at and the magic of being on honeymoon with the love of your life.
A honeymoon spent at Hunters Country House is all about romance and passion. Let your days filled with intimate moments, unforgettable scenery and memories shared for a lifetime.
Birds of Eden is the Garden Route's very own world class free flight bird sanctuary. The unique two-hectare dome (the World's largest) spans over a gorge of indigenous forest and is sanctuary to a myriad of birds that can be viewed up close.
Birds of Eden was developed to create a safe environment in which to release a large collection of free-flight African birds and miniature monkeys. The sanctuary also allows bird owners to apply to release their pet birds into the sanctuary, after undergoing the necessary rehabilitation.
The aviary is open for you to roam around, no guide is required so you may spend as much time as you like watching the birds.
Just you, a board, the river and nature! Stand-up paddle through the deep ravines & indigenous forest on the quiet beauty of the Keurbooms River with the call of the Fish Eagle and the flash of the Knysna Loerie (Turaco) overhead for company.
The SUP river boat takes you on a 4.5km cruise up to Whiskey Creek where your guide will lead you into the non-motorized zone of the river: re-invigorate your body, absorb the serenity of the river, re-connect with your soul.
At Monkeyland guests have the rare opportunity to walk amongst these fascinating creatures, that remind us so much of ourselves.
On the guided safaris you can expect to see a variety of primates, ranging from the Gibbons of Asia to the Lemurs of Madagascar. The knowledgeable rangers will tell you about these fascinating mammals as you encounter them roaming free in the forest. They also point out, identify and explain the many wonders of life in the forest, from the rich diversity of bird life to the intricate workings of the forest itself.
This exclusive offering to Hunter Hotel guests, allows you to glide up the deep ravine of the Keurbooms River. Moor at the sandy cove at Whiskey Creek where you can enjoy a walk through the indigenous forest, swim in the gentle waters, sip on sparkling wine and relax in natural splendour. A glorious end to a perfect day.
What better way to see these beautiful sea creatures than by boat, with a knowledgeable guide who will share interesting information about why they are so important to the balance of nature.
In summer you have a very good chance of spotting the rare, gregarious Humpback Dolphins found in only certain areas of the South African coastline. You can also likely to see Bottlenose Dolphins and Common Dolphin. We will take you to the Robberg Seal Colony, the natural habitat of about 5,000 noisy, fun-loving seals.
In winter there is a very high likelihood that you will see the Southern Right and Humpback whales. Tours include the Robberg Seal Colony (home to +/- 5000 seals) and other marine life of the day.
This exciting adventure takes you out to sea to snorkel with these fun loving creatures, watching them playing and frolicking in the waves.
If you looking for a fun ocean adventure, this is for you. This tour is a first for Plettenberg Bay. It is an experience that will leave you with an invigorated appreciation of the beauty of the ocean and the wonderful animals that inhabit it.
The Keurbooms River in Plett and the Knysna lagoon are two of the most picturesque waterways on the Garden Route. Take a leisurely boat trip to kickback and experience the pristine natural beauty of the area.
Travel upstream between the gorge walls of the un-spoilt Keurbooms Nature Reserve by ferry and enjoy the scenic beauty of the area.
This trip takes you across the lagoon to the Western Head of the Nature Reserve, where a guide and a 4×4 buggy will take you up the headland into the private reserve, stopping at the spectacular viewpoints along the way. After your tour you can enjoy a buffet lunch at the outdoor restaurant under the Milkwood trees. There is also an optional 2.2km walk through coastal forest, fynbos and ocean caves.
Take a leisurely cruise around the Knysna Lagoon to the Heads on the double decker floating restaurant, the John Benn or the 4 star restaurant on the paddle-driven, Paddle Cruiser. Full bars are available on both boats.
Set sail aboard a luxury yacht for a cruise through the Knysna Heads, while enjoying a glass of South African sparkling wine and a seafood platter.
An experienced crew will take you sailing on the famous Knysna Lagoon in the Garden Route. Sail out past the Heads and towards Buffalo Bay. On return, anchor is weighed in the calm waters of the lagoon. Feast on a spread of delectable Mediterranean delicacies and enjoy a refreshing swim before returning to the quays. Witness incredible rock formations, caves, pelagic birds, whales and dolphins unique to this internationally acclaimed Eden.
Hold on and get ready for speed! Knysna and Plettenberg Bay offer high speed and high thrill boat rides in RIB Boats.
For those adrenalin-junkies wishing to get out on the water and feel the rush of the air as they speed down the coastline – this is not for the faint hearted.
(please be there 30 minutes before the time) and set departure times are applicable.
Plettenberg Bay is not only one of South Africa's most beautiful bays, but also one of the most perfect surfing destinations on the Garden Route.
Experienced surfers can head to the beach and enjoy some awesome rides while those wanting to learn have access to some of the best surf instructors in South Africa. These instructors will offer you a carefully designed programme that will have you up and riding in no time. We warn you, once you've experienced the thrill of dropping down the face of a wave and riding one of nature's wonders, you'll be hooked for life!
Experience the sea in a kayak and get a glimpse of Plettenberg Bay's beautiful mountain scenery and dramatic coastline from the ocean.
Kayak with an experienced guide from Central Beach to Robberg Nature Reserve. When you reach Robberg Nature Reserve you will kayak amongst the seals at the seal colony. Your guide will introduce you to Robberg Nature Reserve and our wonderful marine life in the bay. In whale season you will encounter these majestic mammals on your tour. All equipment is provided and beginners are welcome.
A Canopy Tour® takes you on an unforgettable adventure as you slide from one platform to the next along a series of steel cables set amongst magnificent natural surroundings.
Experience one of South Africa's fastest growing eco-adventures with thousands of satisfied thrill-seekers having already caught the bug. The scenery high up within the forest canopy is spectacular. Enjoy the view from above while taking in waterfalls and spotting birdlife in the surrounding trees. Professional guides will assure the safety of each group and point out interesting facts along the way.
Professional guides will assure the safety of each group and point out interesting facts along the way.
For those looking for extreme excitement – Bloukrans Bungy Jump is it! Bloukrans is the World's Highest Commercial Bungy Jump at a whooping 216m.
Once you are secured in a full body harness, you walk along a specially designed catwalk (216m long), which is suspended beneath the road surface. This leads you to the top of the arch – 216m above the Bloukrans River. Here you will be given final instructions by the highly experienced staff, a countdown and BUNGY!!
Bloukrans utilizes pendulum bungy technology ensuring you the smoothest, most comfortable bungy jump possible.
Free-fall over one of the most scenic drop zones in the world.
This thrilling experience begins with a short safety briefing. Then enjoy a 20-minute plane flight to 10,000 feet, over the Knysna forests and Plettenberg Bay coastline. Now the leisurely, scenic plane flight ends and the adrenaline starts to pump as you exit the plane with your Tandem Master and experience the rush of a 35 second free fall at 200KPH!
Either take a ride through the forests and hills of the surrounding area or experience a horse safari on a nature reserve and catch a glimpse of some of Southern Africa's wild animals.
There is no better way to view the game than from horses. The game is accustom to horses and so allows them to wonder up close. On horseback you can go to areas where vehicles can't access and are free to roam with the game or track them down. Feel the grass and bush brush past you, breathe in the fresh air around you and listen to the sounds of Africa.
Experiencing these majestic beasts in their natural environment is a once-in-a-lifetime opportunity. It is a wonderful privilege and an extreme adventure.
Mossel Bay (162km from the lodge) is renowned for its Shark Interactions and is perfect for those looking to meet these terrifying giants of deep.
Your day trip… What's included & some friendly advice!
before and again 2 hours prior to boarding the boat.
The Garden Route is a mountain biker's paradise!
The mountain bike rides are breathtaking journeys through the forest with easy jeep tracks or single-track routes. No matter what your level you will enjoy the beauty, the thrill and the challenge of these well-designed routes.
Mountain bikes and helmets are available for hire at the routes. For those with their own bikes the routes start at the Garden of Eden and maps outlining the routes are available.
Tsitsikamma, Featherbed and Robberg are a few of the Nature Reserves in the area that offer a variety of different walks and hikes. From tough 4-hour treks along the scenic Robberg Peninsula to the more relaxed wander through the Garden of Eden Forest.
The Robberg Peninsula is a nature reserve and national monument that lies about 8km south of Plettenberg Bay, a prestigious coastal resort on South Africa's famous Garden Route. Follow the airport road from town and look for the turn-off to the left.
The reserve is situated in an overlapping region of winter and summer rainfall. There is an increased likelihood of showers between August and November. The ecology of the Robberg Peninsula is similar to that of other rocky headlands on this coastline. It presents a fine example of how plants and animals adapt to the interacting influences of land and sea.Robberg offers a choice of three circular routes of increasing difficulty and distance. The round trip via the Point takes about four hours. It is dangerous at high tide and not recommended for young children. Water, hiking shoes and hats are essential. Always be prepared for sudden changes in weather.
Tsitsikamma National Park is a multi-dimensional destination with dramatic coastal scenery, reefs, rivers, lush forest and delicate Fynbos. Tsitsikamma National Park protects a wonderland of inter-tidal and marine life. This is one of the largest Marine Protected Areas (MPA) in the world, conserving 11% of South Africa's Temperate South Coast rocky shoreline.
Approximately 30% of the park is covered in fynbos (Cape Floral Kingdom), scattered amongst the forest vegetation, boasting a wide variety of beautiful flowers, including proteas and heath.
The Tsitsikamma National Park incorporates various cultural heritage sites ranging from Khoisan cultural heritage sites such as caves, shell middens and rock art to more recent cultural historic sites, such as the ruins of small fisher settlements, remnants of the past forestry industries and grave sites. The national park also offers wonderful hikes and one of the most popular is the walk across the swing bridge at Storms River Mouth.
For the avid golfer there are a number of top class, and PGA recommended, golf courses in the area. Designed by some of the best golfers in the world, like Ernie Els, the opportunity to play these golf courses is well with worth the time.
The Championship Golf Course lies high above the Indian Ocean and the vast Knysna Lagoon – a sweeping spectacle of fairways and greens rolling through the pristine indigenous landscape. The course's designers, Ron Fream and David Dale have compared the look of Pezula golf course to that of Gleneagles in the Scottish Highlands and Pebble beach on the Monterey coastline. A terrain of rolling fairways, fynbos and eyebrow bunkers make it very difficult to walk this course and golf carts are provided for all golfers. The five different tee options on every hole cater for all skill levels. No two challenges, or views, are alike.
The Simola course offers challenging and rewarding golf amidst spectacular scenery. Set below the high ridges, it's free from the wind that so often plagues coastal courses. Fairways flow with the natural undulating contours of the terrain and the unusual configuration of five par 5's and five par 3's adds a new dimension to the game. Exceptional views are par for the course, look out across the Knysna Lagoon all the way to the Heads or over the picturesque Knysna River as it twists and turns through the valley below.
Goose Valley golf course is a world-class course set in the indigenous fynbos. The course is in stunning condition12 months of the year. It is built on pure sand with excellent drainage properties and uses recycled water from the Gans "Goose" River that meanders through the Estate. Players will experience breathtaking views of the lagoon, the ocean and the Tsitsikamma Mountains, the beauty of the natural fynbos and an abundance of animal and bird life.
Upgraded by Rob O'Friell, in 2000, the 18 superb, new bent-grass greens have been built to USGA specifications. There new shapes and slopes plus the new bunkers and water features have created a challenging and beautiful course. The golf course is set in a park-like, proclaimed nature reserve and is the pride of the golfers of Plettenberg Bay. The 470m par-five 4th hole plays particularly long in a southeaster when the average golfer will have little chance of reaching the water-guarded green in two, and sometimes even in three. By contrast the 11th is only 110m long, one of the shortest par-threes in the country. The 300m par-four 14th is a sharp dogleg-left which features two tall oak trees on the left-hand side of the fairway, just after the hole curves towards the green. The foliage makes for a challenging drive.
Local Township Tours – experience the vibe!
Plettenberg Bay and Knysna are rich in culture and heritage. A unique experience is to head into our local townships to experience the incredible vibe and energy that exists amongst local residents in the area.
Meet the locals who live in the energetic Knysna Township. Visit the local stores, have your hair cut or styled at a local hairdresser and see how the brightly illustrated Nigerian restaurant operates. You can visit the shebeen (pub) and play a round of snooker or listen to the jukebox music.
The trip takes you past the Paula Whitney Pre-School, teeming with exuberant, laughing children, where you will be given the most amazing welcome. You have no choice but to interact with them and they will sing their joyous songs for you, including the South African National Anthem.
Then a visit with the "Women of Vision" – a self employed team of motivated women who have a sewing group and create some beautiful articles that make great gifts and memories of South Africa. You can have a go on the African drums, and see just how difficult it is to get that rhythm! Many other sights are pointed out along the way – Video shops, Tailors, Cell phone shops, great views, interesting people and houses. Then we head back to town, after a three hour exciting, happy trip, that people are always sad to end with Emzini Tours.
Experience Emzini in the Knysna Township and by the end you will see why WE LOVE AFRICA!
Ocean Blue Adventures and the Qolweni Community Development Trust offer guests a unique experience through the heart of the Qolweni Community settlement surrounded by magnificent views of the Tsitsikamma Mountains.
Explore the everyday life of a real African. Our guided tour informs you of interesting facts about the Xhosa history and Tribal culture. Meet the local children at the crèche and be entertained by their beautiful voices in song. See where the locals buy their everyday essentials. Gain understanding of the life of a sangoma while you are introduced to their homes.
Our Township tours offer close and personal interaction with the local community. Ocean Blue Adventures is investing in environmentally correct measures, such as the Program of Community Vegetable Gardens. This project, with relatively small contribution of resources, can benefit and reach a great number of people living in Qolweni, with only 20% of this community employed is fulfilling an essential need.
Guests meet with their guide at the Ocean Blue Shop and depart for the memory bridge (Bridge over the national road leading into Qolweni). On crossing over the bridge we take a walk to the Siyakula Pre-School where Teachers welcome guests with the children. Guests get a full tour of the school, ending with the children in choir. From the school guests move towards the local backpackers where they will be introduced to the woman of the community, they will be taken to the spaza shop and shabeen before meeting some locals at their homes. The tour ends at the Siyakhula nursery school before departing back to the Bridge.
There are a myriad of specialty stores, areas with a variety of galleries and boutique style shops that will keep any shopper busy, and husbands why not grab a coffee in a local coffee shop and watch the world go by.
Your stay at Tsala can be combined with a trip to other parts of Southern Africa, or an exploration in and around the scenic Garden Route area.
Plettenberg Bay, Garden Route: Plettenberg Bay is characterised by unspoilt golden beaches, a dramatic rocky peninsula, intriguing lagoons and estuaries, towering indigenous forests and fresh rivers and sea. More than a village Plettenberg Bay is accessible by first class national roads, by sea or by scheduled air flights. Plettenberg Bay is renowned for its teeming bird life, vast expanses of Cape flora, its wetlands and lagoons, gigantic trees and a bay large enough to harbour great whales. With its exceptional climate, and beautiful view sites over the Indian Ocean, Plettenberg Bay is perfect for tourists interested in exploring, watching or just lazing.
Plettenberg Bay justly lays claim to the title of the South African whale watching capital. The southern right whales can be seen for the whole season and when they are getting ready to leave in early November, the humpback whales arrive with their calves, and stay until the end of December or early January. A truly memorable sight!
Dolphin and whale watching in Plett is accessible, organised and easy to arrange. There are whale watching boat trips, dolphin-watching kayak trips and a number of aircraft from which you can check out the whales from the air. Plettenberg Bay has made a huge effort to promote a responsible boat-based whale and dolphin watching programmes. Viewing distances and time spent with each animal are strictly monitored so that there is minimal interference.
Knysna is a natural paradise of lush, indigenous forests, tranquil lakes and golden beaches. The village nestles on the banks of a beautiful lagoon, now a protected marine reserve that is home to the extraordinary sea horse and over 200 species of fish. Beaches, lakes, mountains and rivers provide endless opportunity for leisure and outdoor adventure. Within the town, craft shops, flea markets and cosy cafés beckon with small-town charm and hospitality. The area around Knysna is a veritable Garden of Eden. This is home to the only forest elephant in South Africa, the rare Pansy Shell, the brilliantly coloured, and elusive, Knysna Loerie, a plethora of waterfowl and forest birds, dolphins and visiting whales.
The indigenous forests in Knysna constitute the largest complex of closed-canopy forest in southern Africa, whilst the remarkable richness of the Fynbos vegetation contributes over 8000 plant species to the Cape floral kingdom. Exploring the Knysna forests along demarcated walks, listening to the occasional call of the Loerie provides an escape into the past when herds of elephants still trod these paths. Reading Dalene Matthee's 'Circles in a forest' set in the Knysna forest, will greatly enrich your visit here. Today merely three elephants are still known roam the forest. The Knysna Elephant Park has brought the elephants back to Knysna, all the elephants are former orphans rescued from culling operations in the Kruger Park, except for Thandi who was born in the park.
A visit to Knysna would be incomplete without a trip to the heads – a striking geological feature made up of a pair of huge, brightly coloured cliffs lying at the mouth of the lagoon, flanking a channel of potentially treacherous water that flows into Knysna's lagoon. The eastern head houses a lookout with spectacular views of the lagoon, Leisure Isle and Knysna whilst the western head is a privately owned nature reserve called Featherbed Bay. Visitors can get to the reserve via ferry.
Tsala means "elevated resting place' in Swahili and that is exactly what you can do when staying with us. Put your feet up, read a book, or pamper yourself with a massage in the comfort of your room.
Tsala offers a variety of in-room treatments such as massages, manicures, pedicures, facials and reflexology. We use qualified therapists from reputable salons. Pamper treatments are available between 07h00 -19h00 and are subject to the availability of a therapist.


text:
How did Jimmy Garoppolo compare to other preseason quarterbacks?
Let's see how Jimmy Garoppolo's preseason performance in Week 1 measures up to the rest of the league's quarterbacks.
By Matthew Rewinski@GooseOnBass Aug 15, 2016, 7:00pm EDT
Share All sharing options for: How did Jimmy Garoppolo compare to other preseason quarterbacks?
Bob DeChiara-USA TODAY Sports
Blame Trey Flowers and Jamie Collins. Last week was supposed to be the can't-miss grand premier of the Jimmy Garoppolo show, and instead the Patriots hung 14 points on the Saints on defense with a pick-6 and a sack-fumble-return for a touchdown. Flowers and Collins, overachievers, both of you!
And since Jimmy's had such limited time on the field until now, people have been all over the place with what to expect from the kid. Is he a game manager? Is he another spread QB that'll get eaten alive against a real (well, preseason "real", anyway) NFL defense? Is he, as his college coach said, presumably seriously, the next Dan Marino?
Now, we at least have something to dig into – with a week of preseason ball in the books, we can put Jimmy's numbers up next to his fellow QBs to see how he looks. In most cases, it's not too bad!
This one's about as straightforward as it gets. Jimmy G actually threw for the third-highest yard total in the NFL this week, ending his night against the Saints with 168 yards through the air. Only two guys racked up more yards than Garoppolo – Seattle's Trevone Boykin and Atlanta's Matt Shaub, who passed for 188 and 179 yards, respectively.
As you've surely seen in the stat column already, Jimmy went 11 for 18 against New Orleans' defense, which, no offense, but they set a new all-time NFL record for touchdowns allowed last year. Garoppolo's 11 completions were good for 11th overall, and that puts him in the neighborhood of Eagles rookie Carson Wentz (12 for 24), Cardale Jones in Buffalo (11 for 21), and the guy that used to have Jimmy G's job, Ryan Mallett, who's now with the Baltimore Ravens (11 for 15).
Hey, wait a minute, though – Jimmy had almost the same number of completed passes as all those guys, and he did it in fewer attempts (except for Ryan Mallett). His completion percentage has to be one of the best out there, right?
Completion Percentage
Sure, there's technically a few dudes that have a 100% completion percentage if you just pull up the stats page on NFL.com, but to get a sense of how Jimmy's completion percentage stacks up, I (conveniently) ignored anyone with less than 5 passing attempts. Not trying to talk about how Drew Brees threw one pass, a dude caught it, and then Brees peaced out for the rest of the game.
Anyway, based on what we were just talking about, you would think that Garoppolo's completion percentage would put him in pretty good company.
And a 61.1% completion percentage is nothing to sneeze at, but even if you only count quarterbacks that threw 5 or more passes in Week 1, Jimmy's completion percentage of 61.1% is….
...30th. As in, there were 29 other quarterbacks that actually played this past weekend that posted a better completion percentage.
Touchdowns
No Jimmy G touchdowns to report this year, yet. Booooo.
But, stacked up to what most people would consider comparable players, zero touchdowns in one half of a preseason game was pretty much par for the course. Observe:
-Only four quarterbacks scored multiple touchdowns this week – LA's Sean Mannion, Oakland's Matt McGloin, Dallas's Dak Prescott, and Houston's Tom Savage.
-A whopping 23 quarterbacks threw one touchdown, and that counts guys like Minnesota's Teddy Bridgewater (a late first-round pick in 2014), Geno Smith (a 2013 second-round pick), and EJ Manuel, who you may have forgotten was a 2013 first-round pick before losing his job to Kyle Orton, and Matt Cassell, and Tyrod Taylor.
And finally, Garoppolo also chalked up a big old zero in one last category:
None. That's good.
Maybe Jimmy is way more clutch than we all think, and could dig the team out of a hole even if he did turn the ball over, but taking care of the rock was pretty much everyone's biggest worry last Thursday. And he did, although he had that one backyard-ball across-the-body bomb that probably should have been picked off.
In case you think the "well, he didn't turn the ball over!" aspect of the game is getting too much love, here's some guys that did throw interceptions this weekend:
Jared Goff (LA), Carson Wentz (Philadelphia), Luke McCown (New Orleans), Mark Sanchez (Denver), and Matt Barkley (Arizona).
Oh, and remember that sweet screen pass that James White almost took to the house before he finally got chased down at the goal line?
That was actually the third-longest reception of the weekend – the Garoppolo-to-White pass went for a cool 56 yards, with only Stephen Morris and Matt Schaub in front of Jimmy.
Next up, Jimmy and his partner in crime Jacoby Brissett square off against the Bears on Thursday.
Patriots activate cornerbacks Jalen Mills, Shaun Wade off Covid-19 reserve list Both missed Saturday's wild card at Highmark Stadium.
Patriots' Jerod Mayo, Dave Ziegler receive interview requests from the Raiders Las Vegas is looking for a new head coach and, apparently, general manager.


text:
Title: Performance
nav_order: 7
permalink: /performance.html
has_children: true
---

# Performance

I've done some limited performance tests (turning a GPIO on then off, see
[GpioPerfTest](https://github.com/mattjlewis/diozero/blob/master/diozero-sampleapps/src/main/java/com/diozero/sampleapps/perf/GpioPerfTest.java))
on a Raspberry Pi Zero, 2B, 3B and 4B using the various [provider implementations](1_Providers.md).
I've also run tests using the underlying APIs directly without going via the diozero APIs to assess the overhead of diozero.

The diozero performance test applications are all in the [com.diozero.sampleapps.perf](https://github.com/mattjlewis/diozero/tree/master/diozero-sampleapps/src/main/java/com/diozero/sampleapps/perf) package.
See [PigpioPerfTest](https://github.com/mattjlewis/pigpioj/blob/master/pigpioj-java/src/main/java/uk/pigpioj/test/PigpioPerfTest.java) for a similar performance test application for pigpioj without diozero.
The [mmap-tests]() folder contains some basic applications for testing mmap and gpio chardev performance without diozero.

Results (with diozero 1.2.0 and pigpioj 2.5.7):

![Performance](/assets/images/Performance.png "Performance")

{: .note }
> * All tests were performed with OpenJDK 11 ("11.0.9.1" 2020-11-04) using default settings.
> * An LED was connected to the GPIO to verify that the GPIO was being toggled.
> * The Pi 3B diozero (builtin) results have been verified with an oscilloscope.
> * Operating System and libraries were all current as of April 2021 (RaspiOS 5.10.17-v7+, Armbian 5.10.21).
> * Operating Systems are 32-bit unless otherwise stated.
> * mmap controlled GPIO is not currently available for the BeagleBone Black using the built-in provider - it is via the BBBioLib provider.

## Conclusion

* While pigpio itself is extremely fast, the JNI layer introduces significant overhead
* The builtin memory mapped GPIO implementation is extremely fast
* 64-bit O/S delivers additional performance for the memory mapped GPIO implementation

## Raw Numbers

| Library (Provider) | Device | Frequency (kHz) |
| -------- |:------:| :---|
| pigpioj (JNI) | Pi Zero | 909 |
| pigpioj (JNI) | Pi 2B | 1,667 |
| pigpioj (JNI) | Pi 3B | 2,354 |
| pigpioj (JNI) | CM 4 | 2,751 |
| pigpioj (JNI) | Pi 4B (32-bit) | 2,771 |
| pigpioj (JNI) | Pi 4B (64-bit) | 2,623 |
| diozero (pigpio) | Pi Zero | 805 |
| diozero (pigpio) | Pi 2B | 1,533 |
| diozero (pigpio) | Pi 3B | 2,217 |
| diozero (pigpio) | CM 4 | 2,763 |
| diozero (pigpio) | Pi 4B (32-bit) | 2,858 |
| diozero (pigpio) | Pi 4B (64-bit) | 2,598 |
| diozero (builtin) | TinkerBoard | 515 |
| diozero (builtin) | BeagleBone Black | 191 |
| diozero (BBBioLib) | BeagleBone Black | 1,453 |
| diozero (builtin) | Odroid C2 | 1,668 |
| diozero (builtin) | NanoPi Neo | 2,328 |
| diozero (builtin) | NanoPi Duo 2 | 2,605 |
| diozero (builtin) | Pi Zero | 2,644 |
| diozero (builtin) | Pi 2B | 8,503 |
| diozero (builtin) | Pi 3B | 13,028 |
| diozero (builtin) | CM 4 | 21,115 |
| diozero (builtin) | Pi 4B (32-bit) | 21,110 |
| diozero (builtin) | Pi 4B (64-bit) | 27,785 |

redpajama_set_name: RedPajamaGithub


text:
>> Ed Graney
UNLV coach Marcus Arroyo won press conference — now must win games
It won't help UNLV's new football coach beat Boise State, but first impressions can certainly work wonders in terms of how a community will support a program which has rarely succeeded.
By	Ed Graney	/ Las Vegas Review-Journal
Student athletes attend a press conference to announce UNLV's new football head coach Marcus Arroyo, at UNLV's Fertitta Football Complex in Las Vegas, Friday, Dec. 13, 2019. (Erik Verduzco/Las Vegas Review-Journal) @Erik_Verduzco
He couldn't have known, of course, sitting between his brother and father, driving across Las Vegas to Arizona in a 1972 Primer El Camino listening to, among others, the rock band Santana.
He might have even heard the lyrics to "Day of Celebration," a hidden track which begins 12 seconds following the end of, "The Calling."
Such appropriate song titles for Marcus Arroyo on Friday.
Such a difference between then and now, a young boy not understanding that his journey would one day turn that middle bench seat in Dad's car into glancing out the window of a plane, descending into the city that has afforded him the professional opportunity for which he has worked his entire life.
I have to believe Arroyo is a big proponent of the idea that reality has finally bested his grandest dreams, the new UNLV head football coach who was introduced as the next option to try and stir a program from its seemingly endless state of on-field insensibility.
"This is a place," said Arroyo, "that wants to be great."
I'm pretty sure it will settle for 6-6 and being invited to the New Mexico Bowl.
Arroyo won the press conference. While that won't help him beat Boise State or San Diego State or continue to keep the Fremont Cannon from UNR's blue hands, first impressions can certainly work wonders in terms of how a community will support a program which has rarely succeeded on the scoreboard.
He will need every ounce of it.
It won't take a village to awake UNLV football. Try a metropolis.
I was impressed with who he mostly addressed during opening remarks, beyond the typical words of thanks for family and mentors and those who have now hired him as a first-time head coach.
Arroyo directed a majority of his comments to and about those UNLV players in attendance, a group brought here by former coach Tony Sanchez and his staff. They were staring back at their new leader, a time of uncertainty and anxiousness for each of them.
"I have been in their shoes," said the 39-year-old Arroyo, a former quarterback at San Jose State. "You can't forget for a second what those guys are going through. They are pivotal to our success. … It was very important that my first meeting (Thursday) night was with them. I loved looking into their eyes and shaking their hands and seeing their demeanor and getting ready to hear their stories.
"I have to earn their trust and re-recruit the ones who are here and recruit our tails off for the ones who aren't. The 2020 season started for the (returning players) the minute our meeting ended. I know they're excited. I know they're anxious. That's the beauty of it all, the process of doing something amazing together."
He would be smart to at least try and include in such an undertaking the idea of developing relationships with highly influential folks, specifically the family for which the building he spoke in Friday is named.
Engage the Fertittas
Lorenzo and Frank Fertitta were not at attendance and neither were any of their representatives, curious given that without the family's financial contributions there is no state-of-the-art football complex in which Arroyo can now recruit.
It's true the Fertittas have an incredibly close bond with Sanchez, so if fences need to be mended, Arroyo needs to pick up a hammer and nails.
The Fertittas want UNLV to succeed, a football family which is unquestionably important enough to the overall goal to warrant Arroyo reaching out. He will need it all to win here — a great coaching staff, successful recruiting and major communal support.
"We will win," Arroyo said. "We will win at a really high level. The goal is to compete for championships. We will block out all the naysayers and build a winner that will last."
Sounds good. Also heard it before here.
But as first impressions go, Arroyo was terrific.
I'm just not sure how trustworthy he is.
In meeting him for the first time, I shook his hand and introduced myself.
"I've heard a lot of great things about you," he said.
To which I replied, "Well, I highly doubt that."
More Rebels: Follow at reviewjournal.com/Rebels.
Contact columnist Ed Graney at egraney@reviewjournal.com or 702-383-4618. He can be heard on "The Press Box," ESPN Radio 100.9 FM and 1100 AM, from 7 a.m. to 10 a.m. Monday through Friday. Follow @edgraney on Twitter.
Posted on: Ed Graney, Sports, Sports Columns, UNLV, UNLV Football
UNLV SPORTS YOUR WAY
Stay up to date on the Rebels with our free newsletter.
Even in defeat, Golden Knights take big step forward
By Ed Graney / RJ
You can only be motivated by sentiment for so long, and what the Knights did Saturday was about returning to hockey and moving beyond the drama of their coach being fired.
Have a cold one: Ryan Reaves looks to fit with Peter DeBoer
Few in the Golden Knights room would have had similar thoughts as Reaves when it was announced that DeBoer would be replacing the fired Gerard Gallant this week.
Peter DeBoer must win over Golden Knights and fans, minus clown suit
Fans certainly will be content with first impressions, the Knights having snapped a four-game losing streak by beating the Ottawa Senators 4-2 on Thursday.
Gerard Gallant's firing no 24-hour decision by Golden Knights
Gerard Gallant was fired as coach of the Golden Knights on Wednesday morning. For such a seemingly rushed decision, be assured it wasn't made in the previous 24 hours.
Golden Knights lose first period again, then third straight game
January 11, 2020 - 11:11 pm January 11, 2020 - 11:22 pm
It wasn't a disastrous start for the Golden Knights. It just wasn't very good, an opening 20 minutes that was eventually followed by a 3-0 loss to end a seven-game homestand.
Penguins stir memories of Marc-Andre Fleury's arrival to Las Vegas
January 7, 2020 - 10:26 pm January 7, 2020 - 10:32 pm
A reminder comes each time the Golden Knights play Pittsburgh, with Marc-Andre Fleury again in the opposite net of the team that drafted him No. 1 overall in 2003.
Water shortage aside, Las Vegas is the place for Tom Brady
January 6, 2020 - 5:17 pm January 6, 2020 - 10:22 pm
Tom Brady, Mr. Tuck Rule himself, ending his Hall of Fame career with the Raiders? Why the heck not?
No news conference drama after Golden Knights defeat Blues
January 4, 2020 - 7:28 pm January 5, 2020 - 12:39 am
After walking out of the news conference following the Golden Knights' win Thursday, coach Gerard Gallant kept his cool after his team defeated the St. Louis Blues on Saturday.
Mention 'Army' and Golden Knights' Bill Foley beams with pride
Golden Knights owner Bill Foley, a member of the Army class of 1967, sat just off the ice at T-Mobile Arena on Friday, watching Army play Providence in the Fortress Invitational.
UNLV basketball opens 2020 with best effort of season
January 2, 2020 - 8:29 am January 2, 2020 - 8:41 am
The Rebels bounced a defending Mountain West co-champion and unanimous preseason favorite to repeat right out of the Thomas Mack Center on Wednesday, beating Utah State 70-53.


Project SANDBOX was an iterative 4 month Spring 2014 initiative at the Carnegie Mellon University Entertainment Technology Center (ETC) tasked with bridging the gap between young children, their families, science content, and maker culture.
Together with the New York Hall of Science and the Children's Museum of Pittsburgh, SANDBOX created a digital experience that encouraged play, exploration and collaboration between parent and child.
Very early on, we discovered Sifteo Cubes, and were awed by it's intuitiveness to both children and adults. We did 2 prototype games to specifically test this ease of usability, and playtested these prototypes with children and adults at Children's Museum of Pittsburgh.
We soon found sure footing with the Cubes when we came up with something very similar to Kerbal Space Program, and everyone was very excited by the prospect of building rockets like LEGOs.
We ran with the idea the rest of the way, and have received incredible feedback both from the New York Hall of Science, and from the people we watched play the game.
Editor tools in Unity to facilitate tweaking game parameters for non-programmers (C#).
Rocket builder: Build the rocket in Unity based on current state information from Sifteo Cubes.
Prototyping shaders for cool effects (atmospheric friction, etc) (HLSL).
Bandwidth: Sifteo cubes had a limited bandwidth to communicate over USB (60 bytes), and the state information we needed to send clocked at around twice that amount. I ended up writing routines to pack the data into 36 bytes, by defining ranges for each type of data that I needed to send, and making sure they got exactly as many bits as needed, and not a single one more.
Fault-tolerance: The Unity plugin I used for Websocket communications, as well as the USB library for NodeJS, were not very mature, and failed often. I tried doing a lot of interesting (and to me, at the time clever) things to fix it, but in the end the most reliable method was a simple master-slave program pair where a master process simply watches the communication script, and relaunches it if it fails.