text:
package org.datadog.jenkins.plugins.datadog.model;

import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_AUTHOR_DATE;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_AUTHOR_EMAIL;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_AUTHOR_NAME;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_COMMITTER_DATE;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_COMMITTER_EMAIL;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_COMMITTER_NAME;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.DD_GIT_COMMIT_MESSAGE;
import static org.datadog.jenkins.plugins.datadog.util.git.GitConstants.GIT_BRANCH;
import static org.datadog.jenkins.plugins.datadog.util.git.GitUtils.isCommitInfoAlreadyCreated;
import static org.datadog.jenkins.plugins.datadog.util.git.GitUtils.isRepositoryInfoAlreadyCreated;
import static org.datadog.jenkins.plugins.datadog.util.git.GitUtils.isUserSuppliedGit;
import static org.datadog.jenkins.plugins.datadog.util.git.GitUtils.isValidCommit;
import static org.datadog.jenkins.plugins.datadog.util.git.GitUtils.isValidRepositoryURL;

import com.cloudbees.plugins.credentials.CredentialsParameterValue;
import hudson.EnvVars;
import hudson.model.BooleanParameterValue;
import hudson.model.Cause;
import hudson.model.CauseAction;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.model.Run;
import hudson.model.StringParameterValue;
import hudson.model.TaskListener;
import hudson.model.TextParameterValue;
import hudson.model.User;
import hudson.tasks.Mailer;
import hudson.triggers.SCMTrigger;
import hudson.triggers.TimerTrigger;
import hudson.util.LogTaskListener;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.datadog.jenkins.plugins.datadog.DatadogUtilities;
import org.datadog.jenkins.plugins.datadog.traces.BuildSpanManager;
import org.datadog.jenkins.plugins.datadog.traces.message.TraceSpan;
import org.datadog.jenkins.plugins.datadog.util.SuppressFBWarnings;
import org.datadog.jenkins.plugins.datadog.util.TagsUtil;
import org.datadog.jenkins.plugins.datadog.util.git.GitUtils;
import org.jenkinsci.plugins.gitclient.GitClient;

import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

public class BuildData implements Serializable {

    private static final long serialVersionUID = 1L;

    private static transient final Logger LOGGER = Logger.getLogger(BuildData.class.getName());

    private String buildNumber;
    private String buildId;
    private String buildUrl;
    private Map<String, String> buildParameters = new HashMap<>();
    private String charsetName;
    private String nodeName;
    private String jobName;
    private String baseJobName;
    private String buildTag;
    private String jenkinsUrl;
    private String executorNumber;
    private String javaHome;
    private String workspace;
    // Branch contains either env variable - SVN_REVISION or CVS_BRANCH or GIT_BRANCH
    private String branch;
    private String gitUrl;
    private String gitCommit;
    private String gitMessage;
    private String gitAuthorName;
    private String gitAuthorEmail;
    private String gitAuthorDate;
    private String gitCommitterName;
    private String gitCommitterEmail;
    private String gitCommitterDate;
    private String gitDefaultBranch;
    private String gitTag;

    // Environment variable from the promoted build plugin
    // - See https://plugins.jenkins.io/promoted-builds
    // - See https://wiki.jenkins.io/display/JENKINS/Promoted+Builds+Plugin
    private String promotedUrl;
    private String promotedJobName;
    private String promotedNumber;
    private String promotedId;
    private String promotedTimestamp;
    private String promotedUserName;
    private String promotedUserId;
    private String promotedJobFullName;

    private String result;
    private boolean isCompleted;
    private String hostname;
    private String userId;
    private String userEmail;
    private Map<String, Set<String>> tags;

    private Long startTime;
    private Long endTime;
    private Long duration;
    private Long secondsInQueue;
    private Long propagatedSecondsInQueue;
    private Long millisInQueue;
    private Long propagatedMillisInQueue;

    private String traceId;
    private String spanId;

    @SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE")
    public BuildData(Run run, TaskListener listener) throws IOException, InterruptedException {
        if (run == null) {
            return;
        }
        EnvVars envVars;
        if(listener != null){
            envVars = run.getEnvironment(listener);
        }else{
            envVars = run.getEnvironment(new LogTaskListener(LOGGER, Level.INFO));
        }

        setTags(DatadogUtilities.getBuildTags(run, envVars));

        // Populate instance using environment variables.
        populateEnvVariables(envVars);

        // Populate instance using Git info if possible.
        // Set all Git commit related variables.
        if(isGit(envVars)){
            populateGitVariables(run, listener, envVars);
        }

        // Populate instance using run instance
        // Set StartTime, EndTime and Duration
        long startTimeInMs = run.getStartTimeInMillis();
        setStartTime(startTimeInMs);
        long durationInMs = run.getDuration();
        if (durationInMs == 0 && startTimeInMs != 0) {
            durationInMs = System.currentTimeMillis() - startTimeInMs;
        }
        setDuration(durationInMs);
        if (durationInMs != 0 && startTimeInMs != 0) {
            Long endTimeInMs = startTimeInMs + durationInMs;
            setEndTime(endTimeInMs);
        }

        // Set Jenkins Url
        setJenkinsUrl(DatadogUtilities.getJenkinsUrl());
        // Set UserId
        setUserId(getUserId(run));
        // Set UserEmail
        if(StringUtils.isEmpty(getUserEmail(""))){
            setUserEmail(getUserEmailByUserId(getUserId()));
        }

        // Set Result and completed status
        setResult(run.getResult() == null ? null : run.getResult().toString());
        setCompleted(run.getResult() != null && run.getResult().completeBuild);

        // Set Build Number
        setBuildNumber(String.valueOf(run.getNumber()));
        // Set Hostname
        setHostname(DatadogUtilities.getHostname(envVars));
        // Save charset canonical name
        setCharset(run.getCharset());

        // Set Job Name
        String baseJobName = null;
        try {
            baseJobName = run.getParent().getParent().getFullName();
            if (baseJobName.length() == 0) {
                baseJobName = run.getParent().getName();
            }
        } catch(NullPointerException e){
            //noop
        }
        setBaseJobName(normalizeJobName(baseJobName));
        String jobNameWithConfiguration = null;
        try {
            jobNameWithConfiguration = run.getParent().getFullName();
        } catch(NullPointerException e){
            //noop
        }
        setJobName(normalizeJobName(jobNameWithConfiguration));

        // Set Jenkins Url
        String jenkinsUrl = DatadogUtilities.getJenkinsUrl();
        if("unknown".equals(jenkinsUrl) && envVars != null && envVars.get("JENKINS_URL") != null
                && !envVars.get("JENKINS_URL").isEmpty()) {
            jenkinsUrl = envVars.get("JENKINS_URL");
        }
        setJenkinsUrl(jenkinsUrl);

        // Build parameters
        populateBuildParameters(run);

        // Set Tracing IDs
        final TraceSpan buildSpan = BuildSpanManager.get().get(getBuildTag(""));
        if(buildSpan !=null) {
            setTraceId(Long.toUnsignedString(buildSpan.context().getTraceId()));
            setSpanId(Long.toUnsignedString(buildSpan.context().getSpanId()));
        }
    }

    private void populateBuildParameters(Run<?,?> run) {
        // Build parameters can be defined via Jenkins UI
        // or via Jenkinsfile (https://www.jenkins.io/doc/book/pipeline/syntax/#parameters)
        try {
            final ParametersAction parametersAction = run.getAction(ParametersAction.class);
            if(parametersAction == null){
                return;
            }

            final List<ParameterValue> parameters = parametersAction.getAllParameters();
            if(parameters == null || parameters.isEmpty()){
                return;
            }

            for(final ParameterValue parameter : parameters) {
                // Only support parameters as string (only single line), boolean and credentials for the moment.
                // Credentials parameters are safe because the value will show the credential ID, not the secret itself.
                // Choice parameters are treated as string parameters internally.
                if((parameter instanceof StringParameterValue && !(parameter instanceof TextParameterValue))
                        || parameter instanceof BooleanParameterValue
                        || parameter instanceof CredentialsParameterValue) {
                    this.buildParameters.put(parameter.getName(), String.valueOf(parameter.getValue()));
                }
            }
        } catch (Throwable ex) {
            DatadogUtilities.severe(LOGGER, ex, "Failed to populate Jenkins build parameters.");
        }
    }

    private void populateEnvVariables(EnvVars envVars){
        if (envVars == null) {
            return;
        }
        setBuildId(envVars.get("BUILD_ID"));
        setBuildUrl(envVars.get("BUILD_URL"));
        setNodeName(envVars.get("NODE_NAME"));
        setBuildTag(envVars.get("BUILD_TAG"));
        setExecutorNumber(envVars.get("EXECUTOR_NUMBER"));
        setJavaHome(envVars.get("JAVA_HOME"));
        setWorkspace(envVars.get("WORKSPACE"));
        if (isGit(envVars)) {
            setBranch(GitUtils.resolveGitBranch(envVars, null));
            setGitUrl(GitUtils.resolveGitRepositoryUrl(envVars, null));
            setGitCommit(GitUtils.resolveGitCommit(envVars, null));
            setGitTag(GitUtils.resolveGitTag(envVars, null));

            // Git data supplied by the user has prevalence. We set them first.
            // Only the data that has not been set will be updated later.
            // If any value is not provided, we maintained the original value if any.
            setGitMessage(envVars.get(DD_GIT_COMMIT_MESSAGE, this.gitMessage));
            setGitAuthorName(envVars.get(DD_GIT_COMMIT_AUTHOR_NAME, this.gitAuthorName));
            setGitAuthorEmail(envVars.get(DD_GIT_COMMIT_AUTHOR_EMAIL, this.gitAuthorEmail));
            setGitAuthorDate(envVars.get(DD_GIT_COMMIT_AUTHOR_DATE, this.gitAuthorDate));
            setGitCommitterName(envVars.get(DD_GIT_COMMIT_COMMITTER_NAME, this.gitCommitterName));
            setGitCommitterEmail(envVars.get(DD_GIT_COMMIT_COMMITTER_EMAIL, this.gitCommitterEmail));
            setGitCommitterDate(envVars.get(DD_GIT_COMMIT_COMMITTER_DATE, this.gitCommitterDate));

        } else if (envVars.get("CVS_BRANCH") != null) {
            setBranch(envVars.get("CVS_BRANCH"));
        }
        setPromotedUrl(envVars.get("PROMOTED_URL"));
        setPromotedJobName(envVars.get("PROMOTED_JOB_NAME"));
        setPromotedNumber(envVars.get("PROMOTED_NUMBER"));
        setPromotedId(envVars.get("PROMOTED_ID"));
        setPromotedTimestamp(envVars.get("PROMOTED_TIMESTAMP"));
        setPromotedUserName(envVars.get("PROMOTED_USER_NAME"));
        setPromotedUserId(envVars.get("PROMOTED_USER_ID"));
        setPromotedJobFullName(envVars.get("PROMOTED_JOB_FULL_NAME"));
    }

    /**
     * Populate git commit related information in the BuildData instance.
     * @param run
     * @param listener
     * @param envVars
     */
    private void populateGitVariables(Run<?,?> run, TaskListener listener, EnvVars envVars) {
        // First we obtain the actions to check if the Git information was already calculated.
        // If so, we want to use this information to avoid creating a new Git client instance
        // to calculate the same information.

        boolean commitInfoAlreadyCreated = isCommitInfoAlreadyCreated(run, this.gitCommit);
        boolean repositoryInfoAlreadyCreated = isRepositoryInfoAlreadyCreated(run, this.gitUrl);

        GitRepositoryAction gitRepositoryAction = run.getAction(GitRepositoryAction.class);
        if(repositoryInfoAlreadyCreated){
            this.gitDefaultBranch = gitRepositoryAction.getDefaultBranch();
        }

        final GitCommitAction gitCommitAction = run.getAction(GitCommitAction.class);
        if(commitInfoAlreadyCreated){
            populateCommitInfo(gitCommitAction);
        }

        // If all Git info was already calculated, we finish the method here.
        if(repositoryInfoAlreadyCreated && commitInfoAlreadyCreated) {
            return;
        }

        // At this point, there is some Git information that we need to calculate.
        // We use the same Git client instance to calculate all git information
        // because creating a Git client is a very expensive operation.
        // Create a new Git client is a very expensive operation.
        // Avoid creating Git clients as much as possible.
        if(!isValidCommit(gitCommit) && !isValidRepositoryURL(this.gitUrl)) {
            return;
        }

        final GitClient gitClient = GitUtils.newGitClient(run, listener, envVars, this.nodeName, this.workspace);
        if(isValidCommit(this.gitCommit)){
            populateCommitInfo(GitUtils.buildGitCommitAction(run, gitClient, this.gitCommit));
        }

        if(isValidRepositoryURL(this.gitUrl)){
            gitRepositoryAction = GitUtils.buildGitRepositoryAction(run, gitClient, envVars, this.gitUrl);
            if(gitRepositoryAction != null) {
                this.gitDefaultBranch = gitRepositoryAction.getDefaultBranch();
            }
        }
    }

    /**
     * Populate the information related to the commit (message, author and committer) based on the GitCommitAction
     * only if the user has not set the value manually.
     * @param gitCommitAction
     */
    private void populateCommitInfo(GitCommitAction gitCommitAction) {
        if(gitCommitAction != null) {
            // If any value is not empty, it means that
            // the user supplied the value manually
            // via environment variables.

            if(getGitMessage("").isEmpty()){
                setGitMessage(gitCommitAction.getMessage());
            }

            if(getGitAuthorName("").isEmpty()){
                setGitAuthorName(gitCommitAction.getAuthorName());
            }

            if(getGitAuthorEmail("").isEmpty()) {
                setGitAuthorEmail(gitCommitAction.getAuthorEmail());
            }

            if(getGitAuthorDate("").isEmpty()){
                setGitAuthorDate(gitCommitAction.getAuthorDate());
            }

            if(getGitCommitterName("").isEmpty()){
                setGitCommitterName(gitCommitAction.getCommitterName());
            }

            if(getGitCommitterEmail("").isEmpty()){
                setGitCommitterEmail(gitCommitAction.getCommitterEmail());
            }

            if(getGitCommitterDate("").isEmpty()){
                setGitCommitterDate(gitCommitAction.getCommitterDate());
            }
        }
    }

    /**
     * Return if the Run is based on Git repository checking
     * the GIT_BRANCH environment variable or the user supplied
     * environment variables.
     * @param envVars
     * @return true if GIT_BRANCH is set or the user supplied GIT information via env vars.
     */
    private boolean isGit(EnvVars envVars) {
        if(envVars == null){
            return false;
        }

        return isUserSuppliedGit(envVars) || envVars.get(GIT_BRANCH) != null;
    }

    /**
     * Assembles a map of tags containing:
     * - Build Tags
     * - Global Job Tags set in Job Properties
     * - Global Tag set in Jenkins Global configuration
     *
     * @return a map containing all tags values
     */
    public Map<String, Set<String>> getTags() {
        Map<String, Set<String>> allTags = new HashMap<>();
        try {
            allTags = DatadogUtilities.getTagsFromGlobalTags();
        } catch(NullPointerException e){
            //noop
        }
        allTags = TagsUtil.merge(allTags, tags);
        allTags = TagsUtil.addTagToTags(allTags, "job", getJobName("unknown"));

        if (nodeName != null) {
            allTags = TagsUtil.addTagToTags(allTags, "node", getNodeName("unknown"));
        }
        if (result != null) {
            allTags = TagsUtil.addTagToTags(allTags, "result", getResult("UNKNOWN"));
        }
        if (userId != null) {
            allTags = TagsUtil.addTagToTags(allTags, "user_id", getUserId());
        }
        if (jenkinsUrl != null) {
            allTags = TagsUtil.addTagToTags(allTags, "jenkins_url", getJenkinsUrl("unknown"));
        }
        if (branch != null) {
            allTags = TagsUtil.addTagToTags(allTags, "branch", getBranch("unknown"));
        }

        return allTags;
    }

    public Map<String, String> getTagsForTraces() {
        Map<String, Set<String>> allTags = new HashMap<>();
        try {
            allTags = DatadogUtilities.getTagsFromGlobalTags();
        } catch(NullPointerException e){
            //noop
        }
        allTags = TagsUtil.merge(allTags, tags);
        return TagsUtil.convertTagsToMapSingleValues(allTags);
    }

    public void setTags(Map<String, Set<String>> tags) {
        this.tags = tags;
    }

    private <A> A defaultIfNull(A value, A defaultValue) {
        if (value == null) {
            return defaultValue;
        } else {
            return value;
        }
    }

    public String getJobName(String value) {
        return defaultIfNull(jobName, value);
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getBaseJobName(String value) {
        return defaultIfNull(baseJobName, value);
    }

    public void setBaseJobName(String baseJobName) {
        this.baseJobName = baseJobName;
    }

    public String getResult(String value) {
        return defaultIfNull(result, value);
    }

    public void setResult(String result) {
        this.result = result;
    }

    public boolean isCompleted() {
        return isCompleted;
    }

    public void setCompleted(boolean completed) {
        this.isCompleted = completed;
    }

    public String getHostname(String value) {
        return defaultIfNull(hostname, value);
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }

    public String getBuildUrl(String value) {
        return defaultIfNull(buildUrl, value);
    }

    public void setBuildUrl(String buildUrl) {
        this.buildUrl = buildUrl;
    }

    public Charset getCharset() {
        if (charsetName != null) {
            // Will throw an exception if there is an issue with
            // the charset canonical name.
            return Charset.forName(charsetName);
        }
        return Charset.defaultCharset();
    }

    public void setCharset(Charset charset) {
        if (charset != null) {
            this.charsetName = charset.name();
        }
    }

    public Map<String, String> getBuildParameters() {
        return this.buildParameters;
    }

    public String getNodeName(String value) {
        return defaultIfNull(nodeName, value);
    }

    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }

    public String getBranch(String value) {
        return defaultIfNull(branch, value);
    }

    public void setBranch(String branch) {
        this.branch = branch;
    }

    public String getBuildNumber(String value) {
        return defaultIfNull(buildNumber, value);
    }

    public void setBuildNumber(String buildNumber) {
        this.buildNumber = buildNumber;
    }

    public Long getDuration(Long value) {
        return defaultIfNull(duration, value);
    }

    public void setDuration(Long duration) {
        this.duration = duration;
    }

    public Long getEndTime(Long value) {
        return defaultIfNull(endTime, value);
    }

    public void setEndTime(Long endTime) {
        this.endTime = endTime;
    }

    public Long getStartTime(Long value) {
        return defaultIfNull(startTime, value);
    }

    public void setStartTime(Long startTime) {
        this.startTime = startTime;
    }

    public Long getMillisInQueue(Long value) {
        return defaultIfNull(millisInQueue, value);
    }

    public void setMillisInQueue(Long millisInQueue) {
        this.millisInQueue = millisInQueue;
    }

    public Long getPropagatedMillisInQueue(Long value) {
        return defaultIfNull(propagatedMillisInQueue, value);
    }

    public void setPropagatedMillisInQueue(Long propagatedMillisInQueue) {
        this.propagatedMillisInQueue = propagatedMillisInQueue;
    }

    public String getBuildId(String value) {
        return defaultIfNull(buildId, value);
    }

    public void setBuildId(String buildId) {
        this.buildId = buildId;
    }

    public String getBuildTag(String value) {
        return defaultIfNull(buildTag, value);
    }

    public void setBuildTag(String buildTag) {
        this.buildTag = buildTag;
    }

    public String getJenkinsUrl(String value) {
        return defaultIfNull(jenkinsUrl, value);
    }

    public void setJenkinsUrl(String jenkinsUrl) {
        this.jenkinsUrl = jenkinsUrl;
    }

    public String getExecutorNumber(String value) {
        return defaultIfNull(executorNumber, value);
    }

    public void setExecutorNumber(String executorNumber) {
        this.executorNumber = executorNumber;
    }

    public String getJavaHome(String value) {
        return defaultIfNull(javaHome, value);
    }

    public void setJavaHome(String javaHome) {
        this.javaHome = javaHome;
    }

    public String getWorkspace(String value) {
        return defaultIfNull(workspace, value);
    }

    public void setWorkspace(String workspace) {
        this.workspace = workspace;
    }

    public String getGitUrl(String value) {
        return defaultIfNull(gitUrl, value);
    }

    public void setGitUrl(String gitUrl) {
        this.gitUrl = gitUrl;
    }

    public String getGitCommit(String value) {
        return defaultIfNull(gitCommit, value);
    }

    public void setGitCommit(String gitCommit) {
        this.gitCommit = gitCommit;
    }

    public String getGitMessage(String value) {
        return defaultIfNull(gitMessage, value);
    }

    public void setGitMessage(String gitMessage) {
        this.gitMessage = gitMessage;
    }

    public String getGitAuthorName(final String value) {
        return defaultIfNull(gitAuthorName, value);
    }

    public void setGitAuthorName(String gitAuthorName) {
        this.gitAuthorName = gitAuthorName;
    }

    public String getGitAuthorEmail(final String value) {
        return defaultIfNull(gitAuthorEmail, value);
    }

    public void setGitAuthorEmail(String gitAuthorEmail) {
        this.gitAuthorEmail = gitAuthorEmail;
    }

    public String getGitCommitterName(final String value) {
        return defaultIfNull(gitCommitterName, value);
    }

    public void setGitCommitterName(String gitCommitterName) {
        this.gitCommitterName = gitCommitterName;
    }

    public String getGitCommitterEmail(final String value) {
        return defaultIfNull(gitCommitterEmail, value);
    }

    public void setGitCommitterEmail(String gitCommitterEmail) {
        this.gitCommitterEmail = gitCommitterEmail;
    }

    public String getGitAuthorDate(final String value) {
        return defaultIfNull(gitAuthorDate, value);
    }

    public void setGitAuthorDate(String gitAuthorDate) {
        this.gitAuthorDate = gitAuthorDate;
    }

    public String getGitCommitterDate(final String value) {
        return defaultIfNull(gitCommitterDate, value);
    }

    public void setGitCommitterDate(String gitCommitterDate) {
        this.gitCommitterDate = gitCommitterDate;
    }

    public String getGitDefaultBranch(String value) {
        return defaultIfNull(gitDefaultBranch, value);
    }

    public void setGitDefaultBranch(String gitDefaultBranch) {
        this.gitDefaultBranch = gitDefaultBranch;
    }

    public String getGitTag(String value) {
        return defaultIfNull(gitTag, value);
    }

    public void setGitTag(String gitTag) {
        this.gitTag = gitTag;
    }

    public String getPromotedUrl(String value) {
        return defaultIfNull(promotedUrl, value);
    }

    public void setPromotedUrl(String promotedUrl) {
        this.promotedUrl = promotedUrl;
    }

    public String getPromotedJobName(String value) {
        return defaultIfNull(promotedJobName, value);
    }

    public void setPromotedJobName(String promotedJobName) {
        this.promotedJobName = promotedJobName;
    }

    public String getPromotedNumber(String value) {
        return defaultIfNull(promotedNumber, value);
    }

    public void setPromotedNumber(String promotedNumber) {
        this.promotedNumber = promotedNumber;
    }

    public String getPromotedId(String value) {
        return defaultIfNull(promotedId, value);
    }

    public void setPromotedId(String promotedId) {
        this.promotedId = promotedId;
    }

    public String getPromotedTimestamp(String value) {
        return defaultIfNull(promotedTimestamp, value);
    }

    public void setPromotedTimestamp(String promotedTimestamp) {
        this.promotedTimestamp = promotedTimestamp;
    }

    public String getPromotedUserName(String value) {
        return defaultIfNull(promotedUserName, value);
    }

    public void setPromotedUserName(String promotedUserName) {
        this.promotedUserName = promotedUserName;
    }

    public String getPromotedUserId(String value) {
        return defaultIfNull(promotedUserId, value);
    }

    public void setPromotedUserId(String promotedUserId) {
        this.promotedUserId = promotedUserId;
    }

    public String getPromotedJobFullName(String value) {
        return defaultIfNull(promotedJobFullName, value);
    }

    public void setPromotedJobFullName(String promotedJobFullName) {
        this.promotedJobFullName = promotedJobFullName;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    private String getUserId(Run run) {
        if (promotedUserId != null){
            return promotedUserId;
        }
        String userName;
        List<CauseAction> actions = null;
        try {
            actions = run.getActions(CauseAction.class);
        }catch(NullPointerException e){
            //noop
        }
        if(actions != null){
            for (CauseAction action : actions) {
                if (action != null && action.getCauses() != null) {
                    for (Cause cause : action.getCauses()) {
                        userName = getUserId(cause);
                        if (userName != null) {
                            return userName;
                        }
                    }
                }
            }
        }

        if (run.getParent().getClass().getName().equals("hudson.maven.MavenModule")) {
            return "maven";
        }
        return "anonymous";
    }

    private String getUserId(Cause cause){
        if (cause instanceof TimerTrigger.TimerTriggerCause) {
            return "timer";
        } else if (cause instanceof SCMTrigger.SCMTriggerCause) {
            return "scm";
        } else if (cause instanceof Cause.UserIdCause) {
            String userName = ((Cause.UserIdCause) cause).getUserId();
            if (userName != null) {
                return userName;
            }
        } else if (cause instanceof Cause.UpstreamCause) {
            for (Cause upstreamCause : ((Cause.UpstreamCause) cause).getUpstreamCauses()) {
                String username = getUserId(upstreamCause);
                if (username != null) {
                    return username;
                }
            }
        }
        return null;
    }

    public String getUserEmail(final String value) {
        return defaultIfNull(this.userEmail, value);
    }

    private String getUserEmailByUserId(String userId) {
        try {
            if(StringUtils.isEmpty(userId)) {
                return null;
            }

            final User user = User.getById(userId, false);
            if(user == null){
                return null;
            }

            final Mailer.UserProperty mailInfo = user.getProperty(Mailer.UserProperty.class);
            if(mailInfo != null) {
                return mailInfo.getEmailAddress();
            }

            return null;
        } catch (Throwable ex) {
            DatadogUtilities.severe(LOGGER, ex, "Failed to obtain the user email associated with the user " + userId);
            return null;
        }
    }

    public void setUserEmail(final String userEmail) {
        this.userEmail = userEmail;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }

    public void setSpanId(String spanId) {
        this.spanId = spanId;
    }

    public JSONObject addLogAttributes(){

        JSONObject payload = new JSONObject();

        try {

            JSONObject build = new JSONObject();
            build.put("number", this.buildNumber);
            build.put("id", this.buildId);
            build.put("url", this.buildUrl);
            payload.put("build", build);

            JSONObject http = new JSONObject();
            http.put("url", this.jenkinsUrl);
            payload.put("http", http);

            JSONObject jenkins = new JSONObject();
            jenkins.put("node_name", this.nodeName);
            jenkins.put("job_name", this.jobName);
            jenkins.put("build_tag", this.buildTag);
            jenkins.put("executor_number", this.executorNumber);
            jenkins.put("java_home", this.javaHome);
            jenkins.put("workspace", this.workspace);

            JSONObject promoted = new JSONObject();
            jenkins.put("promoted", promoted);
            if(promotedUrl != null){
                jenkins.put("url", this.promotedUrl);
            }
            if(promotedJobName != null){
                jenkins.put("job_name", this.promotedJobName);
            }
            if(promotedNumber != null){
                jenkins.put("number", this.promotedNumber);
            }
            if(promotedId != null){
                jenkins.put("id", this.promotedId);
            }
            if(promotedTimestamp != null){
                jenkins.put("timestamp", this.promotedTimestamp);
            }
            if(promotedUserName != null){
                jenkins.put("user_name", this.promotedUserName);
            }
            if(promotedUserId != null){
                jenkins.put("user_id", this.promotedUserId);
            }
            if(promotedJobFullName != null){
                jenkins.put("job_full_name", this.promotedJobFullName);
            }
            jenkins.put("result", this.result);

            payload.put("jenkins", jenkins);

            JSONObject scm = new JSONObject();
            scm.put("branch", this.branch);
            scm.put("git_url", this.gitUrl);
            scm.put("git_commit", this.gitCommit);
            payload.put("scm", scm);

            JSONObject user = new JSONObject();
            user.put("id", this.userId);
            payload.put("usr", user);

            payload.put("hostname", this.hostname);

            if(traceId != null){
                payload.put("dd.trace_id", this.traceId);
            }

            if(spanId != null) {
                payload.put("dd.span_id", this.spanId);
            }
            return payload;
        } catch (Exception e){
            DatadogUtilities.severe(LOGGER, e, "Failed to construct log attributes");
            return new JSONObject();
        }
    }

    private static String normalizeJobName(String jobName) {
        if (jobName == null) {
            return null;
        }
        return jobName.replaceAll("»", "/").replaceAll(" ", "");
    }

}


text:
you are here : home » news »
EPA calls for a move to a low carbon economy
by Tim O Brien
ECONOMIC RECOVERY when it comes must involve Ireland developing a low-carbon "smart, green economy", the Environmental Protection Agency (EPA) said yesterday.
Launching the agency's annual highlights for 2008, EPA director general Dr Mary Kelly said the environment was "an asset under threat" and early warnings about the potentially catastrophic effects of climate change "must be heeded".
While she said there was little indication of the scale of the economic crisis the world was facing in early 2008, Dr Kelly warned that the economic crisis was now coinciding "with a climate-change crisis and an ecosystems crisis".
She said the State investment in environmental infrastructure must now be given priority to ensure Ireland "in the first instance catches up to European norms in key areas like waste-water treatment and the provision of good-quality drinking water to all consumers".
Dr Kelly said "fundamental change" was required to ensure that economic recovery was based on low-carbon, sustainable principles.
She said there were clearly many economic and social advantages in developing a green economy.
She claimed Ireland had a real opportunity to become a world leader in renewable energies and to position itself as a net exporter of energy in years to come.

redpajama_set_name: RedPajamaCommonCrawl


We think the venue you select is one of the most important pieces of your wedding puzzle. Not just any old place will do! Club Motor Estates is a 17-acre campus with some of the finest automobiles in the world. The atmosphere will ignite you and your guests. Walk into a modern foyer as a magnificent car greets you. Your guests will be blown away. We make your special day one to remember. Surrounded by beautiful cars or, being driven into the ballroom and dropped off at your special table or, having that high octane atmosphere throughout the venue, we can make it happen. As the preferred caterer for Club Motor Estates, our mission is to provide world-class dining and superior event planning and management. Schedule your tour today!


text:
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

/// <reference path="../UnitTestFramework/UnitTestFramework.js" />
if (this.WScript && this.WScript.LoadScriptFile) {
    WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
}

var p = { pp: 123 };

function F() { this.dummy = 12; /*reserve slots, make jit code simpler to read*/ }
F.prototype = p;

function make_object() {
    /// Create new objects of the same Type, and with __proto__ "p"
    return new F();
}

function foo(o) {
    o.x = 1;
    o.y = 2;
}

// Need to run this twice. Test with maxinterpretcount 1 and 2
foo(make_object());
foo(make_object());

var o3 = make_object();

assert.isTrue(Object.getPrototypeOf(o3) === p);
p.__proto__ = { get x() { return "x"; } };

foo(o3);

assert.areEqual("x", o3.x, "Shouldn't add field x");

WScript.Echo("pass");

redpajama_set_name: RedPajamaGithub


text:
Q: How to handle 2 different layouts in an activity Android [Edited]:
I have already developed one application which works well on different screen size phones and tablets, I followed as per android guidelines to create the different sets of UI layouts to cater with different sizes of screens(phones and tablets) and all layouts will be in portrait mode. Everything works fine till then but now I got one new requirement where the layouts of tablets will be changed i.e. it will be having some extra information than phone layouts and all new layouts will be in landscape mode.
Now my doubts are:

*

*In old implementation, all layouts name are same in different layout folders i.e. layout,layout-small,layout-large etc... so , as per new requirement, all layouts of large and extra-large should be in landscape mode but if i keep the same name of layout then how do I handle the orientation? At present, orientation attribute mentioned in manifest file for each activity.

*If I keep the different name of these layouts then I have to handle at run time i.e. while loading the activity,based on checking on phone screen size and then load the respective layout, so same activity can load different layout based on checking screen size. Will it be a optimal approach to do so?

*OR,Do I have to altogether introduce new activities for all new layouts to handle this scenario?

Please suggest me best approach to handle this scenario.

A: A good point to start on this would be official Android documents (below links).

*

*http://developer.android.com/guide/practices/screens_support.html

*http://developer.android.com/training/basics/supporting-devices/screens.html
In a nutshell I can tell you would have to create multiple layouts to address your requirement for supporting multiple screen sizes/resolution. Within your application source directory you will have to create a different layout xml (with same name) under different resource-layout-directories as shown below:
 res/
        layout/              # default (portrait)
            main.xml
        layout-land/         # landscape
            main.xml
        layout-large/        # large screen devices (portrait)
            main.xml
        layout-large-land/   # large screen devices (landscape)
            main.xml

A: I would suggest you to name all similar files with the same name.
Take full advantage of the qualifiers provided by Android like the size, or the set width qualifier.  You may have a single pane layout for small screen phones and multi pane layout for tablets. It's a good advice to provide multi pane layout ( you may combine two existing layouts into one ) for landscape orientation.
For example :
res/layout/onepane.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment android:id="@+id/frag1"
          android:layout_height="fill_parent"
          android:name="com.example.android.dummyApp"
          android:layout_width="match_parent"
          android:background="@drawable/bg"/>
          </LinearLayout>

res/layout/twopanes.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment android:id="@+id/fragone"
          android:layout_height="fill_parent"
          android:name="com.example.android.dummyApp"
          android:layout_width="400dp"
          android:layout_marginRight="10dp"
          android:background="@drawable/bg"/>
<fragment android:id="@+id/fragtwo"
          android:layout_height="fill_parent"
          android:name="com.example.android.dummyApp"
          android:layout_width="fill_parent" />
         </LinearLayout>

Now that all possible layouts are defined, it's just a matter of mapping the correct layout to each configuration using the configuration qualifiers. You can now do it using the layout alias technique:
res/values/layouts.xml:
<resources>
<item name="main_layout" type="layout">@layout/onepane</item>
<bool name="has_two_panes">false</bool>
</resources>

res/values-sw600dp-land/layouts.xml:
<resources>
<item name="main_layout" type="layout">@layout/twopanes</item>
<bool name="has_two_panes">true</bool>
</resources>

Note : The bool values in the two xml files in values folder.
The Smallest-width qualifier allows you to target screens that have a certain minimum width given in dp. Instead of the large size qualifier, use sw600dp to indicate the two-pane layout is for screens on which the smallest-width is 600 dp.
Also, another solution:
If you are planning to make different activities for different screen sizes, you can build multiple apk for the same project. There should be a separate Android project for each APK you're going to release.
Please look at this link for more information on Multiple APKs.
http://developer.android.com/training/multiple-apks/screensize.html

A: Personally, I'd make two different Fragments, with two different Fragment Layouts, and I'd load the Fragment for the right screen size based on the layout folder identifier, like so: http://developer.android.com/training/basics/supporting-devices/screens.html
Typical Fragment:
public class MyFragment extends Fragment implements View.OnClickListener
{
    private Button btnSave;
    private Button btnCancel;

    public MyFragment()
    {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View rootView = inflater.inflate(R.layout.fragment_myfragment_small, container, false);
        return rootView;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState)
    {
        super.onViewCreated(view, savedInstanceState);
        btnSave = (Button) getActivity().findViewById(R.id.myfragment_small_save);
        btnCancel = (Button) getActivity().findViewById(R.id.myfragment_small_cancel);

        btnSave.setOnClickListener(this);
        btnCancel.setOnClickListener(this);
    }

    @Override
    public void onClick(View v)
    {
        if (btnSave == v)
        {
            save();
        }
        else if (btnCancel == v)
        {
            cancel();
        }
    }
}

And do the same thing for the larger one. Bonus points if you reuse the save() and cancel() function by extending from MyFragment, or by ripping out the logic of them into another class.
Static fragment linking:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <fragment
        android:id="@+id/fragment_myfragment_small"
        android:name="com.example.stuff.longer.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

And the layout for the fragment in fragment_myfragment_small.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
<Button android:id="@+id/myfragment_small_cancel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="@string/cancel"
/>
<Button android:id="@+id/myfragment_small_save"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/myfragment_small_cancel"
        android:text="@string/save"
/>

</RelativeLayout>

And make a second one for the second, larger layout. Place the layout in a different \res\layout folder, such as \res\layout-large.

redpajama_set_name: RedPajamaStackExchange


text:
Written by Keith Meintjes on 04 January 2013 .
Following the re-establishment of British authority at the Cape in 1806, the British found themselves increasingly drawn into the conflict between the indigenous peoples and the Boers. By 1810, the major confrontation was with the Xhosa on the Eastern Frontier.
In October, 1811, the new Governor, John Cradock, resolved to clear the Zuurveld of the Xhosa, and to drive them back to east of the Fish River. He appointed Colonel John Graham to this task. By December, Graham had raised three forces. The southernmost was near the mouth of the Sundays River, while a second was in the area of Coerney near Addo. The third was a Commando from Graaff-Reinet, led by the Landdrost, Anders Stockenström. They were stationed north of the Zuurberg (somewhere in the area south of Ann's Villa), to protect Bruintjeshoogte and Graaff-Reinet against Xhosa intrusions from the south and east.
After events around Christmas Day, Graham concluded the major Xhosa force was concentrated near his central unit at Addo. He summoned Stockenström to bring his force across the Zuurberg. Stockenström responded with about forty of his men, who left their camp at sunrise on December 28, 1811 to travel south over the Zuurberg.
Near the peak of the Zuurberg, Stockenström's party encountered a group of Xhosa. A palaver began and continued for a time, but it ended with a surprise attack on the Landdrost and his men. Stockenström and about a dozen others of his force were killed. This was in the first few days of the Fourth Frontier War (1811-12).
Detailed accounts of this incident can be found in Stockenström, Pringle, Cory, and Mostert (see References below). A shorter account is in the Dictionary of South African Biography (DSAB). These accounts differ in some details, as will be discussed.
I became interested in this incident after reading Pringle's description of the place: "On their route they had to pass along the narrow ridge called Slachters-nek, which connects two arms of the great mountain chain … One of the kloofs of the White river, beautifully lined with various sorts of tall forest timber and thick brushwood, joins another kloof, equally picturesque and magnificently wooded, stretching down into the valley of the Courney, thus forming, together with the stupendous cliffs above, over-hanging their deep and sombre recesses, one of the most remarkable landscapes in Southern Africa." (This is not the same place where the Slagtersnek rebellion occurred.)
I was surprised that the precise location of this incident is not known; that the graves of those slain are not marked; and that I could not find a list of those killed.
The Men Involved
Although historians are specific (and disagree) about the number of men killed and wounded, they name only a few. Daniel Jacobs recently found a document in the Cape Archives (CO 2580/4), which is a report from officials in Graaff-Reinet to Governor Cradock. The report is in Dutch, and there is an English translation. The side-by-side transcriptions of the documents are here.
Among those killed, it names the Landdrost, two Veld-Kornets, and seven Burgers. Two unnamed young Hottentots were also killed. Two men (also named) escaped on foot. The report is signed by four officials, and the informant was Lieutenant-Colonel Lyster.
Not listed in the report is Paul du Plessis, who is stated by both Stockenström and Pringle to have been a survivor who escaped on foot.
Who were these men? Have a look at the list of names, and what is known of their genealogy. If you can add to these genealogies, please contact eGGSA.
The letter from Graaff-Reinet has the Landdrost and eleven of his men killed, and three escaped. Is this a complete list? Probably not. Here is what the historians say:
Stockenström lists Paul du Plessis and Christian Roberts (the latter "severely wounded") as survivors, and says that fourteen were then missing. The next day, "Their bodies were found … and we buried them." He is quite precise about the count of men.
Cory: "The landdrost and thirteen of the Boers were killed, two though wounded, managed to escape."
Pringle: "Mr. Stockenström and fourteen of his men fell, pierced by innumerable wounds. … two, who not being able to get on horseback, crept into the thicket, and eluded the search of the Caffers , until darkness enabled them to re-cross the mountains to the spot where they had that morning started. One of these two men was my acquaintance Paul du Plessies of Zwagershoek."
Mostert: "In moments the Graaf Reinet Landdrost and fourteen of his men lay dead, cut to pieces by the assegais. Two of the Boers managed to crawl into the bush, where they hid."
DSAB: "Stockenström, eight burghers and a half-caste interpreter were killed, and four men were wounded, although they managed to escape."
The Date of the Incident.
According to the letter from Graaff-Reinet, the massacre occurred on December 29, 1811. But, there is not agreement:
DSAB: " At sunset on 29.12.1811 he set out …" Clearly, it should be "sunrise".
Pringle: "On the morning of the 28th December .."
Cory: December 29.
Stockenström: Of his father, he says "He went into his tent and slept for the last time till peep of day, the 28th December, 1811."
Mostert: 28 December.
The date of 28 December is likely correct, for it fits in with the chronology of the campaign in British documents. The time was noon, or soon thereafter.
The Place of the Incident
Although I have not been there, I believe the place of the massacre is on the Zuurberg pass, a few km north of the Zuurberg Inn. This is on the R335, which runs from Port Elizabeth north to Addo, Zuurberg, Ann's Villa, and Somerset East. The latitude and longitude are about -33.335 and 25.759
Stockenström: "… the spot where the massacre had taken place. This was on the narrowest part of the Doorn Neck - the watershed between the Wit-Rivier and Kournay. The new Zuurberg Road has cut away the very tree under which my father and his party sat and stood when they met their fate." (The Zuurberg Pass was built in 1848-58.)
Stockenström returned later to the place, and "found there a worthy farmer named Matthews in possession" Stockenström offered to purchase the site of the massacre, but Matthews refused, saying he would be honoured to erect the monument. On another visit, Stockenström found the place in possession of "the brother of this same Matthew". Stockenström on this occasion offered to purchase the spot where the fallen were buried, but says he was "too sick to proceed in the matter". These Matthews were owners of the farm Doornnek, on which the Zuurberg Inn now stands.
So, neither the spot of the massacre nor the location of the graves was marked. The burgers of Graaff-Reinet asked to build a monument, but they were refused with assurances a monument would be built by the Colonial government. That never happened, possibly because the younger Stockenström became a controversial figure and fell out of favour with the authorities.
Pringle visited the spot in 1821, and says: "The precise spot where the bodies were interred could not, when I was there, be discovered. It is little to the credit of the Colonial Government that not even a rude stone has been erected to mark the grave of this meritorious magistrate …".
According to DSAB, the site of Anders Stockenström's grave is unknown.
Eileen Russell, however, has noted that there is a framed document on the wall of a lounge at the Zuurberg Inn. It is undated, and written by Mrs. D E Rivett-Carnac of Grahamstown. It says of Landdrost Stockenström: "His grave was at a spot near the Post Office until removal many years later to the family home near Bedford." This would be Maasström, granted to Andries Stockenström in 1820. Neither Sir Andries nor his wife are buried there.
Copyright Keith Meintjes © 2005
Noel Mostert, "Frontiers: The epic of South Africa's creation and the tragedy of the Xhosa people, Knopf, New York, 1992.
Thomas Pringle, "Narrative of a residence in South Africa", Struik, Cape Town, 1966.
C.W. Hutton (ed.), "The autobiography of the late Sir Andries Stockenström, Baronet.", Juta, Cape Town, 1887. Facsimile reproduction, Struik, Cape Town, 1964.
G.E. Cory, "The Rise of South Africa", Facsimile reprint, Struik, Cape Town, 1965.
Dictionary of South African Biography, Vol. I, pp 773-4, "Stockenström, Anders", Tafelberg, Cape Town, 1968.
Cape Archives, Colonial Office Archives, document CO 2580/4.


This of six graduated handheld microscopes is housed in a rectangular leather-bound case with two brass hook-and-eye closures. The interior of the case is lined with a faded rust-colored chamois cloth. Each microscope has a brass barrel case with rounded ebony handle. A small pin inside the barrel is used to secure specimens. The uniformity of the workmanship of the microscopes, the simplicity of the turned wooden handles, and the rust-colored, chamois-lined, interior of the case indicates this set was made in the first half of the 19th century.


text:
London to Liverpool by train
© Shahid Khan
Travelling from London to Liverpool by train
Fast trains from London to Liverpool take around 2 hours and 1 minute, covering a distance of approximately 286 kilometres. There are frequent services on the rail route between London and Liverpool.
1. Are there direct trains from London to Liverpool?
Direct trains from London to Liverpool have been found.
We usually find around 29 direct trains on the route from London to Liverpool every weekday.
2. How long is the train journey from London to Liverpool?
The London to Liverpool train travel time is normally about 2 hours and 1 minute, whatever time you make the journey.
3. What are the London to Liverpool train times and schedule?
On weekdays the earliest direct train to Liverpool is usually scheduled to depart London around 05:26 and the last train is around 21:07. At weekends the first train of the day leaves London around 07:07, and the last at 21:21.
What's the London to Liverpool train price?
The earlier you book the better, and the cheapest tickets we've found for trains from London to Liverpool are $16.28.
When to book London to Liverpool train tickets?
Trains in the UK usually open for booking around 3 months in advance. If booking is not yet open for your dates then you can set a booking alert to receive an email on the day that the cheapest tickets are released for your journey from London to Liverpool by train.
Which train companies operate between London and Liverpool?
More than one train company operates on the route from London to Liverpool, so you'll be travelling with one or more of the following rail operators:
Avanti West Coast
West Midlands Trains
Liverpool to London by train
Other journeys to Liverpool View all journeys to Liverpool
From Scarborough From $25.65
From Stockport From $8.14
From Manchester From $3.80
From Crewe From $4.07
From Preston (Lancs) From $6.79
From Wigan From $10.04
From Bolton From $11.54
From Birmingham International From $17.64
It is very easy to travel by train from London to Liverpool. Virgin Trains offer an hourly service between the two cities. It's an interesting journey that cuts across the English Midlands without actually passing through major cities like Birmingham.
Another rail operator, London Midland, offer an alternative route to Liverpool, usually requiring at least one change of train along the way. But it is so slow, that we don't offer that option on Loco2.
London to Liverpool
Join the Pendolino train at London's Euston station for the journey to Liverpool. About twenty minutes before reaching Liverpool, all trains stop at Runcorn and then cross the Mersey – that's the river which has shaped the history and image of Liverpool. Your journey ends at Lime Street station in the heart of the Merseyside city.
Blog posts featuring London or Liverpool


Hey Boris, kill moose and (especially) squirrel!
It seems like a pretty big day when you give it a little thought. The President stopped in Cincinnati to grab some coneys* and pimp his jobs plan by talking about fixing/replacing the bridge connecting the two states of his Congressional archenemies. As if that wasn't enough, scientists at CERN believe they recorded a particle travelling faster than the speed of light.
Now, just for the record, with the possible exception of an adult racing to the restroom in a public place when that familiar pre-Pepto-Bismol cramp strikes out of nowhere, moving faster than the speed of light is supposed to be impossible according to Relativistic physics.
So, yeah, pretty big stuff, indeed. Which is, of course, why I'm going to write about a squirrel today.
Well, not just any squirrel. A poor, dead squirrel. Let's call him Rocky.
Poor Rocky had the misfortune of having his path intersect with something much larger and heavier this morning, right near the end of my driveway, in the middle of the street. The Puddinette came home from running some errands before I left for work and informed me of the sad affair.
As is my way, of course, I shrugged and went back to thinking about space ships and robots that can become hamburgers…a tasty, tasty, transformation.
After my loving wife applied the appropriate "attitude adjustment" with my now least-favorite cast iron frying pan*, I saw the issue in a completely new light. That is, the underlining problem with Rocky the Recently Deceased became abundantly clear. Namely, we have three sons, two of which are now old enough to be mesmerized by the proverbial dead critter.
So, realizing that in all likelihood, Rocky would undergo a heavy battery of tests administered with pointy sticks this afternoon as soon as they boys got home from school, we agreed that a call to the city was in order. Because, obviously, the city crew is supposed to come out and take care of your roadkill issues for you.
Except, apparently they stopped doing that about the same time Mrs. Cleaver ripped her pearls off in disgust and the milkman quit delivering two quarts of whole milk every week. That's right, the lovely woman on the phone at the city building where we so happily live, thrive, and most importantly, pay taxes suggested that we go clean it up ourselves. You know, like we'd do if our dog crapped in the neighbor's yard. Because the public works guys don't do stuff unless it's like a deer or something.
I guess there's a weight limit on what public works considers a keeper.
The thing is, though, this wasn't the neighbor's yard we were talking about, nor dog pooh, for that matter. And the last time I checked, the pet store didn't sell overpriced dead squirrel clean-up bags that you conveniently turn inside out. Our squirrel wasn't a cute little pile of dootie, either.
Rocky was basically unrecognizable. The poor critter looked like he swallowed a whole live grenade and then ran into the street, chittering that we release his comrades. Or he met his end at the hands of a full speed steam locomotive travelling past my house for some reason. I mean, isn't it a little early for the Polar Express?
I don't know. What I do know is that I don't care what kind of pickup bag you might consider using, trying to get Rocky disposed of in that manner would be like trying to pick up Aunt Judy's strange Ambrosia salad with an inside-out plastic grocery bag while wearing mittens.
So what do we do poor Rocky? I'm still not sure. Hopefully those scientists will harness this speed-of-light research and get me some kind of disintegration ray soon.
Otherwise, I'll never be able to eat Aunt Judy's food at Thanksgiving again.
*I made the coney part up, but come on, you know he had to get some chili or goetta action while he was here.


text:
Zaugao (cyr. Заугао) – wieś w Czarnogórze, w gminie Podgorica. W 2011 roku liczyła 9 mieszkańców.

Przypisy

Miejscowości w gminie Podgorica

redpajama_set_name: RedPajamaWikipedia


CloneDVD Studio Free MP4 to AVI Converte 1.0.0.0 CloneDVD Free MP4 to AVI Converter can free convert MP4 files to AVI format with ease. With this free MP4 to AVI converter, you can convert and play MP4 movies on AVI supported devices on the go.
CloneDVD Studio Free MP4 Converter 1.0.0.0 CloneDVD Studio Free MP4 Video Converter can free convert video files to MP4 format compatible with popular multimedia devices such as Amazon Kindle Fire, Apple iPod, iPhone, iPad, etc.
CloneDVD Studio Free 3GP Converter 1.0.0.0 CloneDVD Studio Free 3GP Converter is a 100% free 3gp video converter which supports convert MP4, MPEG, FLV, WMV, MKV, MOV, AVI etc to 3GP videos at blazing speed while reserve high quality.
CloneDVD Studio Free DVD to AVI Ripper 1.0.0.0 CloneDVD Studio Free DVD to AVI Converter is a totally free and clean video converting solution allowing users to rip and convert DVD movies to AVI files without quality loss.
CloneDVD Studio Free MP4 to MOV Converter 1.0.0.0 CloneDVD Studio Free MP4 to MOV Converter is a 100% free video converting program which offers you a perfect solution to convert MP4 to QuickTime MOV.
CloneDVD Studio Free MP4 to WMV Converter 1.0.0.0 CloneDVD Studio Free MP4 to WMV Converter allows users to free convert MP4 videos to WMV files easily and quickly. By converting MP4 to WMV, you could enjoy MP4 videos on Windows Media Player.
CloneDVD Studio Free MP4 to 3GP Converter 1.0.0.0 CloneDVD Studio Free MP4 to 3GP Video Converter is a totally free video converter application for converting MP4 video to 3GP format. This free MP4 to 3GP video converter provides you fast MP4 to 3GP video converting speed and high output quality.
CloneDVD Studio Free MP4 to FLV Converter 1.0.0.0 CloneDVD Studio Free MP4 to FLV Converter provides an easiest way to convert MP4 to FLV at fast speed and high quality.
CloneDVD Studio Free MOV Converter 1.0.0.0 CloneDVD Studio Free MOV Converter is an easy-to-use video converter program allowing users to easily convert common videos to QuickTime (.MOV) files with high quality and fast speed.
CloneDVD Studio Free MKV Converter 1.0.0.0 CloneDVD Studio Free MKV Converter helps users to convert common videos to mkv files, like avi to mkv, flv to mkv, 3gp to mkv, mov to mkv, with ease.
CloneDVD Studio Free DVD to MKV Ripper 1.0.0.0 CloneDVD Studio Free DVD to MKV Ripper is a 100% free yet clean video converting program to help you rip and convert DVD movies to MKV format easily and quickly, and without being disturbed by malware, spyware, adware and virus.
CloneDVD Studio Free DVD to iPad Ripper 1.0.0.0 CloneDVD Studio Free DVD to iPad Ripper is a 100% free yet professional DVD ripping program allowing users to rip and convert DVD movies to iPad supported format for playback on iPad2/3/Mini/4.
CloneDVD Free DVD to iPhone Converter 1.0.0.0 CloneDVD Studio Free DVD to iPhone Ripper is a 100% free DVD to iPhone DVD ripping software which facilitates user to play DVD movie on iPhone 5S, iPhone 5C, iPhone 5, iPhone 4S, iPhone 4, etc.
CloneDVD Studio Free AVI to MOV Converte 1.0.0.0 CloneDVD Studio Free to AVI to MOV Converter is a professional and easy-to-use video conversion software which can easily convert AVI to MOV with several clicks.
CloneDVD Studio Free AVI to iPod Convert 1.0.0.0 CloneDVD Studio Free AVI to iPod Converter is a 100% free and professional video converting solution aiming at helping users to convert AVI video into the formats of iPod for playing.
CloneDVD Studio Free AVI to iPad Convert 1.0.0.0 CloneDVD Studio Free AVI to iPad Converter is specially designed to convert AVI videos to iPad2, iPad3, iPad Mini, etc, easily and quickly.
CloneDVD Free AVI to iPhone Converter 1.0.0.0 CloneDVD Studio Free AVI to iPhone Converter is a 100% free yet easy to use AVI to iPhone video converting tool which is specially designed to help user convert AVI video to Apple iPhone 4, iPhone 4S, iPhone 5, iPhone 5S, iPhone 5C and etc.


It wasn't too long after Lily Pebbles shared the recipe that 'brookies' became half an internet sensation. 'Brookies' -meaning a brownie mixed with a cookie- are supposed to pick up the crunch of a cookie with the inside chew of a brownie. A mouth-watering idea with an instagram-worthy outcome, no wonder so many bloggers have taken it upon themselves to dash to the kitchen and have their own attempt (myself included!).
You can find the recipe here, and for an advanced warning- it makes a lot of brookies.
My final outcome: I loved them! They went down a treat with everyone who tried them, they're light, and they look great. I found they taste best dipped in something (I used milk), as they're a lot more brownie-like. Easy recipe, providing you allow yourself some time for it.
Mmm. Currently drooling. These look absolutely scrumptious & they mix 2 amazing things together.
ooh these look so delicious! I am going to have to try making them!
Good luck! They're really easy to make.


text:
Q: Insert  tag to the second textbox JS I'm building a simple text editor and I start with basics - as user press enter and start a new line a want to insert br to the the second textbox. The second textbox is meant to send ready formatted text to the database. As of now I managed to copy data from first to second textbox as user typing. Hence, I want to disable viewing br in the first textbox. Is there a way not to display br in the first textbox but technically have it. Thank you in advance!
DEMO: https://jsfiddle.net/mxr7hz3p/
Textboxes:
 <textarea type="text" id="first"></textarea>
 <textarea type="text" id="second"></textarea>

JS:
$(function (){
    $('#first').keyup(function (e){
        if(e.keyCode == 13){
            var curr = getCaret(this);
            var val = $(this).val();
            var end = val.length;

            $(this).val( val.substr(0, curr) + '
' + val.substr(curr, end));
    }})
});

    function getCaret(el) {
       if (el.selectionStart) {
          return el.selectionStart;
       }
       else if (document.selection) {
            el.focus();

            var r = document.selection.createRange();
                if (r == null) {
                return 0;
            }

            var re = el.createTextRange(),
            rc = re.duplicate();
            re.moveToBookmark(r.getBookmark());
            rc.setEndPoint('EndToStart', re);

            return rc.text.length;
         }
         return 0;
     }

$('#first').keyup(function(){
    $('#second').val(this.value);
});

A: You can simplify the JS in the fiddle to do this
$('#first').keyup(function(){
  var val = $(this).val();

  val = val.replace(/\n/g, '
')

  $('#second').val(val);
});

https://jsfiddle.net/t3vzgnp7/2/


text:
La Fédération de Russie a participé aux Jeux paralympiques de 2012 à Londres qui se sont déroulés dans la capitale du Royaume-Uni du 29 août au 9 septembre 2012.

Il s'agissait de sa cinquième participation. En 1988, elle était présente sous le drapeau de l'Union Soviétique et en 1992 sous celui d'une équipe unifiée, qui était constituée des anciennes républiques de l'Union Soviétique, excepté l'Estonie, la Géorgie, La Lituanie et la Lettonie.

182 athlètes russes ont pris part à 12 des 20 épreuves.

Lors des Jeux paralympiques de 2008, la Russie a terminé  au classement général des médailles.

Médaillés

Médailles d'or

Médailles d'argent

Médailles de bronze

Athlétisme

Hommes
 Alexey Akhtyamov
 Vladimir Andryushchenko
 Artem Arefyev
 Albert Asadullin
 Alexey Ashapatov
 Vladislav Barinov
 Anton Bubnov
 Alexander El'min
 Alexander Filatov
 Evgeny Gudkov
 Denis Gulin
 Roman Kapranov
 Evgeny Kegelev
 Pavel Kharagezov
 Igor Khavlin
 Viacheslav Khrustalev
 Gocha Khugaev
 Andrey Koptev
 Dmitrii Kornilov
 Alexey Kotlov
 Alexey Kuznetzov
 Alexey Labzin
 Artem Loginov
 Yury Nosulenko
 Ivan Otleykin
 Ivan Prokopyev
 Egor Sharov
 Sergei Shatalov
 Evgenii Shvetcov
 Vladimir Sviridov
 Fedor Trikolich
 Leonid Ustyuzhanin
 Andrey Zhirnov
 Alexander Zverev

Femmes
 Elena Burdykina
 Veronika Doronina
 Margarita Gontcharova
 Nataliya Gudkova
 Elena Ivanova
 Alexandra Moguchaya
 Anastasiya Ovsyannikova
 Elena Pautova
 Marta Prokofyeva
 Nikol Rodomakina
 Aygyul Sakhibzadaeva
 Svetlana Sergeeva
 Anna Sorokina
 Evgeniya Trushnikova
 Larisa Volik
 Krestina Zhukova

Aviron

Hommes
 Aleksey Chuvashev
 Mikhail Jakovlev
 Fedor Levin
 Viacheslav Makhov

Femmes
 Nadezda Andreeva
 Ksenia Guseva
 Elena Naumova
 Alexey Kotlov

Cyclisme

Hommes
 Alexsey Obydennov

Femmes
 Svetlana Moshkovich

Escrime

Hommes
 Ivan Andreev
 Timur Fayzullin
 Sergey Frolov
 Timur Khamatshin
 Alexandr Kurzin
 Alexander Kuzyukov
 Artur Yusupov
 Marat Yusupov

Femmes
 Yulia Efimova
 Irinia Mishurova
 Evgeniya Sycheva
 Liudmila Vasileva

Football à 7

Hommes
 Aleksei Chesmin
 Aleksandr Kuligin
 Andrei Kuvaev
 Viacheslav Larionov
 Aleksandr Lekov
 Lasha Murvanadze
 Zaurbek Pagaev
 Ivan Potekhin
 Eduard Ramonov
 Vladislav Raretckii
 Aslanbek Sapiev
 Alexey Tumakov

Haltérophilie

Hommes
 Karen Abramyants
 Vladimir Balynetc
 Ildar Bedderdinov
 Vladimir Krivulya
 Nikolay Marfin
 Vadim Rakitin
 Sergei Sychev
 Ayrat Zakiev

Femmes
 Kheda Berieva
 Irina Kazantseva
 Olesya Lafina
 Vera Mouratova
 Tamara Podpalnaya
 Tatiana Smirnova

Judo

Hommes
 Vladimir Fedin'
 Gaydar Gaydarov
 Oleg Kretsul
 Shakhban Kurbanov
 Victor Rudenko
 Anatoly Shevchenko

Femmes
 Irina Kalyanova
 Viktoria Potapova
 Tatiana Savostyanova
 Alesia Stepaniuk

Natation

Hommes
 Alexander Chekurov
 Roman Dubovoy
 Alexey Fomenkov
 Andrey Gladkov
 Aleksandr Golintovskii
 Dmitry Grigorev
 Dmitrii Kokarev
 Konstantin Lisenkov
 Aleksei Lyzhikhin
 Roman Makarov
 Andrey Meshcheryakov
 Aleksandr Nevolin-Svetov
 Rustam Nurmukhametov
 Artem Pavlenko
 Pavel Poltavtsev
 Sergey Punko
 Eduard Samarin
 Stepan Smagin
 Denis Tarasov
 Evgeny Zimin
 Mikhail Zimin

Femmes
 Anastasia Diodorova
 Anna Efimenko
 Natalia Gavrilyuk
 Irina Grazhdanova
 Oxana Guseva
 Irina Kolmogorova
 Anna Kolosova
 Irina Lavrova
 Nina Ryabova
 Oxana Savchenko
 Ksenia Sogomonyan
 Olga Sokolova
 Darya Stukalova
 Olesya Vladykina

Tennis de table

Hommes
 Alexander Esaulov
 Pavel Lukyanov
 Iurii Nozdrunov
 Sergey Poddubnyy

Femmes
 Raïssa Tchebanika
 Olga Gorshkaleva
 Anzhelika Kosacheva
 Yulia Ovsyannikova
 Nadezhda Pushpasheva

Tir

Hommes
 Andrey Lebedinskiy
 Sergey Malyshev
 Sergey Nochevnoy
 Valery Ponomarenko

Femmes
 Natalia Dalekova
 Marina Klimenchenko
 Tatiana Ryabchenko

Tir à l'arc

Hommes
 Mikhail Oyun
 Alexey Shcherbakov
 Oleg Shestakov
 Timur Tuchinov

Femmes
 Stepanida Artakhinova
 Irina Batorova
 Marina Lyzhnikova
 Olga Polegaeva

Volley-ball

Hommes
 Tanatkan Bukin
 Dmitry Gordienko
 Svyatoslav Kartashev
 Anatolii Krupin
 Andrei Lavrinovich
 Viktor Milenin
 Sergei Pozdeev
 Alexander Savichev
 Aleksei Volkov
 Evgeny Volosnikov
 Sergey Yakunin (sélectionneur)

Délégation aux Jeux paralympiques d'été de 2012
Russie aux Jeux paralympiques
Sport en Russie en 2012


So enjoy adding garlic to your dishes? You may want to give the Chef'n GarlicZoom Chopper a look. It is a handy tool that minces garlic cloves in seconds. Simply put peeled cloves inside and roll the device. Its rotating stainless steel blades chop your garlic without you having to break a sweat.
This tool is made of plastic and stainless steel. Not too expensive either.


In the 18th and 19th centuries, when the idolatrous cult of Shakespeare was born, grew up, and thrived, it was common to hear over-the-top praise of the Bard. Shakespeare was called divine, immortal, the greatest genius ever, and the like. Stratford-on-Avon became a destination for pilgrims, and the Shakespeare tomb and birthplace there became shrines. Recognizing the absurdity of such "bardolatry," scholars have since adopted a more restrained tone. Nonetheless, worshipful enthusiasm for Shakespeare has never appreciably diminished, and even in the top rank of Shakespeare professors today, it persists.
Given his religious focus and reverential inclination, Greenblatt's essays can seem like sermons. Mediating between the secular deity and the lecture audience, which, analogously, is like a congregation, Greenblatt sounds at times like a quasi-religious cult leader. His lack of concern with giving readers the means to judge his reasoning reinforces the illusion. Informed by reading and discussing, he imparts his impressions on the author and the work he venerates. As he makes transitions with dexterity and flair, listeners or readers are lulled into a state of quasi-religious torpor, projecting Greenblatt as the Bard's evangelist.
Just as sermons use Bible stories, three of the five essays in Shakespeare's Freedom utilize long interpretive retellings of Shakespeare scenarios, eliciting or hinting at lessons to be gleaned from them. The essay on hatred draws heavily on The Merchant of Venice; the discourse on authority dissects some of the Gloucester plot in King Lear. Of the 17 pages in the introductory essay, nine are devoted to recounting the scenes in Measure for Measure that wrangle with the question of whose decapitated head will be presented to the Duke's deputy. Then Greenblatt tries to show how a minor character in the play illustrates the four preoccupations he has developed in the essays that follow—on beauty, hatred, authority, and autonomy.
The next essay, "The Limits of Hatred," opens with Greenblatt's own parable about another "unsightly stain," that of "an alien population," living among us, "who hate us." The parable goes on for about four pages, but it doesn't take more than a few sentences to get the idea that he is projecting bigoted Christian attitudes toward Jews, or alternatively Muslims, as a prelude to a lesson on The Merchant of Venice.
"It can hardly be an accident," Greenblatt writes, "that the two principal historical enemies of Christianity, Judaism and Islam, succeed each other so easily in the imaginative structure created by Shakespeare's comedy of friendship and enmity." If they do, it is only because of the imaginative effect of Greenblatt's parable.
The answer blew the questioner's mind. "Ethically inadequate object" is Greenblatt's mantra for the rest of this essay, as he turns it over in exploring Shakespeare's views on government, morality, and ethics. Sometimes he inflects the mantra, accentuating the positive, as when he asks whether Shakespeare was able "to discover an 'ethically adequate object' for human ambition." Here amid ruminations about the sacredness of kingship, ostentatious shows of faith, and the persecution of Jesuits in Early Modern England, Greenblatt meditates on the "political defects" of the age of Shakespeare.
In Shakespeare's Freedom, Greenblatt is careful to avoid authorship issues and the sticky problems that he and a considerable majority of Shakespeare professors refuse to face as they ridicule the subject and preclude it from academic study. But there are clues in the book that Greenblatt may have some sense of the problem.
It is a vexing question for Stratfordians how Shakespeare escaped the fate of his fellow playwrights, given the political views Greenblatt notes. And one historical point he does not mention: Shakespeare's Richard II, according to Queen Elizabeth's own testimony, was "played 40 times in open streets and houses" as propaganda for the Essex rebellion.
No other playwrights of the time are known to have pitied themselves for their names' receiving a brand on account of their being successful. Quite the opposite in the case of Ben Jonson, who was so proud of his success that he himself prepared the first folio of his plays for publication.
Clearly aristocrats worried about their names receiving a brand. But why would an actor? Unless Shakespeare was—? No, Greenblatt won't consider that possibility.
The type of scholarship that seems the most commendable is thorough in exploring a subject, leaving no stone unturned to discover all and to get as near the truth as possible. The scholar presents information as clearly and completely as she can and, when conclusions are drawn, goes over any possible arguments that can be raised against them.
Practitioners of another type of scholarship skim the surface of selected data, and with a degree of mastery of the art of writing, which they may regard as a performance, mask their assertions, which may be superficial, distorted, insinuating, or even reckless. Such craftsmanship can easily be employed to create propaganda.
As one example of the effort that went into his work, he discusses the way he grazes in libraries, particularly one in Florence. For the essay on beauty, "ten minutes in the Widener Library took me to a translation of [Leon Battista] Alberti's tract on architecture and fifteen minutes more turned up the quotation that I needed" (italics mine). It sounds as if Greenblatt is not reading for discovery but rooting out what he wants to support his preconceived conclusions.
He speaks of the value of anecdotes as a way to begin an essay, saying the Clinton story "enables me to stay entirely within the text of King Lear, patiently explicating its horrific representation of torture, and at the same time, without any explicit reference, to evoke that text's uncanny relevance to the current national and world crisis." The Clinton story is an adequately enabling object, and there is nothing uncanny about how Greenblatt exploits it.
He explicates his parable for the hatred essay, extolling its "several long, unnerving pages" and adding: "Only after I have fully mimed a voice of fear and hatred, do I turn in the direction that some of you may have anticipated. For, as you may have noticed, I have already begun to conjure up the situation of Shakespeare's Merchant of Venice." Greenblatt is performing to predispose readers to accept his tenuous political take on the play.
The regurgitation of historical dictionary cribbing should take care of a good 200 words for any student's paper, as it does for Greenblatt's autonomy essay. But the idea that one can see the birth of words and concepts in the O.E.D. is fanciful, and using the dictionary in such a way is pedantic.
It's bad enough that Greenblatt's brand of scholarship has become so pervasive. What's worse is that for more than a generation, Shakespeare students have been taught to emulate it.
I arrived in the Bay Area to take a full time teaching job at UC Berkeley in 2003, having spent the previous fifteen years in LA. For a long time, I was homesick for the unapologetic ambition of that sprawling, gaudy version of a real city, and for the artists who had taught me to love it.


I have struggled with acne with over two thirds of my life. That's a long time to deal with a face that has never really fit today's standard of beauty, and it has most definitely been (and continues to be) quite the journey of problem-solving vs. self-acceptance. I write this now, with a sheet mask on my face after detoxifying my pores with a mixture of a charcoal and sulfur mask, so I am not going to pretend that my quest for perfect skin has long since come to an end. Quite the contrary, summer has always wreaked havoc on my skin, with the sun, humidity, heat, and generous applications and reapplications of sunscreen. The biggest thing that has changed for me is that I think I ran out of f***s to give, somewhere along the way, so I don't let it bother me the way that it used to. It's still annoying, and yes, I wish these tiny, red face gremlins would leave me the hell alone, but I have come to value myself in deeper, more meaningful ways than I did ten years ago.
That said, I wasn't always so chill about my skin; far from it, acne has provided me with a lifetime supply of obstacles, emotional turmoil, and fragile self-esteem. It pushed me as far as to have an emotional breakdown in front of my mother, where I actually contemplated that being dead might be easier than living with acne. I was 23-years-old.
1. No undoctored photo of me was ever uploaded online of my own accord. Okay, so I am sure that a lot of people can relate to this, especially in this day and age when Instagram-ready photos are the in thing. But even before Instagram, back when Facebook was the new big thing, for the longest time, you simply would not find a photo of me that had not been doctored in some way; either put through a crappy filter to disguise the texture of my face, or airbrushed, or colour-corrected somehow. That said, if I didn't feel 'Instagram-quality', which I often didn't, then pictures were simply NOT an option for me. And, if by some sorcery, untouched photos of me did end up on the big bag internet, I was SO fast to untag myself and dissociate myself with the photo that I'd be surprised if my name was ever successfully attached to it. And then there was all the awkwardness of asking friends to either take down the photo, or blur out my face, when I was really the only one who had a 'problem' with the way I looked. This also largely spurred my tendency for #4 in this list.
2. I never had a healthy night's sleep before work. No matter what was going on, when my acne was at its worst, I could NOT leave the house for any reason without a full face of make-up. Work was the worst; I often had a 25 minute commute, and between washing my face and applying make-up, my morning entailed easily 1.5 hours spent in front of the mirror, just to feel normal. This meant not only covering up my acne to the best of my ability, but going way out with eye-make-up and enhancing my lips, so as to hopefully give people something other than my acne to focus on. So, if I worked at 8:30am, then I absolutely could NOT sleep in past 6:30. I know, this may not sound unreasonable, but being a night owl, I am seldom able to fall asleep before midnight. Meaning that most nights, if I was very, very lucky, I would get a maximum of 6.5 hours of sleep. And if I wanted to grab a bite to eat and make-coffee, well, my mornings looked more like 6-6:10am. I wish I could say that I am one of those people who can function beautifully on 6 hours of sleep, but alas, I was a zombie, more often than not. Leaving the house without full-on make-up was just NOT an option.
4. I was reclusive most of the time. If the above alone seems like an unreasonable way to live your life, that's because it is–and I certainly couldn't keep it up every single day. As soon as that make-up came off at the end of the day, I was housebound by my iron will not to be seen. And, if for whatever reason I just couldn't muster the energy or willpower to spent 1.5 hours on my face, then I just plain wouldn't leave the house. This meant I would not only frequently turn down invitations to socialize, but I would try to bribe others to run weekend errands for me, and utterly refused to answer the door. I was fine sitting around the house in my own skin, so long as outsiders didn't see my face. And, yes, this did put a major strain on a lot of my friendships. I was completely unable to even show my face around my closest friends who have known me forever, and if I'd committed to an hour-long visit, you can bet that I'd spend that 1.5 hours on my face–and still pack my touch-up supplies, just in case.
5. I would try to schedule and reschedule appointments around my acne. At one point, I had almost developed a legit fear of going to the hair salon. Because salons are places that aim to make you look beautiful, where everyone is beautiful, and are notorious hotspots for gossip if you do not fit this mold. That said, if you walk in with a face full of severe acne, then you can bet you're going to get the side-eye on more than on occasion. What's worse, is hairdressers and estheticians are all close-up in your business, so even 1.5 hours of intricate make-up applications will not fully conceal those mountains and craters on your face. When my own hairdresser (who I had known most of my life, since she's my best friend's older sister) began to bring up my acne now and again, I plummeted into the deepest state of depressive self-consciousness I can imagine. She wasn't even trying to be rude or to make me feel bad; I was like another little sister to her, and it was nothing more than an attempt at a heart-to-heart. But I was trying to hide my acne, and I did not want to acknowledge it, even with those closest to me. So this made for quite a handful of canceled appointments, and when I'd rebook, I'd always be taking a stab at what the best face-day would be for me down the road (i.e. not around my time of the month, when I anticipate heavy exercise, etc.). It was downright impossible; at one point, I must have gone a good 6 months without a trim, and I have a haircut that requires a touch-up at LEAST every 2 months. But, having disheveled hair was preferable to talking about my acne.
6. It caused me to purposely avoid alternative treatment, out of embarrassment. At one point, my hairdresser (among many other well-intentioned people) suggested that I should start getting facials to treat my acne. Now, at 29, I have done enough research to know that there can definitely be benefits to treatments such as extractions and chemical peels to treat acne, but at 23, I felt entirely hopeless. And beyond that, even if I'd harboured an inkling of hope that facials could benefit me in any way, I just couldn't bring myself to get them done. It would mean I'd be walking into yet another place, another situation, where my pizza face would be on full display. It would mean that people would have to TOUCH that pizza face. It would mean that they probably found it disgusting (even if it was their job), and would bring stories home about how they had this client with the grossest and most terrible skin. Of course, I was catastrophizing, as people with anxiety tend to do, but what I envisioned was a living nightmare. I didn't want people touching my face, even if it helped; hell, I didn't want to touch my own face. It was hard enough to let my doctor and dermatologist touch my face, and the very thought of it just made me want to hide even more.
7. I wouldn't date, and was afraid to get too close to people. If you've ever heard tell of those people who go and take a shower, and then reapply foundation directly after to give the illusion that 'they were born with it'–well, I wasn't one of those people. But only because letting my guard down around someone in any way, shape, or form, even if it meant them seeing my skin look just a little less than totally unblemished, was just not happening. For this reason, sleepovers or anything that entailed me taking off make-up was INSANELY stressful. Spending the night at other peoples' places often meant that I would stay up until everyone else was asleep, and only then, in the dark, would I take off my make-up. Furthermore, I'd try to make sure I woke up before everyone else, so that I could at least get my foundation and concealer on, and in the event that I wasn't the first one awake, I'd actually go to sleep with concealer and a thin layer of foundation over the worst areas of my face, just in case (and yes, even then, I knew that wasn't doing my skin any favours). And, not that I did a lot of dating back in the day, anyway, but whenever I gave it a try, I found myself purposely pushing significant others away by some means or another, because deep down, I was convinced that they would eventually realize how hideous I was, and leave me. So to save myself the heartbreak, I would behave in such ways that would cause us to just drift apart. It was easier, that way.
8. I felt as though I was leading a double life that no one could know about. If it seems as though these obstacles are becoming progressively worse and more intense, it's because all of these compulsions and all of this avoidance boiled down to the same thing: I was living two lives. There life that I put on display, that I wanted everyone to see, was the life that my acne 100% controlled: a full face of make-up, rare and controlled appearances in public, completely nonplussed by the disaster beneath the layers of foundation. And then, there was the life that I considered my down-time, holed up in my house as I gave my poor skin a break from all of the cosmetics I piled on it. That was the life that I refused to show the world; those days when I could barely look at myself in the mirror were my behind-the-scenes. And like Hollywood, where the finished product is amazing and even inspirational, behind the scenes for me was a very dark place. People who knew me only knew the (literal and figurative) facade that took me 1.5 hours to apply every morning, and countless other precious minutes to touch-up. They didn't know the girl who was so desperate to hide her face from the world, she had practically dissociated from herself. At this point, it had become more than just a problem for me. It was a pathology.


Douga is a rotwiller..Most people thing that are very mean and dangerous dogs.Thats not true!!They are the most harmless dogs on earth!!They are good watch dogs yes!They love their familly,and everybody who is friendly with them..Douga likes people,she loves to travell and go for rides in the car.She loves the beach,the music,the partys,the b.b.qs are her favor..Loves souvlaki and gyros.She olso understands English,Greek and Italian.What a dog!!She has a litle sister her name is Lilly..They get alown well.


text:
def find_missing_drones(delivery_id_confirmations: []):
    unique_delivery_ids = set()
    for id in delivery_id_confirmations:
        if id in unique_delivery_ids:
            unique_delivery_ids.remove(id)
        else:
            unique_delivery_ids.add(id)

    return unique_delivery_ids

# O(n) time and O(1) space but it assumes you'd only have one missing drone, whereas my solution is more generic
# and can find one or more missing drones
def find_missing_drone(delivery_id_confirmations: []):
    unique_delivery_id = 0
    for id in delivery_id_confirmations:
        unique_delivery_id ^= id

    return unique_delivery_id


text:
http://fna.ir/7JAR3P
Yemenis' Ballistic Missile Fire Kills Tens of Saudi-Led Troops, 2 Apache Helicopters in Ma'rib Province
TEHRAN (FNA)- The Saudi-led Coalition Forces and pro-Hadi militias suffered another devastating blow when a Tochka ballistic missile hit their camp in the province of Ma'rib, and killed over 180 troops, including Saudi and UAE officers.
An ammunition depot and two Apache helicopters of the pro-Saudi aggressors were also destroyed in the Yemeni ballistic missile strikes in Southern Yemen.
At least 180 Saudi and UAE military men as well as forces loyal to the former fugitive president Mansour Hadi were killed in the attack on Saudi-led forces' military camp in the Ma'rib province.
Also on Friday, the Yemeni army and popular forces conducted several retaliatory missile attacks against Saudi Arabia's Key military bases and positions in Jizan province, inflicting heavy losses on the kingdom's forces.
Yemen's Tochka ballistic missiles hit the Saudi army's gathering centers in Jizan province yesterday.
The Yemeni forces also fired a Qaher-I missile at Saudi forces' bases in Najran on Friday.
The missile attacks came in response to the violation of truce by the Saudi bomb strikes.
On Tuesday, the Yemeni missiles destroyed the command center of Saudi border guards in Asir province.
Meantime, the Yemeni missiles hit the Saudi governmental buildings in al-Rabou'a region of Asir province.
The Yemeni army also fired 52 rockets at the border regions of Alab, al-Sheibani, al-Hazar and al-Thurein in Asir province.
On Monday, Yemeni forces hit Jizan airport in Southern Saudi Arabia with their new surface-to-surface ballistic missiles.
"The Qaher-I missile precisely hit the target, the Jizan airport; the third such missile used in the past 24 hours to target military positions in Southern Saudi Arabia," Yemeni military sources told FNA.
The first Qaher-I ballistic missiles targeted Khalid bin Abdulaziz air base in Asir province in Southwestern Saudi Arabia on Sunday.
The second ballistic missile hit the Saudi-led coalition's command headquarters in Sha'ab al-Jen region near Bab al-Mandeb in Ta'iz province. Over 150 coalition servicemen, including 23 Saudi troops, 9 UAE officers and soldiers, seven Moroccan officers and 42 Blackwater troops were killed in the second attack.
Qaher-I is an updated version of a Russian-made surface-to-surface missile.
The burnt bodies of 146 Saudi-led military troops have been transferred to the city of Aden and Saudi Arabia has sent a warship to Ta'iz to transfer the wounded from Bab al-Mandeb region.
The Saudi-led forces sustained heavy casualties in the Yemeni army's missile attack on the Bab al-Mandeb region in Southwestern Yemen.
Last Friday, the Yemeni army and popular forces conducted several retaliatory attacks against key military bases and positions in two Saudi provinces, inflicting heavy losses on the kingdom's forces.
Yemeni forces fired 13 missiles at al-Jamarak region in the Saudi province of Jizan, killing at least two Saudi military men.
On December 9, the Yemeni forces launched missile attacks on the Saudi military bases in Jizan province with their new home-made missiles named 'Cry'.
The Yemeni missiles destroyed al-Ain al-Harreh and al-Salah military bases in Jizan province, inflicting heavy losses on the Saudi army.
The Yemeni army and popular forces also hit al-Ramzeh military center in Jizan province, killing tens of Saudi military men and their vehicles.
The Yemeni forces also hit several Saudi military centers in the Southern parts of Al-Khuba region.
On December 5, the Yemeni army and popular forces destroyed a large number of military posts and centers in three provinces in Southern Saudi Arabia.
The Yemeni forces' missile and artillery fire has destroyed tens of Saudi military sites in Najran, Jizan and Asir provinces in the last three days.
A large number of Saudi troops have been killed and many more wounded in the Yemeni forces' retaliatory attacks on their positions.
Also on December 5, FNA dispatches said that the Yemeni army and popular forces continued their nonstop advances on the Saudi soil and seized several military bases and sites in Saudi Arabia's Southern provinces after heavy clashes with the kingdom's troops.
The Yemeni forces captured a number of Saudi military bases in Jizan province, Yemeni Army Commander Ebrahim Moussa al-Hamdani told FNA.
Al-Hamdani noted that the army and popular forces also seized the Riyadh government's strategic military positions in Najran province after several hours of clashes with the Saudi forces, seizing heavy machinery and a large cache of weapons and military tools, including mortar-launchers.
Yemeni Forces Gain Full Control over Strategic Heights in Ma'rib
EXCLUSIVE: 207 More Saudi-Led Troops Killed in Yemen Ballistic Missile Attack
Senior Commander of Saudi-Led Coalition Killed in Yemen
Saudi Air Raids Hit Yemeni Provinces
Saudi Warplanes Violate Truce, Bomb Yemen Again
Saudi-Backed Militants Sustain More Casualties in Yemen
Yemen Unveils New Generation of Home-Made Missiles
Yemen's New Qaher-I Missile Hits Saudi Air Bases in Asir Province
Yemen's Ansarullah Says Ceasefire To Start
Saudi-Led Coalition's F-16 Fighter Jet Crashes in Yemen


NeuroIgnite – the most effective focus, memory and brain nootropics on the market.
Ancient herb used for centuries as a mood-supporter. Enhances overall healthy mood while promoting low stress and anxiety.
Essential in supporting neuron transmission. Helps regenerate brain tissue, reduce stress and anxiety, and enhance mental focus. Also known to increase liver health and stabilize blood pressure.
Important membrane with vital role in cell communication. Thought to be beneficial in cognitive and memory skills.
Helps the conversion from choline to acetylcholine. This release allows for communication between neurons and supports cerebral blood flow.
Supports mental alertness, concentration and circulation to the brain. Also shown to aid vision and damage to retina.
Supports learning enhancement, anti-aging, and increased memory while also promoting alertness and energy.THE PREMIUM BRAIN SUPPLEMENT – Our fast-acting brain booster formula was carefully formulated to provide the perfect blend of ingredients to increase your mental performance, promote positive mood, increase natural energy and ignite your mind's full potential.
INGREDIENTS YOU CAN TRUST! CLINICALLY PROVEN INGREDIENTS INCLUDING SUPER GINKGO BILOBA TO ENHANCE MENTAL PERFORMANCE – Boost your focus, clarity and concentration with physician formulated ingredients including 300mg of Bacopa, 130mg of St. John's Wort, 50mg of Ginkgo Biloba, Phosphatidylserine and more. This natural nootropic is formulated to increase circulation in the brain and improve cognition.
SMOOTH, ALL NATURAL, CAFFEINE-FREE BRAIN PILLS – Stay alert and focused using safe and natural ingredients with this top-of-class focus supplement without the crash and jitters from caffeine. The ingredients in NeuroIGNITE support healthy activity, combat stress and enhance your mood so you can focus on what's important. Brain function support at its best!
ONE PILL A DAY IS ALL YOU NEED – Formulated at an FDA registered facility under strict Good Manufacturing Practice standards, NeuroIgnite provides a simple, once-daily dose that you can take with confidence. NeuroIGNITE is proudly made in the USA and third party tested to ensure you are getting exactly what the bottle says.
100% MONEY-BACK GUARANTEE- Nothing to lose! We are so confident that you will love our top-of-class focus supplement, Neuro IGNITE, that we back it with a 60-day money-back guarantee, hassle-free.