Fix some issues with the path handling in the command task

#!/bin/sh

set -e

# Set VERBOSE to enable verbose logging of the boot script
#VERBOSE=true
if [ ! -z $DEBUG_BOOT ]; then
    set -x
fi;

my_readlink_f() {
    TARGET_FILE="$1"
    cd $(dirname "$TARGET_FILE")
    TARGET_FILE=$(basename "$TARGET_FILE")

    # Iterate down a (possible) chain of symlinks
    while [ -L "$TARGET_FILE" ]
    do
        TARGET_FILE=$(readlink "$TARGET_FILE")
        cd $(dirname "$TARGET_FILE")
        TARGET_FILE=$(basename "$TARGET_FILE")
    done
    # Compute the canonicalized name by finding the physical path
    # for the directory we're in and appending the target file.
    PHYS_DIR=$(pwd -P)
    RESULT="$PHYS_DIR/$TARGET_FILE"
    echo "$RESULT"
}

# Path to this script
if uname | grep -q 'Darwin'; then
  # on OSX, best to install coreutils from homebrew or similar
  # to get greadlink
  if command -v greadlink >/dev/null 2>&1; then
    SCRIPT=$(greadlink -f "$0")
  else
    SCRIPT=$(my_readlink_f "$0" )
  fi
else
  SCRIPT=$(readlink -f "$0" )
fi

# Parent directory of this script
SCRIPT_DIR=$(dirname "${SCRIPT}")
# Root directory of all releases
RELEASE_ROOT_DIR=$(dirname $(dirname ${SCRIPT_DIR}))

# Disable flow control for run_erl
# Flow control can cause several problems. On Linux, if you
# accidentally hit Ctrl-S (instead of Ctrl-D to detach) and
# then some other key, the entire beam process will hang when
# attempting to write to stdout. On Solaris, the beam process
# will hang on writing if ScrollLock is on.
RUN_ERL_DISABLE_FLOWCNTRL="${RUN_ERL_DISABLE_FLOWCNTRL:-true}"
# Name of the release
REL_NAME="<%= release_name %>"
# Current version of the release
REL_VSN="<%= release_version %>"
# Current version of ERTS being used
# If this is not present/unset, it will be detected
<%= unless is_nil(erts_vsn) do %>ERTS_VSN="<%= erts_vsn %>"<% end %>
# VM code loading mode, embedded by default, can also be interactive
# See http://erlang.org/doc/man/code.html
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
# Path to start_erl.data
START_ERL_DATA="$RELEASE_ROOT_DIR/releases/start_erl.data"
# Directory containing the current version of this release
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
# The lib directory for this release
REL_LIB_DIR="$RELEASE_ROOT_DIR/lib"
# Options passed to erl
ERL_OPTS="<%= release.profile.erl_opts %>"
# When stdout is piped to a file, this is the directory those files will
# be stored in. defaults to /log in the release root directory

# RELEASE_MUTABLE_DIR
RELEASE_MUTABLE_DIR="${RELEASE_MUTABLE_DIR:-$RELEASE_ROOT_DIR/var}"

RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_MUTABLE_DIR/log}"
# A string of extra options to pass to erl, here for plugins
EXTRA_OPTS=""

# Pre-start/stop event hook paths
PRE_START_HOOK="$REL_DIR/hooks/pre_start"
POST_START_HOOK="$REL_DIR/hooks/post_start"
PRE_STOP_HOOK="$REL_DIR/hooks/pre_stop"
POST_STOP_HOOK="$REL_DIR/hooks/post_stop"

# Get node pid
get_pid() {
    if output="$(nodetool rpcterms os getpid)"
    then
        echo "$output" | sed -e 's/"//g'
        return 0
    else
        echo "$output"
        return 1
    fi
}

# Generate a unique nodename
gen_nodename() {
    id="longname$(gen_id)-${NAME}"
    "$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
}

# Generate a random id
gen_id() {
    od -t x -N 4 /dev/urandom | head -n1 | awk '{print $2}'
}

# Control a node
# Use like `nodetool "ping"`
nodetool() {
    command="$1"; shift

    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
                            -setcookie "$COOKIE" "$command" $@
}

# Run an escript in the node's environment
# Use like `escript "path/to/escript"`
escript() {
    shift; scriptpath="$1"; shift
    export RELEASE_ROOT_DIR

    "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
}

# Private. For determining the version of ERTS available to the release
_detect_erts_vsn() {
    "$BINDIR/erl" -boot start_clean -eval 'Ver = erlang:system_info(version), io:format("~s~n", [Ver]), halt()' -noshell
}

# Private. Gets a list of code paths for this release
_get_code_paths() {
    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/release_utils.escript" "get_code_paths" "$ROOTDIR" "$ERTS_DIR" "$REL_DIR" "$REL_NAME"
}

# Private. For setting ERTS_DIR and ROOTDIR
_find_erts_dir() {
    __erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
    if [ -d "$__erts_dir" ]; then
        ERTS_DIR="$__erts_dir";
        ROOTDIR="$RELEASE_ROOT_DIR"
    else
        __erl="$(which erl)"
        code="io:format(\"~s\", [code:root_dir()]), halt()."
        __erl_root="$("$__erl" -noshell -eval "$code")"
        ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
        ROOTDIR="$__erl_root"
    fi
}

# Private. Open a shell on a remote node
_rem_sh() {
    # Generate a unique id used to allow multiple remsh to the same node
    # transparently
    id="remsh$(gen_id)-${NAME}"

    # Get the node's ticktime so that we use the same thing.
    TICKTIME="$(nodetool rpcterms net_kernel get_net_ticktime)"

    # Setup remote shell command to control node
    if [ ! -z "$USE_ERL_SHELL" ]; then
        exec "$BINDIR/erl" \
            -hidden \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            "$NAME_TYPE" "$id" -remsh "$NAME" -setcookie "$COOKIE"
    else
        __code_paths=$(_get_code_paths)
        exec "$BINDIR/erl" \
            -pa "$CONSOLIDATED_DIR" \
            ${__code_paths} \
            -hidden -noshell \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            -user Elixir.IEx.CLI "$NAME_TYPE" "$id" -setcookie "$COOKIE" \
            -extra --no-halt +iex -"$NAME_TYPE" "$id" --cookie "$COOKIE" --remsh "$NAME"
    fi
}

# Output a start command for the last argument of run_erl
_start_command() {
    printf "exec \"%s\" \"%s\" -- %s %s" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
           "$START_OPTION" "${ARGS}" "${EXTRA_OPTS}"
}

# Do a textual replacement of ${VAR} occurances in $1 and pipe to $2
_replace_os_vars() {
    awk '
        function escape(s) {
            gsub(/'\&'/, "\\\\&", s);
            return s;
        }
        {
            while(match($0,"[$]{[^}]*}")) {
                var=substr($0,RSTART+2,RLENGTH-3);
                gsub("[$]{"var"}", escape(ENVIRON[var]))
            }
        }1' < "$1" > "$2"
}

# If ERTS_VSN is not set, detect it
if [ -z "$ERTS_VSN" ]; then
    ERTS_VSN="$(_detect_erts_vsn)"
    echo "$ERTS_VSN $REL_VSN" > "$START_ERL_DATA"
fi

# Allow override of where to read configuration from
# By default it's RELEASE_ROOT_DIR
if [ -z "$RELEASE_CONFIG_DIR" ]; then
    RELEASE_CONFIG_DIR="$RELEASE_ROOT_DIR"
fi

# Make sure directories exist
mkdir -p "$RELEASE_MUTABLE_DIR"
echo "Files in this directory are regenerated frequently, edits will be lost" \
    > "$RELEASE_MUTABLE_DIR/WARNING_README"
mkdir -p "$RUNNER_LOG_DIR"

# Set VMARGS_PATH, the path to the vm.args file to use
# Use $RELEASE_CONFIG_DIR/vm.args if exists, otherwise releases/VSN/vm.args
if [ -z "$VMARGS_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/vm.args" ]; then
        VMARGS_PATH="$RELEASE_CONFIG_DIR/vm.args"
    else
        VMARGS_PATH="$REL_DIR/vm.args"
    fi
fi
echo "#### Generated - edit/create $RELEASE_CONFIG_DIR/vm.args instead." \
    >  "$RELEASE_MUTABLE_DIR/vm.args"
cat  "$VMARGS_PATH"                              \
    >> "$RELEASE_MUTABLE_DIR/vm.args"
VMARGS_PATH=$RELEASE_MUTABLE_DIR/vm.args

if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$orig_vmargs_path" "$VMARGS_PATH"
fi

# Set SYS_CONFIG_PATH, the path to the sys.config file to use
# Use $RELEASE_CONFIG_DIR/sys.config if exists, otherwise releases/VSN/sys.config
if [ -z "$SYS_CONFIG_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
fi
echo "%% Generated - edit/create $RELEASE_CONFIG_DIR/sys.config instead." \
    >  "$RELEASE_MUTABLE_DIR/sys.config"
cat  "$SYS_CONFIG_PATH"                              \
    >> "$RELEASE_MUTABLE_DIR/sys.config"
SYS_CONFIG_PATH=$RELEASE_MUTABLE_DIR/sys.config

if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$orig_sys_config_path" "$SYS_CONFIG_PATH"
fi

# Extract the target node name from node.args
# Should be `-sname somename` or `-name somename@somehost`
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
if [ -z "$NAME_ARG" ]; then
    echo "vm.args needs to have either -name or -sname parameter."
    exit 1
fi

# Extract the name type and name from the NAME_ARG for REMSH
# NAME_TYPE should be -name or -sname
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
# NAME will be either `somename` or `somename@somehost`
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"

# Where the pipe will be stored when using `start`
# This is used so you can attach the running application to the current
# shell using `attach`
PIPE_DIR="${PIPE_DIR:-$RELEASE_MUTABLE_DIR/erl_pipes/$NAME/}"

# Extract the target cookie
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)"
DEFAULT_COOKIE_FILE="$HOME/.erlang.cookie"
if [ -z "$COOKIE_ARG" ]; then
    if [ -f "$DEFAULT_COOKIE_FILE" ]; then
        COOKIE="$(cat "$DEFAULT_COOKIE_FILE")"
    else
        printf "a secret cookie must be provided in one of the following ways:\n  - with vm.args using the -setcookie parameter,\n  or\n  by writing the cookie to '$DEFAULT_COOKIE_FILE', with permissions set to 0400"
        exit 1
    fi
else
    # Extract cookie name from COOKIE_ARG
    COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
fi

_find_erts_dir
export ROOTDIR="$RELEASE_ROOT_DIR"
export BINDIR="$ERTS_DIR/bin"
export EMU="beam"
export PROGNAME="erl"
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
ERTS_LIB_DIR="$ERTS_DIR/../lib"
CONSOLIDATED_DIR="$ROOTDIR/lib/${REL_NAME}-${REL_VSN}/consolidated"

cd "$ROOTDIR"

# User can specify an sname without @hostname
# This will fail when creating remote shell
# So here we check for @ and add @hostname if missing
case $NAME in
    *@*)
        # Nothing to do
        ;;
    *)
        NAME=$NAME@$(gen_nodename)
        ;;
esac

# Check the first argument for instructions
case "$1" in
    start|start_boot)

        # Make sure there is not already a node running
        #RES=`$NODETOOL ping`
        #if [ "$RES" = "pong" ]; then
        #    echo "Node is already running!"
        #    exit 1
        #fi
        # Save this for later.
        CMD=$1
        case "$1" in
            start)
                shift
                START_OPTION="console"
                HEART_OPTION="start"
                ;;
            start_boot)
                shift
                START_OPTION="console_boot"
                HEART_OPTION="start_boot"
                ;;
        esac
        ARGS="$@"
        RUN_PARAM="$@"

        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Set arguments for the heart command
        set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
        [ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"

        # Export the HEART_COMMAND
        HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD"
        export HEART_COMMAND

        mkdir -p "$PIPE_DIR"

        "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
                          "$(_start_command)"

        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        ;;

    stop)
        [ -f "$PRE_STOP_HOOK" ] && . "$PRE_STOP_HOOK"
        # Wait for the node to completely stop...
        PID="$(get_pid)"
        if ! nodetool "stop"; then
            exit 1
        fi
        while $(kill -s 0 "$PID" 2>/dev/null);
        do
            sleep 1
        done
        [ -f "$POST_STOP_HOOK" ] && . "$POST_STOP_HOOK"
        ;;

    restart)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM without exiting the process
        if ! nodetool "restart"; then
            exit 1
        fi
        ;;

    reboot)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM completely (uses heart to restart it)
        if ! nodetool "reboot"; then
            exit 1
        fi
        ;;

    pid)
        ## Get the VM's pid
        if ! get_pid; then
            exit 1
        fi
        ;;

    ping)
        ## See if the VM is alive
        if ! nodetool "ping"; then
            exit 1
        fi
        ;;

    escript)
        ## Run an escript under the node's environment
        if ! escript $@; then
            exit 1
        fi
        ;;

    attach)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;

    remote_console)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        _rem_sh
        ;;

    upgrade|downgrade|install)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "install" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    unpack)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "unpack" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    console|console_clean|console_boot)
        # .boot file typically just $REL_NAME (ie, the app name)
        # however, for debugging, sometimes start_clean.boot is useful.
        # For e.g. 'setup', one may even want to name another boot script.
        case "$1" in
            console)
                if [ -f "$REL_DIR/$REL_NAME.boot" ]; then
                  BOOTFILE="$REL_DIR/$REL_NAME"
                else
                  BOOTFILE="$REL_DIR/start"
                fi
                ;;
            console_clean)
                BOOTFILE="$ROOTDIR/bin/start_clean"
                ;;
            console_boot)
                shift
                BOOTFILE="$1"
                shift
                ;;
        esac
        # Setup beam-required vars
        EMU="beam"
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre_start hook along
        # the way. We can't run the post_start hook because
        # the console will crash with no TTY attached
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        __code_paths=$(_get_code_paths)
        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" \
            -boot "$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            ${__code_paths} \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -user Elixir.IEx.CLI \
            -extra --no-halt +iex

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS} ${EXTRA_OPTS}
            echo "Root: $ROOTDIR"

            # Log the startup
            echo "$RELEASE_ROOT_DIR"
        fi;

        logger -t "$REL_NAME[$$]" "Starting up"

        exec "$@" -- ${1+$ARGS} ${EXTRA_OPTS}
        ;;

    foreground)
        # start up the release in the foreground for use by runit
        # or other supervision services

        [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
        FOREGROUNDOPTIONS="-noshell -noinput +Bd"

        # Setup beam-required vars
        EMU=beam
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre and post start hooks
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
            -boot "$REL_DIR/$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -extra ${EXTRA_OPTS}

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS}
            echo "Root: $ROOTDIR"
        fi;

        "$@" -- ${1+$ARGS} &
        __bg_pid=$!
        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        wait $__bg_pid
        ;;
    rpc)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpc $@
        ;;
    rpcterms)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpcterms $@
        ;;
    eval)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        nodetool "eval" $@
        ;;
    command)
        # Execute as command-line utility
        #
        # Like the escript command, this does not start the OTP application.
        # If your command depends on a running OTP application,
        # use
        #
        #     {:ok, _} = Application.ensure_all_started(:your_app)

        shift
        MODULE="$1"; shift
        FUNCTION="$1"; shift

        # Save extra arguments
        ARGS="$@"

        # Build arguments for erlexec
        __code_paths=$(_get_code_paths)
        set -- "$ERL_OPTS"
        [ "$SYS_CONFIG_PATH" ] && set -- "$@" -config "$SYS_CONFIG_PATH"
        set -- "$@" -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR"
        set -- "$@" -noshell
        set -- "$@" -boot start_clean
        set -- "$@" -pa "$CONSOLIDATED_DIR"
        set -- "$@" ${__code_paths}
        set -- "$@" -s "$MODULE" "$FUNCTION"

        $BINDIR/erlexec $@ -extra $ARGS
        exit "$?"
        ;;
    *)
        __command_path="$REL_DIR/commands/$1"
        if [ -f "$__command_path" ]; then
            . "$__command_path"
        else
            echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|escript|rpc|rpcterms|eval|command <module> <function> <args>}"
            exit 1
        fi
        ;;
esac

exit 0

#!/bin/sh

set -e

# Set VERBOSE to enable verbose logging of the boot script
#VERBOSE=true
if [ ! -z $DEBUG_BOOT ]; then
    set -x
fi;

my_readlink_f() {
    TARGET_FILE="$1"
    cd $(dirname "$TARGET_FILE")
    TARGET_FILE=$(basename "$TARGET_FILE")

    # Iterate down a (possible) chain of symlinks
    while [ -L "$TARGET_FILE" ]
    do
        TARGET_FILE=$(readlink "$TARGET_FILE")
        cd $(dirname "$TARGET_FILE")
        TARGET_FILE=$(basename "$TARGET_FILE")
    done
    # Compute the canonicalized name by finding the physical path
    # for the directory we're in and appending the target file.
    PHYS_DIR=$(pwd -P)
    RESULT="$PHYS_DIR/$TARGET_FILE"
    echo "$RESULT"
}

# Path to this script
if uname | grep -q 'Darwin'; then
  # on OSX, best to install coreutils from homebrew or similar
  # to get greadlink
  if command -v greadlink >/dev/null 2>&1; then
    SCRIPT=$(greadlink -f "$0")
  else
    SCRIPT=$(my_readlink_f "$0" )
  fi
else
  SCRIPT=$(readlink -f "$0" )
fi

# Parent directory of this script
SCRIPT_DIR=$(dirname "${SCRIPT}")
# Root directory of all releases
RELEASE_ROOT_DIR=$(dirname $(dirname ${SCRIPT_DIR}))

# Disable flow control for run_erl
# Flow control can cause several problems. On Linux, if you
# accidentally hit Ctrl-S (instead of Ctrl-D to detach) and
# then some other key, the entire beam process will hang when
# attempting to write to stdout. On Solaris, the beam process
# will hang on writing if ScrollLock is on.
RUN_ERL_DISABLE_FLOWCNTRL="${RUN_ERL_DISABLE_FLOWCNTRL:-true}"
# Name of the release
REL_NAME="<%= release_name %>"
# Current version of the release
REL_VSN="<%= release_version %>"
# Current version of ERTS being used
# If this is not present/unset, it will be detected
<%= unless is_nil(erts_vsn) do %>ERTS_VSN="<%= erts_vsn %>"<% end %>
# VM code loading mode, embedded by default, can also be interactive
# See http://erlang.org/doc/man/code.html
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}"
# Path to start_erl.data
START_ERL_DATA="$RELEASE_ROOT_DIR/releases/start_erl.data"
# Directory containing the current version of this release
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
# The lib directory for this release
REL_LIB_DIR="$RELEASE_ROOT_DIR/lib"
# Options passed to erl
ERL_OPTS="<%= release.profile.erl_opts %>"
# When stdout is piped to a file, this is the directory those files will
# be stored in. defaults to /log in the release root directory

# RELEASE_MUTABLE_DIR
RELEASE_MUTABLE_DIR="${RELEASE_MUTABLE_DIR:-$RELEASE_ROOT_DIR/var}"

RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_MUTABLE_DIR/log}"
# A string of extra options to pass to erl, here for plugins
EXTRA_OPTS=""

# Pre-start/stop event hook paths
PRE_START_HOOK="$REL_DIR/hooks/pre_start"
POST_START_HOOK="$REL_DIR/hooks/post_start"
PRE_STOP_HOOK="$REL_DIR/hooks/pre_stop"
POST_STOP_HOOK="$REL_DIR/hooks/post_stop"

# Get node pid
get_pid() {
    if output="$(nodetool rpcterms os getpid)"
    then
        echo "$output" | sed -e 's/"//g'
        return 0
    else
        echo "$output"
        return 1
    fi
}

# Generate a unique nodename
gen_nodename() {
    id="longname$(gen_id)-${NAME}"
    "$BINDIR/erl" -boot start_clean -eval '[Host] = tl(string:tokens(atom_to_list(node()),"@")), io:format("~s~n", [Host]), halt()' -noshell ${NAME_TYPE} $id
}

# Generate a random id
gen_id() {
    od -t x -N 4 /dev/urandom | head -n1 | awk '{print $2}'
}

# Control a node
# Use like `nodetool "ping"`
nodetool() {
    command="$1"; shift

    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
                            -setcookie "$COOKIE" "$command" $@
}

# Run an escript in the node's environment
# Use like `escript "path/to/escript"`
escript() {
    shift; scriptpath="$1"; shift
    export RELEASE_ROOT_DIR

    "$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@
}

# Private. For determining the version of ERTS available to the release
_detect_erts_vsn() {
    "$BINDIR/erl" -boot start_clean -eval 'Ver = erlang:system_info(version), io:format("~s~n", [Ver]), halt()' -noshell
}

# Private. Gets a list of code paths for this release
_get_code_paths() {
    "$ERTS_DIR/bin/escript" "$ROOTDIR/bin/release_utils.escript" "get_code_paths" "$ROOTDIR" "$ERTS_DIR" "$REL_DIR" "$REL_NAME"
}

# Private. For setting ERTS_DIR and ROOTDIR
_find_erts_dir() {
    __erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
    if [ -d "$__erts_dir" ]; then
        ERTS_DIR="$__erts_dir";
        ROOTDIR="$RELEASE_ROOT_DIR"
    else
        __erl="$(which erl)"
        code="io:format(\"~s\", [code:root_dir()]), halt()."
        __erl_root="$("$__erl" -noshell -eval "$code")"
        ERTS_DIR="$__erl_root/erts-$ERTS_VSN"
        ROOTDIR="$__erl_root"
    fi
}

# Private. Open a shell on a remote node
_rem_sh() {
    # Generate a unique id used to allow multiple remsh to the same node
    # transparently
    id="remsh$(gen_id)-${NAME}"

    # Get the node's ticktime so that we use the same thing.
    TICKTIME="$(nodetool rpcterms net_kernel get_net_ticktime)"

    # Setup remote shell command to control node
    if [ ! -z "$USE_ERL_SHELL" ]; then
        exec "$BINDIR/erl" \
            -hidden \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            "$NAME_TYPE" "$id" -remsh "$NAME" -setcookie "$COOKIE"
    else
        __code_paths=$(_get_code_paths)
        exec "$BINDIR/erl" \
            -pa "$CONSOLIDATED_DIR" \
            ${__code_paths} \
            -hidden -noshell \
            -boot start_clean -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -kernel net_ticktime $TICKTIME \
            -user Elixir.IEx.CLI "$NAME_TYPE" "$id" -setcookie "$COOKIE" \
            -extra --no-halt +iex -"$NAME_TYPE" "$id" --cookie "$COOKIE" --remsh "$NAME"
    fi
}

# Output a start command for the last argument of run_erl
_start_command() {
    printf "exec \"%s\" \"%s\" -- %s %s" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
           "$START_OPTION" "${ARGS}" "${EXTRA_OPTS}"
}

# Do a textual replacement of ${VAR} occurances in $1 and pipe to $2
_replace_os_vars() {
    awk '
        function escape(s) {
            gsub(/'\&'/, "\\\\&", s);
            return s;
        }
        {
            while(match($0,"[$]{[^}]*}")) {
                var=substr($0,RSTART+2,RLENGTH-3);
                gsub("[$]{"var"}", escape(ENVIRON[var]))
            }
        }1' < "$1" > "$2"
}

# If ERTS_VSN is not set, detect it
if [ -z "$ERTS_VSN" ]; then
    ERTS_VSN="$(_detect_erts_vsn)"
    echo "$ERTS_VSN $REL_VSN" > "$START_ERL_DATA"
fi

# Allow override of where to read configuration from
# By default it's RELEASE_ROOT_DIR
if [ -z "$RELEASE_CONFIG_DIR" ]; then
    RELEASE_CONFIG_DIR="$RELEASE_ROOT_DIR"
fi

# Make sure directories exist
mkdir -p "$RELEASE_MUTABLE_DIR"
echo "Files in this directory are regenerated frequently, edits will be lost" \
    > "$RELEASE_MUTABLE_DIR/WARNING_README"
mkdir -p "$RUNNER_LOG_DIR"

# Set VMARGS_PATH, the path to the vm.args file to use
# Use $RELEASE_CONFIG_DIR/vm.args if exists, otherwise releases/VSN/vm.args
if [ -z "$VMARGS_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/vm.args" ]; then
        VMARGS_PATH="$RELEASE_CONFIG_DIR/vm.args"
    else
        VMARGS_PATH="$REL_DIR/vm.args"
    fi
fi
echo "#### Generated - edit/create $RELEASE_CONFIG_DIR/vm.args instead." \
    >  "$RELEASE_MUTABLE_DIR/vm.args"
cat  "$VMARGS_PATH"                              \
    >> "$RELEASE_MUTABLE_DIR/vm.args"
VMARGS_PATH=$RELEASE_MUTABLE_DIR/vm.args

if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$orig_vmargs_path" "$VMARGS_PATH"
fi

# Set SYS_CONFIG_PATH, the path to the sys.config file to use
# Use $RELEASE_CONFIG_DIR/sys.config if exists, otherwise releases/VSN/sys.config
if [ -z "$SYS_CONFIG_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
fi
echo "%% Generated - edit/create $RELEASE_CONFIG_DIR/sys.config instead." \
    >  "$RELEASE_MUTABLE_DIR/sys.config"
cat  "$SYS_CONFIG_PATH"                              \
    >> "$RELEASE_MUTABLE_DIR/sys.config"
SYS_CONFIG_PATH=$RELEASE_MUTABLE_DIR/sys.config

if [ $REPLACE_OS_VARS ]; then
    _replace_os_vars "$orig_sys_config_path" "$SYS_CONFIG_PATH"
fi

# Extract the target node name from node.args
# Should be `-sname somename` or `-name somename@somehost`
NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true)
if [ -z "$NAME_ARG" ]; then
    echo "vm.args needs to have either -name or -sname parameter."
    exit 1
fi

# Extract the name type and name from the NAME_ARG for REMSH
# NAME_TYPE should be -name or -sname
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
# NAME will be either `somename` or `somename@somehost`
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"

# Where the pipe will be stored when using `start`
# This is used so you can attach the running application to the current
# shell using `attach`
PIPE_DIR="${PIPE_DIR:-$RELEASE_MUTABLE_DIR/erl_pipes/$NAME/}"

# Extract the target cookie
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH" || true)"
DEFAULT_COOKIE_FILE="$HOME/.erlang.cookie"
if [ -z "$COOKIE_ARG" ]; then
    if [ -f "$DEFAULT_COOKIE_FILE" ]; then
        COOKIE="$(cat "$DEFAULT_COOKIE_FILE")"
    else
        printf "a secret cookie must be provided in one of the following ways:\n  - with vm.args using the -setcookie parameter,\n  or\n  by writing the cookie to '$DEFAULT_COOKIE_FILE', with permissions set to 0400"
        exit 1
    fi
else
    # Extract cookie name from COOKIE_ARG
    COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
fi

_find_erts_dir
export ROOTDIR="$RELEASE_ROOT_DIR"
export BINDIR="$ERTS_DIR/bin"
export EMU="beam"
export PROGNAME="erl"
export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
ERTS_LIB_DIR="$ERTS_DIR/../lib"
CONSOLIDATED_DIR="$ROOTDIR/lib/${REL_NAME}-${REL_VSN}/consolidated"

cd "$ROOTDIR"

# User can specify an sname without @hostname
# This will fail when creating remote shell
# So here we check for @ and add @hostname if missing
case $NAME in
    *@*)
        # Nothing to do
        ;;
    *)
        NAME=$NAME@$(gen_nodename)
        ;;
esac

# Check the first argument for instructions
case "$1" in
    start|start_boot)

        # Make sure there is not already a node running
        #RES=`$NODETOOL ping`
        #if [ "$RES" = "pong" ]; then
        #    echo "Node is already running!"
        #    exit 1
        #fi
        # Save this for later.
        CMD=$1
        case "$1" in
            start)
                shift
                START_OPTION="console"
                HEART_OPTION="start"
                ;;
            start_boot)
                shift
                START_OPTION="console_boot"
                HEART_OPTION="start_boot"
                ;;
        esac
        ARGS="$@"
        RUN_PARAM="$@"

        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Set arguments for the heart command
        set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
        [ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"

        # Export the HEART_COMMAND
        HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD"
        export HEART_COMMAND

        mkdir -p "$PIPE_DIR"

        "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
                          "$(_start_command)"

        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        ;;

    stop)
        [ -f "$PRE_STOP_HOOK" ] && . "$PRE_STOP_HOOK"
        # Wait for the node to completely stop...
        PID="$(get_pid)"
        if ! nodetool "stop"; then
            exit 1
        fi
        while $(kill -s 0 "$PID" 2>/dev/null);
        do
            sleep 1
        done
        [ -f "$POST_STOP_HOOK" ] && . "$POST_STOP_HOOK"
        ;;

    restart)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM without exiting the process
        if ! nodetool "restart"; then
            exit 1
        fi
        ;;

    reboot)
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"
        ## Restart the VM completely (uses heart to restart it)
        if ! nodetool "reboot"; then
            exit 1
        fi
        ;;

    pid)
        ## Get the VM's pid
        if ! get_pid; then
            exit 1
        fi
        ;;

    ping)
        ## See if the VM is alive
        if ! nodetool "ping"; then
            exit 1
        fi
        ;;

    escript)
        ## Run an escript under the node's environment
        if ! escript $@; then
            exit 1
        fi
        ;;

    attach)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;

    remote_console)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        _rem_sh
        ;;

    upgrade|downgrade|install)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "install" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    unpack)
        if [ -z "$2" ]; then
            echo "Missing package argument"
            echo "Usage: $REL_NAME $1 {package base name}"
            echo "NOTE {package base name} MUST NOT include the .tar.gz suffix"
            exit 1
        fi

        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
             "unpack" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2"
        ;;

    console|console_clean|console_boot)
        # .boot file typically just $REL_NAME (ie, the app name)
        # however, for debugging, sometimes start_clean.boot is useful.
        # For e.g. 'setup', one may even want to name another boot script.
        case "$1" in
            console)
                if [ -f "$REL_DIR/$REL_NAME.boot" ]; then
                  BOOTFILE="$REL_DIR/$REL_NAME"
                else
                  BOOTFILE="$REL_DIR/start"
                fi
                ;;
            console_clean)
                BOOTFILE="$ROOTDIR/bin/start_clean"
                ;;
            console_boot)
                shift
                BOOTFILE="$1"
                shift
                ;;
        esac
        # Setup beam-required vars
        EMU="beam"
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre_start hook along
        # the way. We can't run the post_start hook because
        # the console will crash with no TTY attached
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        __code_paths=$(_get_code_paths)
        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" \
            -boot "$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            ${__code_paths} \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -user Elixir.IEx.CLI \
            -extra --no-halt +iex

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS} ${EXTRA_OPTS}
            echo "Root: $ROOTDIR"

            # Log the startup
            echo "$RELEASE_ROOT_DIR"
        fi;

        logger -t "$REL_NAME[$$]" "Starting up"

        exec "$@" -- ${1+$ARGS} ${EXTRA_OPTS}
        ;;

    foreground)
        # start up the release in the foreground for use by runit
        # or other supervision services

        [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
        FOREGROUNDOPTIONS="-noshell -noinput +Bd"

        # Setup beam-required vars
        EMU=beam
        PROGNAME="${0#*/}"

        export EMU
        export PROGNAME

        # Store passed arguments since they will be erased by `set`
        ARGS="$@"

        # Start the VM, executing pre and post start hooks
        [ -f "$PRE_START_HOOK" ] && . "$PRE_START_HOOK"

        # Build an array of arguments to pass to exec later on
        # Build it here because this command will be used for logging.
        set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \
            -boot "$REL_DIR/$BOOTFILE" \
            -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \
            -env ERL_LIBS "$REL_LIB_DIR" \
            -pa "$CONSOLIDATED_DIR" \
            -args_file "$VMARGS_PATH" \
            -config "$SYS_CONFIG_PATH" \
            -mode "$CODE_LOADING_MODE" \
            ${ERL_OPTS} \
            -extra ${EXTRA_OPTS}

        # Dump environment info for logging purposes
        if [ ! -z $VERBOSE ]; then
            echo "Exec: $@" -- ${1+$ARGS}
            echo "Root: $ROOTDIR"
        fi;

        "$@" -- ${1+$ARGS} &
        __bg_pid=$!
        [ -f "$POST_START_HOOK" ] && . "$POST_START_HOOK"
        wait $__bg_pid
        ;;
    rpc)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpc $@
        ;;
    rpcterms)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift

        nodetool rpcterms $@
        ;;
    eval)
        # Make sure a node IS running
        if ! nodetool "ping" > /dev/null; then
            echo "Node is not running!"
            exit 1
        fi

        shift
        nodetool "eval" $@
        ;;
    command)
        # Execute as command-line utility
        #
        # Like the escript command, this does not start the OTP application.
        # If your command depends on a running OTP application,
        # use
        #
        #     {:ok, _} = Application.ensure_all_started(:your_app)

        shift
        MODULE="$1"; shift
        FUNCTION="$1"; shift

        # Save extra arguments
        ARGS="$@"

        # Build arguments for erlexec
        __code_paths=$(_get_code_paths)
        set -- "$ERL_OPTS"
        [ "$SYS_CONFIG_PATH" ] && set -- "$@" -config "$SYS_CONFIG_PATH"
        set -- "$@" -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR"
        set -- "$@" -noshell
        set -- "$@" -boot start_clean
        set -- "$@" ${_code_paths}
        set -- "$@" -pa "$CONSOLIDATED_DIR"
        set -- "$@" -s "$MODULE" "$FUNCTION"

        $BINDIR/erlexec $@ -extra $ARGS
        exit "$?"
        ;;
    *)
        __command_path="$REL_DIR/commands/$1"
        if [ -f "$__command_path" ]; then
            . "$__command_path"
        else
            echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|downgrade|install|escript|rpc|rpcterms|eval|command <module> <function> <args>}"
            exit 1
        fi
        ;;
esac

exit 0


Adds ?d=404 to gravatar URL to get a 404 error and no image if not exist.

<%= full_name(@user) %>

<%= if gravatar_url(@user) do %>
<img src="<%= gravatar_url(@user) %>?d=404" />
<% end %>

  <%= if @user.first_name do %>

      <%= gettext "First name:" %>
      <%= @user.first_name %>

  <% end %>

  <%= if @user.last_name do %>

      <%= gettext "Last name:" %>
      <%= @user.last_name %>

  <% end %>

  <%= if @user.middlename do %>

      <%= gettext "Middlename:" %>
      <%= @user.middlename %>

  <% end %>

  <%= if @user.nickname do %>

      <%= gettext "Nickname:" %>
      <%= @user.nickname %>

  <% end %>

  <%= if @user.honorific_prefix do %>

      <%= gettext "Honorific prefix:" %>
      <%= @user.honorific_prefix %>

  <% end %>

  <%= if @user.honorific_suffix do %>

      <%= gettext "Honorific suffix:" %>
      <%= @user.honorific_suffix %>

  <% end %>

  <%= if @user.gender do %>

      <%= gettext "Gender:" %>
      <%= @user.gender %>

  <% end %>

  <%= if @user.birthdate do %>

      <%= gettext "Birthdate:" %>
      <%= @user.birthdate %>

  <% end %>

  <%= if @user.verified do %>

      <%= gettext "Verified:" %>
      <%= @user.verified %>

  <% end %>

<%= if @user.avatar do %>

<img src="<%= avatar_url(@user) %>" alt="Avatar of <%= full_name(@user) %>">

<% end %>

<%= unless Enum.empty?(@user.emails) do %>

E-Mails

  <%= for email <- @user.emails do %>

<%= email.value %>

  <% end %>

<% end %>

<%= unless Enum.empty?(@user.groups) do %>

Groups

  <%= for group <- @user.groups do %>

<%= group.name %>

  <% end %>

<% end %>

<%= unless Enum.empty?(@user.followers) do %>

Followers

  <%= for follower <- @user.followers do %>

<%= full_name(follower) %>

  <% end %>

<% end %>

<%= unless Enum.empty?(@user.followees) do %>

Followees

  <%= for followee <- @user.followees do %>

<%= full_name(followee) %>

  <% end %>

<% end %>

<%= link gettext("Edit"), to: user_path(@conn, :edit, @user) %>
<%= link gettext("Back"), to: user_path(@conn, :index) %>

<%= full_name(@user) %>

<%= if gravatar_url(@user) do %>
<img src="<%= gravatar_url(@user) %>" />
<% end %>

  <%= if @user.first_name do %>

      <%= gettext "First name:" %>
      <%= @user.first_name %>

  <% end %>

  <%= if @user.last_name do %>

      <%= gettext "Last name:" %>
      <%= @user.last_name %>

  <% end %>

  <%= if @user.middlename do %>

      <%= gettext "Middlename:" %>
      <%= @user.middlename %>

  <% end %>

  <%= if @user.nickname do %>

      <%= gettext "Nickname:" %>
      <%= @user.nickname %>

  <% end %>

  <%= if @user.honorific_prefix do %>

      <%= gettext "Honorific prefix:" %>
      <%= @user.honorific_prefix %>

  <% end %>

  <%= if @user.honorific_suffix do %>

      <%= gettext "Honorific suffix:" %>
      <%= @user.honorific_suffix %>

  <% end %>

  <%= if @user.gender do %>

      <%= gettext "Gender:" %>
      <%= @user.gender %>

  <% end %>

  <%= if @user.birthdate do %>

      <%= gettext "Birthdate:" %>
      <%= @user.birthdate %>

  <% end %>

  <%= if @user.verified do %>

      <%= gettext "Verified:" %>
      <%= @user.verified %>

  <% end %>

<%= if @user.avatar do %>

<img src="<%= avatar_url(@user) %>" alt="Avatar of <%= full_name(@user) %>">

<% end %>

<%= unless Enum.empty?(@user.emails) do %>

E-Mails

  <%= for email <- @user.emails do %>

<%= email.value %>

  <% end %>

<% end %>

<%= unless Enum.empty?(@user.groups) do %>

Groups

  <%= for group <- @user.groups do %>

<%= group.name %>

  <% end %>

<% end %>

<%= unless Enum.empty?(@user.followers) do %>

Followers

  <%= for follower <- @user.followers do %>

<%= full_name(follower) %>

  <% end %>

<% end %>

<%= unless Enum.empty?(@user.followees) do %>

Followees

  <%= for followee <- @user.followees do %>

<%= full_name(followee) %>

  <% end %>

<% end %>

<%= link gettext("Edit"), to: user_path(@conn, :edit, @user) %>
<%= link gettext("Back"), to: user_path(@conn, :index) %>


Fixed footer

Fixed footer

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="Online Experiments System for Economic Education">
    <meta name="author" content="Ryohei HAYASHI">

    <%= if assigns[:title] do %>
      <title>XEE.JP - <%= @title %> -</title>
    <% else %>
      <title>XEE.JP</title>
    <% end %>

    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
    <link rel="shortcut icon" href="<%= static_path(@conn, "/favicon.ico") %>">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/intro.js/2.1.0/introjs.min.css" rel="stylesheet" type="text/css">

<a href="<%= host_path(@conn, :index) %>">実験管理画面

<%= link "ログアウト", to: session_path(@conn, :delete) %>

          XEE.JP
          <%= if assigns[:title] do %>
            <%= @title %>
          <%= end %>

            <%= if logged_in?(@conn) do %>

<%= current_user(@conn).name %>

            <%= else %>

<%= link "新規登録", to: registration_path(@conn, :new) %>

<%= link "ログイン", to: session_path(@conn, :new) %>

            <%= end %>

<%= get_flash(@conn, :info) %>

<%= get_flash(@conn, :error) %>

<%= render @view_module, @view_template, assigns %>

© 2015 Ryohei HAYASHI All Rights Reserved.

Powered by Xee System.


Pagination

Pagination

      <%= if @page_number > 1 do %>
        <%= link(gettext("Previous page"),
          to: Phoenix.Controller.current_path(@conn, Map.put(@conn.params, "page", @page_number - 1)),
          class: "pagination-link") %>
      <% else %>
        <%= gettext("Previous page") %>
      <% end %>

      <%= if @page_number < @total_pages do %>
        <%= link(gettext("Next page"),
          to: Phoenix.Controller.current_path(@conn, Map.put(@conn.params, "page", @page_number + 1)),
          class: "pagination-link") %>
      <% else %>
        <%= gettext("Next page") %>
      <% end %>

  <%= if @page_number > 1 do %>
    <%= link(gettext("Previous"),
      to: Phoenix.Controller.current_path(@conn, Map.put(@conn.params, "page", @page_number - 1)),
      class: "item item-older") %>
  <% else %>
    <%= gettext("Previous") %>
  <% end %>
  <%= if @page_number < @total_pages do %>
    <%= link(gettext("Next"),
      to: Phoenix.Controller.current_path(@conn, Map.put(@conn.params, "page", @page_number + 1)),
      class: "item item-newer") %>
  <% else %>
    <%= gettext("Next") %>
  <% end %>


add ribbon to posts template

add ribbon to posts template

  <%= for post <- @posts do %>
  <% img_src = hd(post.json_metadata["image"]) %>

        <a href="/posts/<%= post.permlink %>"> <img src="<%= img_src %>">
        <%= post.category %>

        <a class="header" href="/posts/<%= post.permlink %>"> <%= post.title %>

            <%= for tag <- post.tags do %>
              <a class="ui  label" href="/tags/<%=tag%>">
                <%= format_tag(tag, @conn.assigns.lang) %>

            <% end %>

  <% end %>

      <%= for {v, i} <- generate_pagination_list(@current_page) do %>

        <a class="<%=if i == @current_page, do: "active" %> item"
           href="<%= @conn.request_path <> "?" <> URI.encode_query(%{"page"=> v}) %>">
          <%= v %>

      <% end %>

  <%= for post <- @posts do %>
  <% img_src = hd(post.json_metadata["image"]) %>

        <a href="/posts/<%= post.permlink %>"> <img src="<%= img_src %>">

        <a class="header" href="/posts/<%= post.permlink %>"> <%= post.title %>

            <%= for tag <- post.tags do %>
              <a class="ui  label" href="/tags/<%=tag%>">
                <%= format_tag(tag, @conn.assigns.lang) %>

            <% end %>

  <% end %>

      <%= for {v, i} <- generate_pagination_list(@current_page) do %>

        <a class="<%=if i == @current_page, do: "active" %> item"
           href="<%= @conn.request_path <> "?" <> URI.encode_query(%{"page"=> v}) %>">
          <%= v %>

      <% end %>


Remove redundant MIME type (#648)

Remove redundant MIME type (#648)

Per MDN:

Omitted or a JavaScript MIME type: This indicates the script is
JavaScript. The HTML5 specification urges authors to omit the attribute
rather than provide a redundant MIME type. In earlier browsers, this
identified the scripting language of the embedded or imported (via the
src attribute) code. JavaScript MIME types are listed in the
specification.

Source:

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script

<!DOCTYPE html>

    <meta charset="utf-8">
    <title>
      <%= page_title(assigns) %> - Today I Learned
    </title>

    <meta name="csrf" content="<%= Plug.CSRFProtection.get_csrf_token() %>">

    <meta name="format-detection" content="telephone=no">
    <meta name="description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day.">

    <meta itemprop="name" content="Today I Learned">
    <meta itemprop="brand" content="Today I Learned">
    <meta itemprop="description" content="TIL is an open-source project by Hashrocket that exists to catalogue the sharing & accumulation of knowledge as it happens day-to-day.">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:site" content="@<%= Application.get_env(:tilex, :default_twitter_handle)%>">
    <meta name="twitter:creator" content="@<%= Application.get_env(:tilex, :default_twitter_handle)%>">
    <meta name="twitter:title" content="<%= twitter_title(assigns[:post]) %>">
    <meta name="twitter:description" content="<%= twitter_description(assigns[:post]) %>">
    <meta name="twitter:image" content=<%= twitter_image_url(assigns[:post]) %>>

    <link href='//fonts.googleapis.com/css?family=Raleway:700,900&display=swap' rel='stylesheet' type='text/css'>
    <link href='//fonts.googleapis.com/css?family=Lora:400,700italic,700,400italic&display=swap' rel='stylesheet' type='text/css'>
    <link rel="alternate feed" type="application/rss+xml" title="Today I Learned" href="<%= feed_path(@conn, :index) %>">

    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/atom-one-dark.min.css">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <link rel="stylesheet" href="<%= static_url(@conn, "/css/app.css") %>">
    <%= if assigns[:canonical_url] do %>
      <link rel="canonical" href="<%= @canonical_url %>">
    <% end %>
    <link rel="manifest" href="<%= web_manifest_path(@conn, :index) %>">

    <%= if request_tracking() do %>

    <% end %>

    <%= if developer = current_user(@conn) do %>

 <%= link(developer.username, to: developer_path(@conn, :show, developer)) %>

 <%= link("Sign Out", to: auth_path(@conn, :delete), method: :delete) %>

 <%= link("Create Post", to: post_path(@conn, :new)) %>

 <%= link("Profile", to: developer_path(@conn, :edit)) %>

    <% end %>

    <header class="site_head <%= if System.get_env("BANNER"), do: "has-banner" %>">
      <%= if (System.get_env("BANNER")) do %>

            Hashrocket is hosting a Ruby, Rails, and React conference. Buy your tickets for ACR today!

      <% end %>

<%= link("Today I Learned", to: post_path(@conn, :index)) %>

          A Hashrocket project

            <a href="https://twitter.com/<%= Application.get_env(:tilex, :default_twitter_handle)%>" class="twitter">Follow on Twitter

      <%= if message = get_flash(@conn, :info) do %>

          <%= message %>

      <% end %>

      <%= render @view_module, @view_template, assigns %>

          <%= link("search", to: "#", class: "site_nav__link") %>

            <%= form_tag post_path(@conn, :index), method: :get do %>
              <input type="search" name="q" id="q" aria-label="Search">
              <%= submit "Search" %>
            <% end %>

          <%= link("?", to: "#", class: "site_nav__link", aria_label: "About TIL") %>

              Today I Learned is an open-source project by

                Hashrocket

              that exists to catalogue the sharing & accumulation of knowledge
              as it happens day-to-day. Posts have a 200-word limit, and
              posting is open to any Rocketeer as well as selected friends of
              Hashrocket. We hope you enjoy learning along with us.

                  <%= link("/#{Application.get_env(:tilex, :default_twitter_handle)}", to: "https://twitter.com/#{Application.get_env(:tilex, :default_twitter_handle)}", class: "social_twitter") %>

                  <%= link("/hashrocket/tilex", to: "https://github.com/hashrocket/tilex", class: "social_github") %>

          <%= if current_user(@conn) do %>
            <%= link("Statistics", to: stats_path(@conn, :developer), class: "site_nav__link") %>
          <% else %>
            <%= link("Statistics", to: stats_path(@conn, :index), class: "site_nav__link") %>
          <% end %>

            <%= link("Twitter", to: "https://twitter.com/#{Application.get_env(:tilex, :default_twitter_handle)}", class: "site_nav__link") %>

            <%= link("Surprise Me", to: post_path(@conn, :random), class: "site_nav__link", rel: "nofollow") %>

    <%= if ga_identifier() do %>

    <% end %>


edits to top banner

edits to top banner

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="robots" content="noindex">

    <title>Action for Children</title>
    <link href="https://fonts.googleapis.com/css?family=Rubik:400,500" rel="stylesheet">
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">

        Help keep our work going - click here to donate to Action for Children and support families across the UK.

        <a href="<%= page_path(@conn, :index) %>">

      Speak to us

      <%= render @view_module, @view_template, assigns %>

            Contact your local council if you are worried about a child's
            welfare. Contact 111 if you are worried about your child's health,
            or 999 in a medical emergency.

          <%= if @conn.assigns[:user] do %>

              You are logged in as <%= @conn.assigns.user.email %> –

            <%= link "Logout", to: session_path(@conn, :delete), class: "white"
            %>

          <% end %>
          <%= link to: page_path(@conn, :privacy), class: "white" do %>
            Privacy Policy
          <% end %>


Fix location searched for plugins in example config

# Import all plugins from `rel/plugins`
# They can then be used by adding `plugin MyPlugin` to
# either an environment, or release definition, where
# `MyPlugin` is the name of the plugin module.
Path.join(["rel", "plugins", "*.exs"])
|> Path.wildcard()
|> Enum.map(&Code.eval_file(&1))

use Mix.Releases.Config,
    # This sets the default release built by `mix release`
    default_release: :default,
    # This sets the default environment used by `mix release`
    default_environment: :dev
<%= unless no_docs do %>
# For a full list of config options for both releases
# and environments, visit https://hexdocs.pm/distillery/configuration.html
<% end %>
<%= unless no_docs do %>
# You may define one or more environments in this file,
# an environment's settings will override those of a release
# when building in that environment, this combination of release
# and environment configuration is called a profile
<% end %>
environment :dev do
  set dev_mode: true
  set include_erts: false
  set cookie: <%= inspect(get_cookie.()) %>
end

environment :prod do
  set include_erts: true
  set include_src: false
  set cookie: <%= inspect(get_cookie.()) %>
end
<%= unless no_docs do %>
# You may define one or more releases in this file.
# If you have not set a default release, or selected one
# when running `mix release`, the first release in the file
# will be used by default<% end %>
<%= for release <- releases do %><%= if Keyword.get(release, :is_umbrella) do %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: "0.1.0"
  set applications: [
<%= Enum.map(Keyword.get(release, :release_applications), fn {app, start_type} ->
    "    #{app}: :#{start_type}"
    end) |> Enum.join(",\n") %>
  ]
end<% else %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: current_version(:<%= Keyword.get(release, :release_name)%>)
end<% end %>
<% end %>

# Import all plugins from `rel/plugins`
# They can then be used by adding `plugin MyPlugin` to
# either an environment, or release definition, where
# `MyPlugin` is the name of the plugin module.
Path.join([__DIR__, "plugins", "*.exs"])
|> Path.wildcard()
|> Enum.map(&Code.eval_file(&1))

use Mix.Releases.Config,
    # This sets the default release built by `mix release`
    default_release: :default,
    # This sets the default environment used by `mix release`
    default_environment: :dev
<%= unless no_docs do %>
# For a full list of config options for both releases
# and environments, visit https://hexdocs.pm/distillery/configuration.html
<% end %>
<%= unless no_docs do %>
# You may define one or more environments in this file,
# an environment's settings will override those of a release
# when building in that environment, this combination of release
# and environment configuration is called a profile
<% end %>
environment :dev do
  set dev_mode: true
  set include_erts: false
  set cookie: <%= inspect(get_cookie.()) %>
end

environment :prod do
  set include_erts: true
  set include_src: false
  set cookie: <%= inspect(get_cookie.()) %>
end
<%= unless no_docs do %>
# You may define one or more releases in this file.
# If you have not set a default release, or selected one
# when running `mix release`, the first release in the file
# will be used by default<% end %>
<%= for release <- releases do %><%= if Keyword.get(release, :is_umbrella) do %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: "0.1.0"
  set applications: [
<%= Enum.map(Keyword.get(release, :release_applications), fn {app, start_type} ->
    "    #{app}: :#{start_type}"
    end) |> Enum.join(",\n") %>
  ]
end<% else %>
release :<%= Keyword.get(release, :release_name) %> do
  set version: current_version(:<%= Keyword.get(release, :release_name)%>)
end<% end %>
<% end %>


lines

lines

  <%= @catcount %> Categories with
  <%= @podcount %> Podcasts and
  <%= @epicount %> Episodes and counting...

    <%= for {category, counter} <- Enum.with_index(@categories) do %>

        <span class="btn btn-sm <%= btn_cycle(counter) %>">
        <%= link [fa_icon("folder-o"), " ", C.String.truncate(category.title, 22)],
                 to: category_frontend_path(@conn, :show, category),
                 style: "color: #" <> color_cycle(counter) %>

        <%= if category.children != [] do %>

            <%= for subcategory <- category.children do %>

                <%= link [fa_icon("folder-o"), " ", subcategory.title],
                         to: category_frontend_path(@conn, :show, subcategory),
                         style: "color: #555" %>

            <% end %>

        <% end %>

    <% end %>

Search

        <%= form_for @conn, search_frontend_path(@conn, :new), [as: :search], fn f -> %>

            <%= text_input f, :searchstring, class: "form-control" %>

            <%= submit "Submit", class: "btn btn-primary" %>

        <% end %>

Latest Podcasts

        <%= for podcast <- latest_podcasts do %>

            <%= link [fa_icon("podcast"), " ", C.String.truncate(podcast.title, 50)],
                     to: podcast_frontend_path(@conn, :show, podcast),
                     class: "btn btn-default btn-xs",
                     style: "color: #000" %>

            <%= fa_icon("user") %> <%= podcast.author %>

            <%= fa_icon("calendar") %> <%= podcast.inserted_at && Ecto.DateTime.to_date(podcast.inserted_at) %>

            <%= if podcast.description do %>
              <%= fa_icon("image") %> <%= C.String.truncate(podcast.description, 150) %>
            <% end %>

        <% end %>

Top 10 subscribed Podcasts

        <%= for {[count, id, title], rank} <- Enum.with_index(@popular_podcasts) do %>

            <%= rank + 1 %>.:
            <%= link [fa_icon("podcast"), " ", C.String.truncate(title, 50)],
                     to: podcast_frontend_path(@conn, :show, id),
                     class: "btn btn-default btn-xs",
                     style: "color: #000" %>
            <%= count %> <%= fa_icon("user") %>

        <% end %>

Latest Episodes

        <%= for episode <- latest_episodes do %>

            <%= link [fa_icon("headphones"), " ", C.String.truncate(episode.title, 40)],
                        to: episode_frontend_path(@conn, :show, episode),
                        class: "btn btn-primary btn-xs" %>

            <%= link [fa_icon("podcast"), " ", episode.podcast.title],
                        to: podcast_frontend_path(@conn, :show, episode.podcast),
                        class: "btn btn-default btn-xs",
                        style: "color: #000;" %>

            <%= fa_icon("calendar") %> <%= Ecto.DateTime.to_date(episode.publishing_date) %>

            <%= if episode.duration do %>
              <%= fa_icon("clock-o") %> <%= episode.duration %>

            <%= end %>
            <%= if episode.author do %>
              <%= fa_icon("user") %> <%= episode.author %>

            <%= end %>
            <%= if episode.subtitle do %>
              <%= fa_icon("image") %> <%= episode.subtitle %>
            <%= end %>

        <% end %>


Load assets from bungie over https to avoid mixed content warnings

Redemptions

Please install the Privileged bungie api extension


Add autofocus.

Add autofocus.

      Player
      Chips
      Exact
      $1

    <%= for attendee_result <- @attendees do %>
      <% selected_player = (Integer.to_string(attendee_result.player_id) == @selected_player_id) %>

          <%= if selected_player && !@historical_game do %>
            <%= render("cash_out_player_button.html",
                  game_night_id: @game_night.id,
                  player_id: -1,
                  hostname: @hostname,
                  nickname: attendee_result.player.nickname,
                  classname: "btn-primary") %>
          <%= else %>
            <%= render("cash_out_player_button.html",
                  game_night_id: @game_night.id,
                  player_id: attendee_result.player_id,
                  hostname: @hostname,
                  nickname: attendee_result.player.nickname,
                  classname: "btn-default") %>
          <%= end %>

        <%= if selected_player && !@historical_game do %>

            <form
              class="form-search"
              style="margin: 0;"
              action="/attendee_result/<%= attendee_result.id %>/set_chipcount"
            >

              <input autofocus
                pattern="[0-9]*"
                type="text"
                name="chipcount"
                maxlength="7"
                size="7"
                value="<%= attendee_result.chips %>"
              />

              <input type="submit" value="OK" class="btn btn-primary">
            </form>

        <%= else %>

            <%= :erlang.float_to_binary(attendee_result.chips / 100, decimals: 2) %>

            <%= dollars_n_cents(attendee_result.exact_cents) %>

            $<%= round(attendee_result.rounded_cents / 100) %>

        <%= end %>

    <%= end %>

        TOTALS:

      <td class="<%= @chips_color %>">
        <%= :erlang.float_to_binary(@total_chips, decimals: 2) %>

        <%= dollars_n_cents(@exact_cents) %>

        $<%= round(@rounded_1_cents / 100) %>

<%= if @fwd_to != [] do %>

    Please forward to:
    <%= Enum.join(@fwd_to, ", ") %>

<%= end %>

      Player
      Chips
      Exact
      $1

    <%= for attendee_result <- @attendees do %>
      <% selected_player = (Integer.to_string(attendee_result.player_id) == @selected_player_id) %>

          <%= if selected_player && !@historical_game do %>
            <%= render("cash_out_player_button.html",
                  game_night_id: @game_night.id,
                  player_id: -1,
                  hostname: @hostname,
                  nickname: attendee_result.player.nickname,
                  classname: "btn-primary") %>
          <%= else %>
            <%= render("cash_out_player_button.html",
                  game_night_id: @game_night.id,
                  player_id: attendee_result.player_id,
                  hostname: @hostname,
                  nickname: attendee_result.player.nickname,
                  classname: "btn-default") %>
          <%= end %>

        <%= if selected_player && !@historical_game do %>

            <form
              class="form-search"
              style="margin: 0;"
              action="/attendee_result/<%= attendee_result.id %>/set_chipcount"
            >

              <input
                pattern="[0-9]*"
                type="text"
                name="chipcount"
                maxlength="7"
                size="7"
                value="<%= attendee_result.chips %>"
              />

              <input type="submit" value="OK" class="btn btn-primary">
            </form>

        <%= else %>

            <%= :erlang.float_to_binary(attendee_result.chips / 100, decimals: 2) %>

            <%= dollars_n_cents(attendee_result.exact_cents) %>

            $<%= round(attendee_result.rounded_cents / 100) %>

        <%= end %>

    <%= end %>

        TOTALS:

      <td class="<%= @chips_color %>">
        <%= :erlang.float_to_binary(@total_chips, decimals: 2) %>

        <%= dollars_n_cents(@exact_cents) %>

        $<%= round(@rounded_1_cents / 100) %>

<%= if @fwd_to != [] do %>

    Please forward to:
    <%= Enum.join(@fwd_to, ", ") %>

<%= end %>


Render game server state status on the board.

  <% width = @world.width %>
  <% height = @world.height %>

    <%= content_tag :svg, width: "100%", height: "100%", style: "flex: 1;", viewBox: "0 0 #{width} #{height}" do %>
      <%= content_tag :rect, "", y: 0, x: 0, width: width, height: height, fill: "lightgrey" %>

      <%= for snake <- @world.snakes, {point, index} <- Enum.with_index(snake.coords, 1) do %>
        <%=
        content_tag :rect, "",
        y: point.y,
        x: point.x,
        width: 1,
        height: 1,
        fill: snake.color,
        fill_opacity: 1 - index / length(snake.coords) + 0.3
        %>
      <% end %>

      <%= for food <- @world.food do %>
        <%=
        content_tag :rect, "",
        y: food.y,
        x: food.x,
        width: 1,
        height: 1,
        fill: :green
        %>
      <% end %>
    <% end %>

          status

          <%= @state.status %>

      <%= content_tag :pre, Apex.Format.format(%{@state|hist: nil}, color: false) %>

  <% width = @world.width %>
  <% height = @world.height %>
  <%= content_tag :svg, height: "100%", width: "100%", viewBox: "0 0 #{width} #{height}" do %>
    <%= content_tag :rect, "", y: 0, x: 0, width: width, height: height, fill: "lightgrey" %>

    <%= for snake <- @world.snakes, {point, index} <- Enum.with_index(snake.coords, 1) do %>
      <%=
      content_tag :rect, "",
      y: point.y,
      x: point.x,
      width: 1,
      height: 1,
      fill: snake.color,
      fill_opacity: 1 - index / length(snake.coords) + 0.3
      %>
    <% end %>

    <%= for food <- @world.food do %>
      <%=
      content_tag :rect, "",
      y: food.y,
      x: food.x,
      width: 1,
      height: 1,
      fill: :green
      %>
    <% end %>
  <% end %>
  <%= content_tag :pre, Apex.Format.format(%{@state|hist: nil}, color: false) %>


Update of the ad.

Update of the ad.

  <%= gettext("Ad") %>

Fire HD 6 ab nur 74,99 €

15,2 cm (6 Zoll), HD-Display. 30 € Rabatt auf Fire HD 6 (Limone)

  amazon.de

  <%= gettext("Ad") %>

Urlaubsplaner online

Mit dem timetape Urlaubsplaner organisieren Sie Urlaubsanträge und Abwesenheiten online. Einfach, sicher und zuverlässig. Testen Sie uns.

  https://www.timetape.de


Don't draw tail if the snake is stacked

Don't draw tail if the snake is stacked

this way only the head will be drawn on the first turn

<% coords = Enum.dedup(@snake.coords) %>
<% [head|hs] = Enum.take(coords, 2) %>
<% [tail|ts] = Enum.take(coords, -2) |> Enum.reverse %>
<% color = @snake.color %>
<use
    class="obj-snake"
    style="fill: <%= color %>"
    transform="<%= transform_segment(head, hs) %>"
    x="<%= head.x %>"
    xlink:href="#snake-head"
    y="<%= head.y %>"
></use>
<%= if length(coords) > 1 do %>
  <g transform="translate(0.5 0.5)">
    <path class="obj-snake"
          stroke="<%= color %>"
          d="<%= snake_path(@snake) %>">
    </path>
  </g>
  <use
      class="obj-snake"
      style="fill: <%= color %>"
      transform="<%= transform_segment(tail, ts) %>"
      x="<%= tail.x %>"
      xlink:href="#snake-tail"
      y="<%= tail.y %>"
  ></use>
<% end %>

<% coords = Enum.dedup(@snake.coords) %>
<% [head|hs] = Enum.take(coords, 2) %>
<% [tail|ts] = Enum.take(coords, -2) |> Enum.reverse %>
<% color = @snake.color %>

<g transform="translate(0.5 0.5)">
  <path class="obj-snake"
        stroke="<%= color %>"
        d="<%= snake_path(@snake) %>">
  </path>
</g>

<use
    class="obj-snake"
    style="fill: <%= color %>"
    transform="<%= transform_segment(head, hs) %>"
    x="<%= head.x %>"
    xlink:href="#snake-head"
    y="<%= head.y %>"
></use>

<use
    class="obj-snake"
    style="fill: <%= color %>"
    transform="<%= transform_segment(tail, ts) %>"
    x="<%= tail.x %>"
    xlink:href="#snake-tail"
    y="<%= tail.y %>"
></use>


Parent -> Parent/Guardian

Parent -> Parent/Guardian

Add your information!

    Enter your information to be included in the student directory. All fields are optional.
    <%= if @support_email do %>

Questions or comments? Email <a href='mailto:<%= @support_email %>?Subject=Support'>
        <%= @support_email %>
    <% end %>

  <%= form_for @conn, "/", [as: :entry, class: "form-horizontal"],  fn _ -> %>

Student Information

        <button id="add-student-button" type="button" class="btn btn-default btn-small pull-right">
           Add Another Student
        </button>

Parent/Guardian Information

        <button id="add-parent-button" type="button" class="btn btn-default btn-small pull-right">
           Add Another Parent/Guardian
        </button>

Notes

            Notes

              <textarea name="entry[notes]" id="notes" rows="3" class="form-control" placeholder="Anything you want the fine folks compiling the directory to know. Let us know if you are on the PTO, a classroom representative, on the School Committee, on the School Council, or on the Safety Committee."></textarea>

        <button type="submit" class="btn btn-lg btn-success btn-block">Submit</button>

<% end %>

Add your information!

    Enter your information to be included in the student directory. All fields are optional.
    <%= if @support_email do %>

Questions or comments? Email <a href='mailto:<%= @support_email %>?Subject=Support'>
        <%= @support_email %>
    <% end %>

  <%= form_for @conn, "/", [as: :entry, class: "form-horizontal"],  fn _ -> %>

Student Information

        <button id="add-student-button" type="button" class="btn btn-default btn-small pull-right">
           Add Another Student
        </button>

Parent Information

        <button id="add-parent-button" type="button" class="btn btn-default btn-small pull-right">
           Add Another Parent
        </button>

Notes

            Notes

              <textarea name="entry[notes]" id="notes" rows="3" class="form-control" placeholder="Anything you want the fine folks compiling the directory to know. Let us know if you are on the PTO, a classroom representative, on the School Committee, on the School Council, or on the Safety Committee."></textarea>

        <button type="submit" class="btn btn-lg btn-success btn-block">Submit</button>

<% end %>


Don't display the upvote thumb up when already upvoted.

  <%= for user_skill <- @user_skills do %>
    <li class="<%= if @current_user && Vutuv.Endorsement.skill_endorsed?(user_skill.id, @current_user_id), do: "upvoted" %>">
        <%= link to: user_user_skill_path(@conn, :show, @user, user_skill), class: "tag" do %>
          <%= Skill.resolve_name(user_skill.skill_id) %>
          <%= Enum.count(user_skill.endorsements) %>
        <% end %>
      <%= if @current_user do %>
        <%= unless Vutuv.Endorsement.skill_endorsed?(user_skill.id, @current_user_id) do %>
          <%= button to: user_endorsement_path(@conn, :create, @user, id: user_skill), method: :post, class: "button-link", form: [class: "upvote button_list"] do %>

          <% end %>
        <%= end %>
      <% end %>

  <% end %>

  <%= for user_skill <- @user_skills do %>
    <li class="<%= if @current_user && Vutuv.Endorsement.skill_endorsed?(user_skill.id, @current_user_id), do: "upvoted" %>">
        <%= link to: user_user_skill_path(@conn, :show, @user, user_skill), class: "tag" do %>
          <%= Skill.resolve_name(user_skill.skill_id) %>
          <%= Enum.count(user_skill.endorsements) %>
        <% end %>
      <%= if @current_user do %>
        <%= if Vutuv.Endorsement.skill_endorsed?(user_skill.id, @current_user_id) do %>
          <%= button to: user_endorsement_path(@conn, :delete, @user, user_skill), method: :delete , class: "button-link", form: [class: "upvote button_list"] do %>

          <% end %>
        <%= else %>
          <%= button to: user_endorsement_path(@conn, :create, @user, id: user_skill), method: :post, class: "button-link", form: [class: "upvote button_list"] do %>

          <% end %>
        <%= end %>
      <% end %>

  <% end %>


Add a list of reasons why the previewer may not be working. (#177)

Closes #175

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <title>Email Preview</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.0.0/normalize.css" charset="utf-8">

No emails have been sent

        Here are some possible reasons

            Not using Bamboo.LocalAdapter. Make sure you have
            your mailer configured to use Bamboo.LocalAdapter or the
            emails will not show up here.

            You recently restarted your server. The previewer
            does not persist emails so whenever you restart the server the list
            will be cleared.

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <title>Email Preview</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.0.0/normalize.css" charset="utf-8">

No emails have been sent

        If you think you have sent an email and it is not showing up, make sure
        you are using Bamboo.LocalAdapter for your mailer.


Link to correct member on access log

Link to correct member on access log

Access Log

<%= if length(@access_attempts) > 0 do %>

      Allowed
      Why
      When
      Who
      Where

    <%= for access_attempt <- @access_attempts do %>
      <tr class="door_access_attempt_allowed_<%= access_attempt.access_allowed %>">

          <%= if access_attempt.access_allowed do %>

            Yes
          <% else %>
            No
          <% end %>

        <%= access_attempt.reason %>

          <%=
            {:ok, inserted_at} = Ecto.DateTime.dump access_attempt.inserted_at
            local_time = Timex.Timezone.convert Timex.Date.from(inserted_at), Timex.Timezone.get("America/New_York")
            {:ok, time} = Timex.DateFormat.format(local_time, "%a, %b %e @ %l:%M:%S%P", :strftime)
            time
          %>

          <%= if member = access_attempt.member do %>
            <%= link member.name, to: company_member_path(@conn, :show, member.company, member) %> (<%= link member.company.name, to: company_path(@conn, :show, member.company) %>)
          <% else %>
            <%= link "Unassigned Token: #{access_attempt.rfid_token.identifier}", to: rfid_token_path(@conn, :show, access_attempt.rfid_token) %>
          <% end %>

        <%= link access_attempt.door.name, to: door_path(@conn, :show, access_attempt.door) %>

    <% end %>

<% else %>

No attempts to access a door

<% end %>

Access Log

<%= if length(@access_attempts) > 0 do %>

      Allowed
      Why
      When
      Who
      Where

    <%= for access_attempt <- @access_attempts do %>
      <tr class="door_access_attempt_allowed_<%= access_attempt.access_allowed %>">

          <%= if access_attempt.access_allowed do %>

            Yes
          <% else %>
            No
          <% end %>

        <%= access_attempt.reason %>

          <%=
            {:ok, inserted_at} = Ecto.DateTime.dump access_attempt.inserted_at
            local_time = Timex.Timezone.convert Timex.Date.from(inserted_at), Timex.Timezone.get("America/New_York")
            {:ok, time} = Timex.DateFormat.format(local_time, "%a, %b %e @ %l:%M:%S%P", :strftime)
            time
          %>

          <%= if member = access_attempt.member do %>
            <%= link member.name, to: company_member_path(@conn, :show, member, member.company) %> (<%= link member.company.name, to: company_path(@conn, :show, member.company) %>)
          <% else %>
            <%= link "Unassigned Token: #{access_attempt.rfid_token.identifier}", to: rfid_token_path(@conn, :show, access_attempt.rfid_token) %>
          <% end %>

        <%= link access_attempt.door.name, to: door_path(@conn, :show, access_attempt.door) %>

    <% end %>

<% else %>

No attempts to access a door

<% end %>


note at feed_backlogs_new, that you can upload whole opml files

Suggest a new Podcast

  If you want to suggest several or all the podcasts you listen to at once, you can upload an OPML file at
  <%= link "My OPMLs", to: opml_frontend_path(@conn, :index)%> in your personal menu.

  <%= form_for @changeset, feed_backlog_frontend_path(@conn, :create), fn f -> %>
    <%= if @changeset.action do %>

Oops, something went wrong! Please check the errors below.

    <% end %>

      <%= label f, "RSS Feed Url", class: "control-label" %>
      <%= text_input f, :url, class: "form-control" %>
      <%= error_tag f, :url %>

      <%= submit "Submit", class: "btn btn-primary" %>

  <% end %>

Suggest a new Podcast

<%= form_for @changeset, feed_backlog_frontend_path(@conn, :create), fn f -> %>
  <%= if @changeset.action do %>

Oops, something went wrong! Please check the errors below.

  <% end %>

    <%= label f, "RSS Feed Url", class: "control-label" %>
    <%= text_input f, :url, class: "form-control" %>
    <%= error_tag f, :url %>

    <%= submit "Submit", class: "btn btn-primary" %>

<% end %>

<%= link "Back", to: feed_backlog_path(@conn, :index) %>


Very minor UI improvement

Very minor UI improvement

Node name

Cluster name

0

Instances

0

Clients

0

Channels

0

Partitions

Processing Time (Per Operation)


Add fields to manage stock edit form

Add fields to manage stock edit form

<%= form_for @changeset, @action, [multipart: true],  fn f -> %>
  <%= if @changeset.action do %>

Oops, something went wrong! Please check the errors below.

  <% end %>

    <%= label f, :food_id, class: "control-label" %>
    <%= select f, :food_id, food_list(), class: "form-control select2" %>
    <%= error_tag f, :food %>

    <%= label f, :facility_id, class: "control-label" %>
    <%= select f, :facility_id, facility_list(), class: "form-control" %>
    <%= error_tag f, :facility %>

    <%= label f, :quantity, class: "control-label" %>
    <%= number_input f, :quantity, class: "form-control" %>
    <%= error_tag f, :quantity %>

    <%= label f, :override_text, class: "control-label" %>
    <%= text_input f, :override_text, class: "form-control" %>
    <%= error_tag f, :override_text %>

    <%= label f, :arrival, class: "control-label" %>
    <%= date_select f, :arrival, class: "form-control" %>
    <%= error_tag f, :arrival %>

    <%= label f, :expiration, class: "control-label" %>
    <%= date_select f, :expiration, class: "form-control" %>
    <%= error_tag f, :expiration %>

    <%= label f, :reorder_quantity, class: "control-label" %>
    <%= number_input f, :reorder_quantity, class: "form-control" %>
    <%= error_tag f, :reorder_quantity %>

    <%= label f, :weight, class: "control-label" %>
    <%= number_input f, :weight, class: "form-control" %>
    <%= error_tag f, :weight %>

    <%= label f, :aisle, class: "control-label" %>
    <%= text_input f, :aisle, class: "form-control" %>
    <%= error_tag f, :aisle %>

    <%= label f, :row, class: "control-label" %>
    <%= text_input f, :row, class: "form-control" %>
    <%= error_tag f, :row %>

    <%= label f, :shelf, class: "control-label" %>
    <%= text_input f, :shelf, class: "form-control" %>
    <%= error_tag f, :shelf %>

    <%= label f, :packaging, class: "control-label" %>
    <%= text_input f, :packaging, class: "form-control" %>
    <%= error_tag f, :packaging %>

    <%= label f, :credits_per_package, class: "control-label" %>
    <%= number_input f, :credits_per_package, class: "form-control" %>
    <%= error_tag f, :credits_per_package %>

    <%= label f, :max_per_package, class: "control-label" %>
    <%= number_input f, :max_per_package, class: "form-control" %>
    <%= error_tag f, :max_per_package %>

    <%= label f, :max_per_person, class: "control-label" %>
    <%= number_input f, :max_per_person, class: "form-control" %>
    <%= error_tag f, :max_per_person %>

    <%= label f, :storage, class: "control-label" %>
    <%= select f, :storage, RefrigerationEnum.__enum_map__,  class: "form-control" %>
    <%= error_tag f, :storage %>

  <%= if @changeset.data.image do %>
    <%= img_tag(image_url(@changeset.data), class: "image") %>
  <% end %>

    <%= label f, :image, class: "control-label" %>
    <%= file_input f, :image, class: "form-control" %>
    <%= error_tag f, :image %>

    <%= submit "Submit", class: "btn btn-primary" %>

<% end %>

<%= form_for @changeset, @action, [multipart: true],  fn f -> %>
  <%= if @changeset.action do %>

Oops, something went wrong! Please check the errors below.

  <% end %>

    <%= label f, :food_id, class: "control-label" %>
    <%= select f, :food_id, food_list(), class: "form-control select2" %>
    <%= error_tag f, :food %>

    <%= label f, :facility_id, class: "control-label" %>
    <%= select f, :facility_id, facility_list(), class: "form-control" %>
    <%= error_tag f, :facility %>

    <%= label f, :quantity, class: "control-label" %>
    <%= number_input f, :quantity, class: "form-control" %>
    <%= error_tag f, :quantity %>

    <%= label f, :override_text, class: "control-label" %>
    <%= text_input f, :override_text, class: "form-control" %>
    <%= error_tag f, :override_text %>

    <%= label f, :arrival, class: "control-label" %>
    <%= date_select f, :arrival, class: "form-control" %>
    <%= error_tag f, :arrival %>

    <%= label f, :expiration, class: "control-label" %>
    <%= date_select f, :expiration, class: "form-control" %>
    <%= error_tag f, :expiration %>

    <%= label f, :reorder_quantity, class: "control-label" %>
    <%= number_input f, :reorder_quantity, class: "form-control" %>
    <%= error_tag f, :reorder_quantity %>

    <%= label f, :weight, class: "control-label" %>
    <%= number_input f, :weight, class: "form-control" %>
    <%= error_tag f, :weight %>

    <%= label f, :aisle, class: "control-label" %>
    <%= text_input f, :aisle, class: "form-control" %>
    <%= error_tag f, :aisle %>

    <%= label f, :row, class: "control-label" %>
    <%= text_input f, :row, class: "form-control" %>
    <%= error_tag f, :row %>

    <%= label f, :shelf, class: "control-label" %>
    <%= text_input f, :shelf, class: "form-control" %>
    <%= error_tag f, :shelf %>

    <%= label f, :packaging, class: "control-label" %>
    <%= text_input f, :packaging, class: "form-control" %>
    <%= error_tag f, :packaging %>

    <%= label f, :credits_per_package, class: "control-label" %>
    <%= number_input f, :credits_per_package, class: "form-control" %>
    <%= error_tag f, :credits_per_package %>

    <%= label f, :storage, class: "control-label" %>
    <%= select f, :storage, RefrigerationEnum.__enum_map__,  class: "form-control" %>
    <%= error_tag f, :storage %>

  <%= if @changeset.data.image do %>
    <%= img_tag(image_url(@changeset.data), class: "image") %>
  <% end %>

    <%= label f, :image, class: "control-label" %>
    <%= file_input f, :image, class: "form-control" %>
    <%= error_tag f, :image %>

    <%= submit "Submit", class: "btn btn-primary" %>

<% end %>


Added list of teachers to the offered course show page

          <%= Enum.join [@offered_course.course.name, @offered_course.term.name], " - " %>

        <%= if @user_role == "Coordinator" do %>

            <%= link "Edit", to: offered_course_path(@conn, :edit, @offered_course),
                             class: "mdl-button mdl-js-button mdl-button--raised"
            %>

        <% end %>

        <%= CoursePlanner.SharedView.card "Syllabus", highlighted_title: true do %>
          <%= CoursePlanner.SharedView.card_content do %>

              <%= @offered_course.syllabus %>

          <% end %>
        <% end %>

        <%= if length(@next_classes) > 0 do %>

              Next Classes

          <%= CoursePlanner.SharedView.class_list @next_classes, empty_text: "This course has no classes yet",
                                                                 show_attendances: @user_role === "Student"
          %>
        <% end %>

        <%= if length(@past_classes) > 0 do %>

              Past Classes

          <%= CoursePlanner.SharedView.class_list @past_classes, empty_text: "This course has no classes yet",
                                                                 show_attendances: @user_role === "Student"
          %>
        <% end %>

            Teachers

        <%= CoursePlanner.SharedView.user_list @offered_course.teachers, empty_text: "This course has no teachers yet" %>

            <%= if @user_role == "Student" do %>
              Classmates
            <% else %>
              Students
            <% end %>

        <%= CoursePlanner.SharedView.user_list @offered_course.students, empty_text: "This course has no students yet" %>

          <%= Enum.join [@offered_course.course.name, @offered_course.term.name], " - " %>

        <%= if @user_role == "Coordinator" do %>

            <%= link "Edit", to: offered_course_path(@conn, :edit, @offered_course),
                             class: "mdl-button mdl-js-button mdl-button--raised"
            %>

        <% end %>

        <%= CoursePlanner.SharedView.card "Syllabus", highlighted_title: true do %>
          <%= CoursePlanner.SharedView.card_content do %>

              <%= @offered_course.syllabus %>

          <% end %>
        <% end %>

        <%= if length(@next_classes) > 0 do %>

              Next Classes

          <%= CoursePlanner.SharedView.class_list @next_classes, empty_text: "This course has no classes yet",
                                                                 show_attendances: @user_role === "Student"
          %>
        <% end %>

        <%= if length(@past_classes) > 0 do %>

              Past Classes

          <%= CoursePlanner.SharedView.class_list @past_classes, empty_text: "This course has no classes yet",
                                                                 show_attendances: @user_role === "Student"
          %>
        <% end %>

            <%= if @user_role == "Student" do %>
              Classmates
            <% else %>
              Students
            <% end %>

        <%= CoursePlanner.SharedView.user_list @offered_course.students, empty_text: "This course has no students yet" %>


beautify account dashboard

beautify account dashboard

Dashboard

Attended events

      <%= if length(@events_as_attendee) > 0 do %>

          <%= for event <- @events_as_attendee do %>

              <%= link event.name, to: classroom_dashboard_path(@conn, :show, event) %>
              <%= if Calendar.DateTime.before?(event.ends_at, Calendar.DateTime.now_utc()) do %>
                Finished
              <% end %>
              <%= if Calendar.DateTime.after?(event.ends_at, Calendar.DateTime.now_utc()) && Calendar.DateTime.before?(event.starts_at, Calendar.DateTime.now_utc()) do %>
                Running
              <% end %>

          <% end %>

      <% else %>

There are no attendences, yet

      <% end %>

Own events

      <%= if length(@events_as_owner) > 0 do %>

          <%= for event <- @events_as_owner do %>

              <%= link event.name, to: classroom_dashboard_path(@conn, :show, event) %>
              <%= if Calendar.DateTime.before?(event.ends_at, Calendar.DateTime.now_utc()) do %>
                Finished
              <% end %>
              <%= if Calendar.DateTime.after?(event.ends_at, Calendar.DateTime.now_utc()) && Calendar.DateTime.before?(event.starts_at, Calendar.DateTime.now_utc()) do %>
                Running
              <% end %>

          <% end %>

      <% else %>

There are own events, yet

      <% end %>

Dashboard

My attended events

      <%= for event <- @events_as_attendee do %>

<%= link event.name, to: classroom_dashboard_path(@conn, :show, event) %>

      <% end %>

My created events

      <%= for event <- @events_as_owner do %>

<%= link event.name, to: classroom_dashboard_path(@conn, :show, event) %>

      <% end %>


BRANDING!

BRANDING!

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="<%= page_description(@conn, assigns) %>">
<meta name="keywords" content="<%= I18n.t!("en", "seo.keywords") %>">
<meta name="author" content="Michelada.io">

<meta property="og:title" content="<%= page_title(@conn, assigns) %>">
<meta property="og:type" content="article">
<meta property="og:image" content="<%= static_url(@conn, "/images/main-logo.png") %>">
<meta property="og:description" content="<%= page_description(@conn, assigns) %>">
<meta property="og:url" content="<%= current_page_url(@conn, assigns) %>">

<meta name="twitter:card" content="summary">
<meta name="twitter:url" content="<%= current_page_url(@conn, assigns) %>">
<meta name="twitter:title" content="<%= page_title(@conn, assigns) %>">
<meta name="twitter:description" content="<%= page_description(@conn, assigns) %>">
<meta name="twitter:image" content="<%= static_url(@conn, "/images/main-logo.png") %>">
<meta name="twitter:site" content="@micheladaio">
<link rel="alternate" type="application/atom+xml" title="feed" href="<%= atom_url(@conn, :index) %>" />

<title>michelada.io :: <%= page_title(@conn, assigns) %></title>

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="<%= page_description(@conn, assigns) %>">
<meta name="keywords" content="<%= I18n.t!("en", "seo.keywords") %>">
<meta name="author" content="Michelada.io">

<meta property="og:title" content="<%= page_title(@conn, assigns) %>">
<meta property="og:type" content="article">
<meta property="og:image" content="<%= static_url(@conn, "/images/main-logo.png") %>">
<meta property="og:description" content="<%= page_description(@conn, assigns) %>">
<meta property="og:url" content="<%= current_page_url(@conn, assigns) %>">

<meta name="twitter:card" content="summary">
<meta name="twitter:url" content="<%= current_page_url(@conn, assigns) %>">
<meta name="twitter:title" content="<%= page_title(@conn, assigns) %>">
<meta name="twitter:description" content="<%= page_description(@conn, assigns) %>">
<meta name="twitter:image" content="<%= static_url(@conn, "/images/main-logo.png") %>">
<meta name="twitter:site" content="@micheladaio">
<link rel="alternate" type="application/atom+xml" title="feed" href="<%= atom_url(@conn, :index) %>" />

<title>Michelada.io :: <%= page_title(@conn, assigns) %></title>


Remove optional namespace from nested <svg> elem

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="width: <%= @cols + 2 %>ch; height: <%= (@rows + 1) * 1.4 %>em" font-family="Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'" font-size="14px">
  <style>
   <%= render "_svg_theme_#{@theme_name}.css" %>
   <%= render "_svg_256_colors.css" %>
   .br { font-weight: bold }
   .it { font-style: italic }
   .un { text-decoration: underline }
  </style>

  <rect width="100%" height="100%" class="default-bg-fill"></rect>

  <svg x="<%= percent(1.0 * 100 / (@cols + 2)) %>" y="<%= percent(0.5 * 100 / (@rows + 1)) %>" class="default-text-fill">
    <g style="shape-rendering: optimizeSpeed">
    <%= for chunks <- @chunk_lines do %><%= for chunk <- chunks do %><%= if c = svg_rect_class(chunk.attrs) do %><rect x="<%= percent(100 * chunk.x / (@cols + 2)) %>" y="<%= percent(100 * chunk.y / (@rows + 1)) %>" width="<%= percent(100 * chunk.width / (@cols + 2)) %>" height="<%= percent(102 / (@rows + 1)) %>" class="<%= c %>"></rect>
<% end %><% end %><% end %>
    </g>

    <text>
      <%= for chunks <- @char_lines do %><%= for chunk <- chunks do %><%= if String.trim(chunk.text) != "" do %><tspan dy="1.0em" x="<%= percent(100 * chunk.x / (@cols + 2)) %>" y="<%= percent(100 * chunk.y / (@rows + 1)) %>"<%= if c = svg_text_class(chunk.attrs) do %> class="<%= c %>"<% end %><%= if s = svg_style(chunk.attrs) do %> style="<%= s %>"<% end %>><%= chunk.text %></tspan>
<% end %><% end %><% end %>
    </text>
  </svg>
</svg>

<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="width: <%= @cols + 2 %>ch; height: <%= (@rows + 1) * 1.4 %>em" font-family="Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'" font-size="14px">
  <style>
   <%= render "_svg_theme_#{@theme_name}.css" %>
   <%= render "_svg_256_colors.css" %>
   .br { font-weight: bold }
   .it { font-style: italic }
   .un { text-decoration: underline }
  </style>

  <rect width="100%" height="100%" class="default-bg-fill"></rect>

  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="<%= percent(1.0 * 100 / (@cols + 2)) %>" y="<%= percent(0.5 * 100 / (@rows + 1)) %>" class="default-text-fill">
    <g style="shape-rendering: optimizeSpeed">
    <%= for chunks <- @chunk_lines do %><%= for chunk <- chunks do %><%= if c = svg_rect_class(chunk.attrs) do %><rect x="<%= percent(100 * chunk.x / (@cols + 2)) %>" y="<%= percent(100 * chunk.y / (@rows + 1)) %>" width="<%= percent(100 * chunk.width / (@cols + 2)) %>" height="<%= percent(102 / (@rows + 1)) %>" class="<%= c %>"></rect>
<% end %><% end %><% end %>
    </g>

    <text>
      <%= for chunks <- @char_lines do %><%= for chunk <- chunks do %><%= if String.trim(chunk.text) != "" do %><tspan dy="1.0em" x="<%= percent(100 * chunk.x / (@cols + 2)) %>" y="<%= percent(100 * chunk.y / (@rows + 1)) %>"<%= if c = svg_text_class(chunk.attrs) do %> class="<%= c %>"<% end %><%= if s = svg_style(chunk.attrs) do %> style="<%= s %>"<% end %>><%= chunk.text %></tspan>
<% end %><% end %><% end %>
    </text>
  </svg>
</svg>


Make player nickname into a button.

Make player nickname into a button.

    <%= @attendee_result.player.nickname %>

    <%= @attendee_result.chips %>

    <%= @attendee_result.exact_cents %>

    <%= @attendee_result.rounded_cents %>


Fixed button text

Fixed button text

<%= if @products != [] do %>

    <%=  for {product, id} <- Enum.with_index @products do %>

        <%= if product.product_images != [] do %>
          <div class="<%= alternate_class_name(id, 7, 'push') %>">

                <a href="<%= product_path(@conn, :show, product.slug) %>">
                  <img src="<%= featured_image_url(product.product_images) %>" alt="<%= product.title %>" class="img-responsive" />

                <%= readable_price(product.base_price) %>

        <div class="<%= alternate_class_name(id, 5, 'pull') %>">
        <% else %>

        <% end %>

            <a href="<%= product_path(@conn, :show, product.slug) %>">
              <%= product.title %>

              <%= product.extract %>

            <%= link to: product_path(@conn, :show, product.slug), class: "btn btn-cta" do %>
              <%= if product.base_price == 0 do %>
                Preview & Download →
              <% else %>
                Preview & Purchase →
              <% end %>
            <% end %>

    <% end %>

<% else %>

    Coming soon.

    We are working aggresively to add more resources to our collection.

<% end %>

<%= if @products != [] do %>

    <%=  for {product, id} <- Enum.with_index @products do %>

        <%= if product.product_images != [] do %>
          <div class="<%= alternate_class_name(id, 7, 'push') %>">

                <a href="<%= product_path(@conn, :show, product.slug) %>">
                  <img src="<%= featured_image_url(product.product_images) %>" alt="<%= product.title %>" class="img-responsive" />

                <%= readable_price(product.base_price) %>

        <div class="<%= alternate_class_name(id, 5, 'pull') %>">
        <% else %>

        <% end %>

            <a href="<%= product_path(@conn, :show, product.slug) %>">
              <%= product.title %>

              <%= product.extract %>

            <%= link to: product_path(@conn, :show, product.slug), class: "btn btn-cta" do %>
              Preview & Purchase →
            <% end %>

    <% end %>

<% else %>

    Coming soon.

    We are working aggresively to add more resources to our collection.

<% end %>


Add encoding to container template

Add encoding to container template

<?xml version="1.0" encoding="utf-8"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
  <rootfiles>
    <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
  </rootfiles>
</container>

<?xml version="1.0"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
  <rootfiles>
    <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
  </rootfiles>
</container>