diff --git a/.ansible.cfg b/.ansible.cfg
index 09fc9ebe5a5cb40b429620d97c5043957d71b73e..8c7fd3429252633926dba095a8a3a3ce7f60f853 100644
--- a/.ansible.cfg
+++ b/.ansible.cfg
@@ -15,7 +15,6 @@ callback_whitelist = profile_tasks
 
 [ssh_connection]
 pipelining = True
-control_path=/tmp/ssh-%%h
 
 [privilege_escalation]
 #become = True
diff --git a/.aspell.en.pws b/.aspell.en.pws
index d9cabcf65e86c6b77018fe479ee40afe32f78320..e0bb31be1879628074dfe06eea2b7c40b0413e67 100644
--- a/.aspell.en.pws
+++ b/.aspell.en.pws
@@ -1,4 +1,4 @@
-personal_ws-1.1 en 154 
+personal_ws-1.1 en 158 
 cfg
 runtime
 Nginx
@@ -15,6 +15,7 @@ crackable
 cd
 Ansible's
 arn
+uuencode
 SHA
 pytest
 submodule
@@ -107,6 +108,7 @@ pdf
 ECDSA
 localhost
 linters
+wget
 SimpleHTTPServer
 scrypt
 PyPI
@@ -126,6 +128,7 @@ usr
 PolicyKit
 txt
 Bitbucket
+uudecode
 entrypoint
 html
 Jinja
@@ -135,6 +138,7 @@ Rackspace
 AES
 GPG
 PHP
+cgit
 filenames
 sudo
 POSIX
diff --git a/.bash_completion.d/aws b/.bash_completion.d/aws
new file mode 100644
index 0000000000000000000000000000000000000000..8932d45d10665583e0c578f069393e8dc0a44796
--- /dev/null
+++ b/.bash_completion.d/aws
@@ -0,0 +1 @@
+! command -v aws_completer >/dev/null || complete -C 'aws_completer' aws
diff --git a/.bash_completion.d/docker-compose b/.bash_completion.d/docker-compose
new file mode 100644
index 0000000000000000000000000000000000000000..b90af45d18921d7a3842cbfd29c5614b1bdcbfd7
--- /dev/null
+++ b/.bash_completion.d/docker-compose
@@ -0,0 +1,659 @@
+#!/bin/bash
+#
+# bash completion for docker-compose
+#
+# This work is based on the completion for the docker command.
+#
+# This script provides completion of:
+#  - commands and their options
+#  - service names
+#  - filepaths
+#
+# To enable the completions either:
+#  - place this file in /etc/bash_completion.d
+#  or
+#  - copy this file to e.g. ~/.docker-compose-completion.sh and add the line
+#    below to your .bashrc after bash completion features are loaded
+#    . ~/.docker-compose-completion.sh
+
+__docker_compose_previous_extglob_setting=$(shopt -p extglob)
+shopt -s extglob
+
+__docker_compose_q() {
+	docker-compose 2>/dev/null "${top_level_options[@]}" "$@"
+}
+
+# Transforms a multiline list of strings into a single line string
+# with the words separated by "|".
+__docker_compose_to_alternatives() {
+	local parts=( $1 )
+	local IFS='|'
+	echo "${parts[*]}"
+}
+
+# Transforms a multiline list of options into an extglob pattern
+# suitable for use in case statements.
+__docker_compose_to_extglob() {
+	local extglob=$( __docker_compose_to_alternatives "$1" )
+	echo "@($extglob)"
+}
+
+# Determines whether the option passed as the first argument exist on
+# the commandline. The option may be a pattern, e.g. `--force|-f`.
+__docker_compose_has_option() {
+	local pattern="$1"
+	for (( i=2; i < $cword; ++i)); do
+		if [[ ${words[$i]} =~ ^($pattern)$ ]] ; then
+			return 0
+		fi
+	done
+	return 1
+}
+
+# Returns `key` if we are currently completing the value of a map option (`key=value`)
+# which matches the extglob passed in as an argument.
+# This function is needed for key-specific completions.
+__docker_compose_map_key_of_current_option() {
+        local glob="$1"
+
+        local key glob_pos
+        if [ "$cur" = "=" ] ; then        # key= case
+                key="$prev"
+                glob_pos=$((cword - 2))
+        elif [[ $cur == *=* ]] ; then     # key=value case (OSX)
+                key=${cur%=*}
+                glob_pos=$((cword - 1))
+        elif [ "$prev" = "=" ] ; then
+                key=${words[$cword - 2]}  # key=value case
+                glob_pos=$((cword - 3))
+        else
+                return
+        fi
+
+        [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--))  # --option=key=value syntax
+
+        [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key"
+}
+
+# suppress trailing whitespace
+__docker_compose_nospace() {
+	# compopt is not available in ancient bash versions
+	type compopt &>/dev/null && compopt -o nospace
+}
+
+
+# Outputs a list of all defined services, regardless of their running state.
+# Arguments for `docker-compose ps` may be passed in order to filter the service list,
+# e.g. `status=running`.
+__docker_compose_services() {
+	__docker_compose_q ps --services "$@"
+}
+
+# Applies completion of services based on the current value of `$cur`.
+# Arguments for `docker-compose ps` may be passed in order to filter the service list,
+# see `__docker_compose_services`.
+__docker_compose_complete_services() {
+	COMPREPLY=( $(compgen -W "$(__docker_compose_services "$@")" -- "$cur") )
+}
+
+# The services for which at least one running container exists
+__docker_compose_complete_running_services() {
+	local names=$(__docker_compose_services --filter status=running)
+	COMPREPLY=( $(compgen -W "$names" -- "$cur") )
+}
+
+
+_docker_compose_build() {
+	case "$prev" in
+		--build-arg)
+			COMPREPLY=( $( compgen -e -- "$cur" ) )
+			__docker_compose_nospace
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--build-arg --compress --force-rm --help --memory --no-cache --pull" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services --filter source=build
+			;;
+	esac
+}
+
+
+_docker_compose_bundle() {
+	case "$prev" in
+		--output|-o)
+			_filedir
+			return
+			;;
+	esac
+
+	COMPREPLY=( $( compgen -W "--push-images --help --output -o" -- "$cur" ) )
+}
+
+
+_docker_compose_config() {
+	COMPREPLY=( $( compgen -W "--help --quiet -q --resolve-image-digests --services --volumes" -- "$cur" ) )
+}
+
+
+_docker_compose_create() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--build --force-recreate --help --no-build --no-recreate" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_docker_compose() {
+	case "$prev" in
+		--tlscacert|--tlscert|--tlskey)
+			_filedir
+			return
+			;;
+		--file|-f)
+			_filedir "y?(a)ml"
+			return
+			;;
+		--log-level)
+			COMPREPLY=( $( compgen -W "debug info warning error critical" -- "$cur" ) )
+			return
+			;;
+		--project-directory)
+			_filedir -d
+			return
+			;;
+		$(__docker_compose_to_extglob "$daemon_options_with_args") )
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "$daemon_boolean_options $daemon_options_with_args $top_level_options_with_args --help -h --no-ansi --verbose --version -v" -- "$cur" ) )
+			;;
+		*)
+			COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
+			;;
+	esac
+}
+
+
+_docker_compose_down() {
+	case "$prev" in
+		--rmi)
+			COMPREPLY=( $( compgen -W "all local" -- "$cur" ) )
+			return
+			;;
+		--timeout|-t)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --rmi --timeout -t --volumes -v --remove-orphans" -- "$cur" ) )
+			;;
+	esac
+}
+
+
+_docker_compose_events() {
+	case "$prev" in
+		--json)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --json" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_exec() {
+	case "$prev" in
+		--index|--user|-u|--workdir|-w)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "-d --detach --help --index --privileged -T --user -u --workdir -w" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_running_services
+			;;
+	esac
+}
+
+
+_docker_compose_help() {
+	COMPREPLY=( $( compgen -W "${commands[*]}" -- "$cur" ) )
+}
+
+_docker_compose_images() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --quiet -q" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+_docker_compose_kill() {
+	case "$prev" in
+		-s)
+			COMPREPLY=( $( compgen -W "SIGHUP SIGINT SIGKILL SIGUSR1 SIGUSR2" -- "$(echo $cur | tr '[:lower:]' '[:upper:]')" ) )
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help -s" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_running_services
+			;;
+	esac
+}
+
+
+_docker_compose_logs() {
+	case "$prev" in
+		--tail)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--follow -f --help --no-color --tail --timestamps -t" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_pause() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_running_services
+			;;
+	esac
+}
+
+
+_docker_compose_port() {
+	case "$prev" in
+		--protocol)
+			COMPREPLY=( $( compgen -W "tcp udp" -- "$cur" ) )
+			return;
+			;;
+		--index)
+			return;
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --index --protocol" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_ps() {
+	local key=$(__docker_compose_map_key_of_current_option '--filter')
+	case "$key" in
+		source)
+			COMPREPLY=( $( compgen -W "build image" -- "${cur##*=}" ) )
+			return
+			;;
+		status)
+			COMPREPLY=( $( compgen -W "paused restarting running stopped" -- "${cur##*=}" ) )
+			return
+			;;
+	esac
+
+	case "$prev" in
+		--filter)
+			COMPREPLY=( $( compgen -W "source status" -S "=" -- "$cur" ) )
+			__docker_compose_nospace
+			return;
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --quiet -q --services --filter" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_pull() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --ignore-pull-failures --include-deps --no-parallel --quiet -q" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services --filter source=image
+			;;
+	esac
+}
+
+
+_docker_compose_push() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --ignore-push-failures" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_restart() {
+	case "$prev" in
+		--timeout|-t)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_running_services
+			;;
+	esac
+}
+
+
+_docker_compose_rm() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--force -f --help --stop -s -v" -- "$cur" ) )
+			;;
+		*)
+			if __docker_compose_has_option "--stop|-s" ; then
+				__docker_compose_complete_services
+			else
+				__docker_compose_complete_services --filter status=stopped
+			fi
+			;;
+	esac
+}
+
+
+_docker_compose_run() {
+	case "$prev" in
+		-e)
+			COMPREPLY=( $( compgen -e -- "$cur" ) )
+			__docker_compose_nospace
+			return
+			;;
+		--entrypoint|--label|-l|--name|--user|-u|--volume|-v|--workdir|-w)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--detach -d --entrypoint -e --help --label -l --name --no-deps --publish -p --rm --service-ports -T --use-aliases --user -u --volume -v --workdir -w" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_scale() {
+	case "$prev" in
+		=)
+			COMPREPLY=("$cur")
+			return
+			;;
+		--timeout|-t)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
+			;;
+		*)
+			COMPREPLY=( $(compgen -S "=" -W "$(__docker_compose_services)" -- "$cur") )
+			__docker_compose_nospace
+			;;
+	esac
+}
+
+
+_docker_compose_start() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services --filter status=stopped
+			;;
+	esac
+}
+
+
+_docker_compose_stop() {
+	case "$prev" in
+		--timeout|-t)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help --timeout -t" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_running_services
+			;;
+	esac
+}
+
+
+_docker_compose_top() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_running_services
+			;;
+	esac
+}
+
+
+_docker_compose_unpause() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services --filter status=paused
+			;;
+	esac
+}
+
+
+_docker_compose_up() {
+	case "$prev" in
+		=)
+			COMPREPLY=("$cur")
+			return
+			;;
+		--exit-code-from)
+			__docker_compose_complete_services
+			return
+			;;
+		--scale)
+			COMPREPLY=( $(compgen -S "=" -W "$(__docker_compose_services)" -- "$cur") )
+			__docker_compose_nospace
+			return
+			;;
+		--timeout|-t)
+			return
+			;;
+	esac
+
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--abort-on-container-exit --always-recreate-deps --build -d --detach --exit-code-from --force-recreate --help --no-build --no-color --no-deps --no-recreate --no-start --renew-anon-volumes -V --remove-orphans --scale --timeout -t" -- "$cur" ) )
+			;;
+		*)
+			__docker_compose_complete_services
+			;;
+	esac
+}
+
+
+_docker_compose_version() {
+	case "$cur" in
+		-*)
+			COMPREPLY=( $( compgen -W "--short" -- "$cur" ) )
+			;;
+	esac
+}
+
+
+_docker_compose() {
+	local previous_extglob_setting=$(shopt -p extglob)
+	shopt -s extglob
+
+	local commands=(
+		build
+		bundle
+		config
+		create
+		down
+		events
+		exec
+		help
+		images
+		kill
+		logs
+		pause
+		port
+		ps
+		pull
+		push
+		restart
+		rm
+		run
+		scale
+		start
+		stop
+		top
+		unpause
+		up
+		version
+	)
+
+	# Options for the docker daemon that have to be passed to secondary calls to
+	# docker-compose executed by this script.
+	local daemon_boolean_options="
+		--skip-hostname-check
+		--tls
+		--tlsverify
+	"
+	local daemon_options_with_args="
+		--file -f
+		--host -H
+		--project-directory
+		--project-name -p
+		--tlscacert
+		--tlscert
+		--tlskey
+	"
+
+	# These options are require special treatment when searching the command.
+	local top_level_options_with_args="
+		--log-level
+	"
+
+	COMPREPLY=()
+	local cur prev words cword
+	_get_comp_words_by_ref -n : cur prev words cword
+
+	# search subcommand and invoke its handler.
+	# special treatment of some top-level options
+	local command='docker_compose'
+	local top_level_options=()
+	local counter=1
+
+	while [ $counter -lt $cword ]; do
+		case "${words[$counter]}" in
+			$(__docker_compose_to_extglob "$daemon_boolean_options") )
+				local opt=${words[counter]}
+				top_level_options+=($opt)
+				;;
+			$(__docker_compose_to_extglob "$daemon_options_with_args") )
+				local opt=${words[counter]}
+				local arg=${words[++counter]}
+				top_level_options+=($opt $arg)
+				;;
+			$(__docker_compose_to_extglob "$top_level_options_with_args") )
+				(( counter++ ))
+				;;
+			-*)
+				;;
+			*)
+				command="${words[$counter]}"
+				break
+				;;
+		esac
+		(( counter++ ))
+	done
+
+	local completions_func=_docker_compose_${command//-/_}
+	declare -F $completions_func >/dev/null && $completions_func
+
+	eval "$previous_extglob_setting"
+	return 0
+}
+
+eval "$__docker_compose_previous_extglob_setting"
+unset __docker_compose_previous_extglob_setting
+
+complete -F _docker_compose docker-compose docker-compose.exe
diff --git a/.bash_completion.d/docker_machine.bash b/.bash_completion.d/docker-machine.bash
similarity index 81%
rename from .bash_completion.d/docker_machine.bash
rename to .bash_completion.d/docker-machine.bash
index 1c9f2aba946d96104a6cfbfff685ef0d982f0804..feb08247f3c46d21108ce879e16d11aa77c6f8e1 100644
--- a/.bash_completion.d/docker_machine.bash
+++ b/.bash_completion.d/docker-machine.bash
@@ -62,7 +62,7 @@ _docker_machine_value_of_option() {
 }
 
 # Returns `key` if we are currently completing the value of a map option
-# (`key=value`) which matches the extglob passed in as an argument.
+# (`key=value`) which matches the glob passed in as an argument.
 # This function is needed for key-specific argument completions.
 _docker_machine_map_key_of_current_option() {
     local glob="$1"
@@ -83,9 +83,43 @@ _docker_machine_map_key_of_current_option() {
 
     [ "${words[$glob_pos]}" = "=" ] && ((glob_pos--))  # --option=key=value syntax
 
-    [[ ${words[$glob_pos]} == @($glob) ]] && echo "$key"
+    [[ ${words[$glob_pos]} == $glob ]] && echo "$key"
 }
 
+# Finds the position of the first word that is neither option nor an option's argument.
+# If there are options that require arguments, you need to pass a glob describing
+# those options, e.g. "--option1|-o|--option2".
+# Use this function to restrict completions to exact positions after the options.
+_docker_machine_pos_first_nonflag() {
+    local argument_flags=$1
+
+    local counter=$((${subcommand_pos:-${command_pos}} + 1))
+    while [ "$counter" -le "$cword" ]; do
+       if [ -n "$argument_flags" ] && eval "case '${words[$counter]}' in $argument_flags) true ;; *) false ;; esac"; then
+          (( counter++ ))
+          # eat "=" in case of --option=arg syntax
+          [ "${words[$counter]}" = "=" ] && (( counter++ ))
+       else
+          case "${words[$counter]}" in
+             -*)
+                 ;;
+             *)
+                 break
+                 ;;
+          esac
+       fi
+
+       # Bash splits words at "=", retaining "=" as a word, examples:
+       # "--debug=false" => 3 words, "--log-opt syslog-facility=daemon" => 4 words
+       while [ "${words[$counter + 1]}" = "=" ] ; do
+               counter=$(( counter + 2))
+       done
+
+       (( counter++ ))
+    done
+
+    echo $counter
+}
 # --- completion functions ---------------------------------------------------
 
 _docker_machine_active() {
@@ -208,6 +242,21 @@ _docker_machine_ls() {
     fi
 }
 
+_docker_machine_mount() {
+    if [[ "${cur}" == -* ]]; then
+        COMPREPLY=($(compgen -W "--help --unmount -u" -- "${cur}"))
+    else
+        local pos=$(_docker_machine_pos_first_nonflag)
+        if [ "$cword" -eq "$pos" ]; then
+            # We can't complete remote filesystems. All we can do here is to complete the machine.
+            COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -S: -- "${cur}"))
+            _docker_machine_nospace
+        elif [ "$cword" -eq "$((pos + 1))" ]; then
+           _filedir -d
+        fi
+    fi
+}
+
 _docker_machine_provision() {
     if [[ "${cur}" == -* ]]; then
         COMPREPLY=($(compgen -W "--help" -- "${cur}"))
@@ -218,7 +267,7 @@ _docker_machine_provision() {
 
 _docker_machine_regenerate_certs() {
     if [[ "${cur}" == -* ]]; then
-        COMPREPLY=($(compgen -W "--force -f --help" -- "${cur}"))
+        COMPREPLY=($(compgen -W "--client-certs --force -f --help" -- "${cur}"))
     else
         COMPREPLY=($(compgen -W "$(_docker_machine_machines --filter state=Running)" -- "${cur}"))
     fi
@@ -250,7 +299,7 @@ _docker_machine_ssh() {
 
 _docker_machine_scp() {
     if [[ "${cur}" == -* ]]; then
-        COMPREPLY=($(compgen -W "--delta -d --help --recursive -r" -- "${cur}"))
+        COMPREPLY=($(compgen -W "--delta -d --help --quiet -q --recursive -r" -- "${cur}"))
     else
         _filedir
         # It would be really nice to ssh to the machine and ls to complete
@@ -329,7 +378,7 @@ _docker_machine_docker_machine() {
 
 _docker_machine() {
     COMPREPLY=()
-    local commands=(active config create env inspect ip kill ls provision regenerate-certs restart rm ssh scp start status stop upgrade url version help)
+    local commands=(active config create env inspect ip kill ls mount provision regenerate-certs restart rm ssh scp start status stop upgrade url version help)
 
     local flags=(--debug --native-ssh --github-api-token --bugsnag-api-token --help --version)
     local wants_dir=(--storage-path)
@@ -343,7 +392,7 @@ _docker_machine() {
     local cur prev words cword
     _get_comp_words_by_ref -n : cur prev words cword
     local i
-    local command=docker-machine
+    local command=docker-machine command_pos=0
 
     for (( i=1; i < ${cword}; ++i)); do
         local word=${words[i]}
@@ -352,6 +401,7 @@ _docker_machine() {
             (( ++i ))
         elif [[ " ${commands[*]} " =~ " ${word} " ]]; then
             command=${word}
+            command_pos=$i
         fi
     done
 
diff --git a/.bash_completion.d/travis.sh b/.bash_completion.d/travis.sh
new file mode 120000
index 0000000000000000000000000000000000000000..f11637383f84a84ce3169cd9c1b4cf93c453e394
--- /dev/null
+++ b/.bash_completion.d/travis.sh
@@ -0,0 +1 @@
+../.travis/travis.sh
\ No newline at end of file
diff --git a/.bashrc b/.bashrc
index 4fc07e1e1a5b5a44e79185350a976f7dd0ed3d26..3dbf81a707e79e355f8a0746bd97d119e7f36a43 100644
--- a/.bashrc
+++ b/.bashrc
@@ -1,49 +1,12 @@
-# shellcheck disable=SC2148,SC1091
+# shellcheck disable=SC2148
 # If not running interactively, don't do anything
 [ -z "$PS1" ] && return
 
 export LANG=en_US.UTF8
+export HISTFILE="$HOME/.history"
 export HISTCONTROL=ignoreboth:erasedups
 export HISTSIZE=100000
 export HISTFILESIZE=100000
-export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
-if [ -n "${BASH:-}" ]
-then
-    shopt -s histappend
-    shopt -s checkwinsize
-    shopt -s cmdhist
-    [ -f /etc/bash_completion ] && . /etc/bash_completion
-
-    # shellcheck disable=SC2086,SC1090
-    [ -d "$HOME/.bash_completion.d" ] && . $HOME/.bash_completion.d/*
-
-    # shellcheck disable=SC1090
-    # added by travis gem
-    [ -f "$HOME/.travis/travis.sh" ] && . "$HOME/.travis/travis.sh"
-
-    # shellcheck disable=SC2015
-    which aws_completer >/dev/null && complete -C 'aws_completer' aws ||
-        true
-fi
-
-# make less more friendly for non-text input files, see lesspipe(1)
-[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
-
-# set variable identifying the chroot you work in (used in the prompt below)
-if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
-    debian_chroot=$(cat /etc/debian_chroot)
-fi
-
-# enable color support of ls and also add handy aliases
-if [ -x /usr/bin/dircolors ]; then
-    eval "$(dircolors -b)"
-    alias ls='ls --color=auto'
-    alias grep='grep --color=auto'
-fi
-
-# shellcheck disable=SC2142
-[ -f /usr/local/bin/virtualenvwrapper.sh ] && . /usr/local/bin/virtualenvwrapper.sh
-
 export REPREPRO_BASE_DIR="$HOME/Documents/Shore/debian-repository"
 export EDITOR=vim
 export GOPATH="$HOME/Documents/Golang"
@@ -53,25 +16,41 @@ export PATH="$HOME/Documents/Shore/ssl-ca:$PATH"
 export PATH="$HOME/.cargo/bin:$PATH"
 export PATH="$HOME/.cabal/bin:$PATH"
 export PATH="$HOME/Documents/bin:$PATH"
-export PYTHONSTARTUP=~/.pythonstartup
+export PYTHONSTARTUP=~/.config/pythonrc/pythonrc.py
 export AWS_DEFAULT_PROFILE='shore'
 export ANSIBLE_VERBOSITY=2
 export ANSIBLE_COMMAND_WARNINGS=True
 export ANSIBLE_DEPRECATION_WARNINGS=True
 export ANSIBLE_RETRY_FILES_SAVE_PATH=/tmp/
 export ANSIBLE_SSH_PIPELINING=True
-export ANSIBLE_SSH_CONTROL_PATH_DIR='/tmp/ssh-%%h'
 export ANSIBLE_GATHERING=smart
 export ANSIBLE_CACHE_PLUGIN=jsonfile
 export ANSIBLE_CACHE_PLUGIN_CONNECTION="$HOME/.ansible/facts"
 export ANSIBLE_CALLBACK_WHITELIST=profile_tasks
 export LYNX_SAVE_SPACE="$HOME/Downloads"
 export LYNX_TEMP_SPACE="$HOME/.cache/lynx"
+export VAGRANT_DEFAULT_PROVIDER="virtualbox"
+# Blinking
+export LESS_TERMCAP_mb=$'\E[01;31m'
+# Double bright
+export LESS_TERMCAP_md=$'\E[01;35m'
+export LESS_TERMCAP_me=$'\E[0m'
+# Standout
+export LESS_TERMCAP_so=$'\E[01;33m'
+export LESS_TERMCAP_se=$'\E[0m'
+# Underline
+export LESS_TERMCAP_us=$'\E[01;32m'
+export LESS_TERMCAP_ue=$'\E[0m'
+export PS0="\$(__prerun)"
+# shellcheck disable=SC1117
+export PS1="\[\$(__prompt)\]\u@\h:\w\$ "
+export CDPATH="$HOME/Documents:$HOME/Documents/Shore"
+
 alias ll='ls -lha'
 alias la='ls -A'
 alias l='ls -CF'
 alias gcc='gcc --std=c99 -Wall -Wextra -Werror -pedantic'
-alias dpkglog="grep -v 'status\|trigproc\|configure' /var/log/dpkg.log"
+alias dpkglog="grep -v 'status\\|trigproc\\|configure' /var/log/dpkg.log"
 alias deborphan='deborphan -a --no-show-section --ignore-suggests'
 alias aptitude='aptitude --display-format %p --quiet'
 alias obsolete='aptitude search ?obsolete'
@@ -80,39 +59,119 @@ alias missing-recommends="aptitude search '~RBrecommends:~i'"
 alias deinstalled="dpkg --get-selections | awk '\$2==\"deinstall\" {print \$1}'"
 alias ansible-local='ansible localhost -c local -i localhost,'
 alias ansible-local-playbook='ansible-playbook -i localhost, -c local'
-alias concat="perl -pe 's/\n/\\\n/g'"
-alias deconcat="perl -pe 's/\\\n/\n/g'"
-alias ggo='sudo GOPATH=/usr/share/go go'
-alias ecr-login='eval $(aws ecr get-login)'
+alias concat="perl -pe 's/\\n/\\\\n/g'"
+alias deconcat="perl -pe 's/\\\\n/\\n/g'"
+alias ecr-login='eval $(aws ecr get-login --no-include-email)'
 alias hostlocal='docker run --rm --privileged --net=host gliderlabs/hostlocal'
-alias apt-daily="sudo /bin/sh -c 'apt-get update && apt-get dist-upgrade --download-only --yes && apt-get autoclean'"
-alias docker-build='docker build -t "$(basename $PWD)" ./'
+alias cadvisor='docker run --rm   --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --volume=/dev/disk/:/dev/disk:ro --publish=8080:8080 --detach=true --name=cadvisor google/cadvisor:latest'
+alias __apt-daily="sudo /bin/sh -c 'apt-get update && apt-get dist-upgrade --download-only --yes && apt-get autoclean'"
+alias apt-daily="monitor __apt-daily"
+alias __flatpak-daily='sudo flatpak update --assumeyes'
+alias flatpak-daily="monitor __flatpak-daily"
 alias cdtemp='cd $(mktemp -d)'
 alias 0-day-cleanup='ssh xbmc.shore.co.il "sudo -u debian-transmission find /srv/library/Comics -name *.part -path *0-Day\ Week\ of* -delete"'
-alias httpbin='tox -c $HOME/.tox.ini.httpbin --'
+alias httpbin='gunicorn httpbin:app'
 alias update-requirements='find -name "*requirements*.txt" -exec pur --requirement {} \;'
-alias restart-kodi='ssh xbmc.shore.co.il "sudo systemctl kill --kill-who all xorg.service"'
-alias sync-podcasts='(cd && unison podcasts)'
+alias restart-kodi='ssh xbmc.shore.co.il "sudo systemctl kill --kill-who=all --signal=9 xorg.service"'
+alias __sync-podcasts='(cd && unison podcasts)'
+alias sync-podcasts='monitor __sync-podcasts'
+alias sync-comics='monitor __sync_comics'
 # shellcheck disable=SC2142
 alias tolower='awk "{print tolower(\$0)}"'
 # shellcheck disable=SC2142
 alias toupper='awk "{print toupper(\$0)}"'
 alias wifi-portal='curl --silent --fail --write-out "%{redirect_url}" --output /dev/null http://detectportal.firefox.com/success.txt'
-alias urlencode='perl -MURI::Escape -ne "chomp;print uri_escape(\$_), \"\n\""'
-alias urldecode='perl -MURI::Escape -ne "chomp;print uri_unescape(\$_), \"\n\""'
 alias transmission-remote='ssh -fNo ExitOnForwardFailure=yes xbmc.shore.co.il && transmission-remote'
 alias kpcli='kpcli --kdb ~/Documents/Database.kdbx'
 alias gen-mac="hexdump -n5 -e '\"02\" 5/1 \":%02X\" \"\\n\"' /dev/urandom"
+alias clean-swp="find \$HOME/ -name '*.swp' -delete"
+alias unssh="ssh -o \"UserKnownHostsFile /dev/null\" -o \"StrictHostKeyChecking no\""
+alias todo="vim \$HOME/Documents/TODO.yml"
+alias sudo="sudo "
+alias git="git "
+alias xargs="xargs "
+alias presentation='docker dev adarnimrod/presentation'
+alias prune_prerun='find "$HOME" -maxdepth 1 -name ".prerun\.[0-9]*" | grep -v "$(pgrep -u "$(id -u)" "$(basename "$SHELL" )" )" | xargs -r rm'
+alias netdata='docker run --detach --name netdata --cap-add SYS_PTRACE --volume /proc:/host/proc:ro --volume /sys:/host/sys:ro --volume /var/run/docker.sock:/var/run/docker.sock --publish 19999:19999 firehol/netdata:alpine'
+alias newman='docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/etc/newman" -t postman/newman_alpine33'
+alias http-server='python3 -m http.server 8080'
+alias dd='monitor sudo dd status=progress'
+alias screenshot-cleanup='find "$HOME/Pictures" -name "Screenshot from *.png" -delete'
+alias black='black --line-length 79'
+alias torrent_off='ssh xbmc.shore.co.il sudo systemctl stop transmission-{rss,daemon}.service'
+alias torrent_on='ssh xbmc.shore.co.il sudo systemctl start transmission-{daemon,rss}.service'
+alias bell="printf '\\a'"
+command -v notify-send > /dev/null || alias notify-send='bell'
+alias __gcloud='docker run --rm -it -v "$HOME/.config/gcloud:/tmp/.config/gcloud" -e "HOME=/tmp" -u "$(id -u):$(id -g)" google/cloud-sdk:alpine'
+alias gcloud='__gcloud gcloud'
+alias gsutil='__gcloud gsutil'
+
+monitor () {
+    if eval "$@"
+    then
+        notify-send "$(basename "${1#__}") has finished."
+    else
+        notify-send --urgency=critical "$(basename "${1#__}") has failed."
+    fi
+}
+
+jt () {
+    if command -v pygmentize > /dev/null
+    then
+        python3 -m json.tool "$@" | pygmentize -l javascript
+    else
+        python3 -m json.tool "$@"
+    fi
+}
+
+bold () {
+    printf '\e[1m' || true
+    echo "$@"
+    printf '\e[0m' || true
+}
+
+red () {
+    printf '\e[1;91m' || true
+    echo "$@"
+    printf '\e[0m' || true
+}
+
+green () {
+    printf '\e[1;92m' || true
+    echo "$@"
+    printf '\e[0m' || true
+}
+
+yellow () {
+    printf '\e[1;93m' || true
+    echo "$@"
+    printf '\e[0m' || true
+}
+
+blue () {
+    printf '\e[1;94m' || true
+    echo "$@"
+    printf '\e[0m' || true
+}
+
+magenta () {
+    printf '\e[1;95m' || true
+    echo "$@"
+    printf '\e[0m' || true
+}
+
+cyan () {
+    printf '\e[1;96m' || true
+    echo "$@"
+    printf '\e[0m' || true
+}
 
 deduce_aws_region () {
-    AWS_DEFAULT_REGION="$(python << EOF
-from __future__ import print_function
-try:
-    from urllib import urlopen
-except ImportError:
-    from urllib.request import urlopen
+    AWS_DEFAULT_REGION="$(python3 << EOF
+from urllib.request import urlopen
 import json
-print(json.load(urlopen('http://169.254.169.254/latest/dynamic/instance-identity/document'))['region'])
+response = urlopen('http://169.254.169.254/latest/dynamic/instance-identity/document')
+print(json.loads(response.read().decode('utf-8'))['region'])
 EOF
     )"
     export AWS_DEFAULT_REGION
@@ -128,39 +187,114 @@ gen_csr () {
     openssl req -new -newkey rsa:4096 -nodes -out "$1.csr" -keyout "$1.key"
 }
 
-docker_dev () {
-    local root repo uid
-    root="$(git rev-parse --show-toplevel)"
-    repo="$(basename "$root")"
-    uid="$(id -u)"
-    docker build -t "$repo:dev" "$root"
-    docker run --interactive \
-               --publish-all \
-               --name "$repo" \
-               --rm \
-               --tty \
-               --volume "$HOME:$HOME" \
-               --volume "$root:$root" \
-               --user "$uid" \
-               --workdir "$PWD" "$repo:dev" /bin/sh -l
+__sync_comics () {
+    local this_month last_month format
+    format='+xbmc.shore.co.il:/srv/library/Comics/0-Day\ Week\ of\ %Y.%m.*'
+    this_month="$( date "$format" )"
+    last_month="$( date --date '1 month ago' "$format" )"
+    rsync --prune-empty-dirs --ignore-missing-args --recursive --compress --progress --exclude "*.part" "$last_month" "$this_month" "$HOME/Downloads/Comics/"
+    find "$HOME/Downloads/Comics/" -name "$(date --date '2 month ago' +'0-Day\ Week\ of\ %Y.%m.*')" -exec rm -r {} +
 }
 
-sync_comics () {
-    local this_month last_month
-    this_month="$( date '+xbmc.shore.co.il:/srv/library/Comics/0-Day\ Week\ of\ %Y.%m.*' )"
-    last_month="$( date --date '1 month ago' '+xbmc.shore.co.il:/srv/library/Comics/0-Day\ Week\ of\ %Y.%m.*' )"
-    rsync --recursive --compress --progress --exclude "*.part" "$last_month" "$this_month" "$HOME/Downloads/Comics/"
-    find "$HOME/Downloads/Comics/" -name "$(date --date '2 month ago' +''0-Day\ Week\ of\ %Y.%m.*)" -delete
+ddg () {
+    lynx "https://duckduckgo.com/lite/?q=$(echo "$@" | urlencode)"
 }
 
-bfg () {
-    [ -f "$HOME/Downloads/bfg.jar" ] || curl 'https://search.maven.org/remote_content?g=com.madgag&a=bfg&v=LATEST' -sLo "$HOME/Downloads/bfg.jar"
-    java -jar "$HOME/Downloads/bfg.jar" "$@"
+toux () {
+    touch "$@"
+    chmod +x "$@"
 }
 
-ddg () {
-    lynx "https://duckduckgo.com/lite/?q=$(echo "$@" | urlencode)"
+match_ssl_pair () {
+    if [ "$#" -ne 2 ]
+    then
+        echo "Usage: match_ssl_pair private_key certificate"
+        return 1
+    fi
+    tempkey="$(mktemp)"
+    tempcert="$(mktemp)"
+    openssl pkey -pubout -outform PEM -in "$1" > "$tempkey"
+    openssl x509 -pubkey -noout -in "$2" > "$tempcert"
+    cmp "$tempkey" "$tempcert" > /dev/null
+    exitcode="$?"
+    rm "$tempkey" "$tempcert"
+    return "$exitcode"
+}
+
+flatpak-kill () {
+    if [ "$#" -lt 1 ]
+    then
+        echo "You must specify application name." >> /dev/stderr
+        false
+    else
+        name="$1"
+        shift
+        for pid in $(flatpak ps --columns=application,pid | awk "tolower(\$2) ~ /$name/ {print \$3}")
+        do
+            pkill "$@" "$pid"
+        done
+    fi
+}
+
+__run_duration () {
+    if [ -f "$HOME/.prerun.$$" ]
+    then
+        local endtime starttime
+        endtime="$(date +%s)"
+        starttime="$(cat "$HOME/.prerun.$$")"
+        rm "$HOME/.prerun.$$"
+        echo "$(( endtime - starttime ))"
+    else
+        echo 0
+    fi
+}
+
+__prerun () {
+    date +%s > "$HOME/.prerun.$$"
+}
+
+__prompt () {
+    local exitstatus="$?"
+    local runduration prompt
+    ! [ "$(type history 2> /dev/null)" = "history is a shell builtin" ] || history -a
+    prompt=""
+    [ ! -f "$HOME/.prerun.$$" ] || runduration="$(__run_duration)"
+    [ "${runduration:-0}" -lt "10" ] || prompt="$(cyan -n "[Run duration: $runduration]") $prompt"
+    [ -n "${runduration:-}" ] || exitstatus='0'
+    [ "$exitstatus" = "0" ] || prompt="$(red -n "[Exit status: $exitstatus]") $prompt"
+    echo "$prompt"
 }
 
 # shellcheck disable=SC1090
 . "$HOME/Documents/Shore/bundle_certs/bundle_certs"
+
+if [ -n "${BASH:-}" ]
+then
+    shopt -s checkwinsize
+    shopt -s cmdhist
+    # shellcheck disable=SC1091
+    [ -f /etc/bash_completion ] && . /etc/bash_completion
+
+    # shellcheck disable=SC1090
+    for sourcefile in $HOME/.bash_completion.d/*
+    do
+        [ ! -f "$sourcefile" ] || . "$sourcefile"
+    done
+    ! command -v direnv > /dev/null || eval "$(direnv hook bash)"
+fi
+
+
+# make less more friendly for non-text input files, see lesspipe(1)
+[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
+
+# enable color support of ls and also add handy aliases
+if [ -x /usr/bin/dircolors ]; then
+    eval "$(dircolors -b)"
+    alias ls='ls --color=auto'
+    alias grep='grep --color=auto'
+    alias diff='diff --color=auto'
+    alias ip='ip -color'
+    alias less='less --raw-control-chars'
+fi
+
+prune_prerun
diff --git a/.config/gcloud/.gitkeep b/.config/gcloud/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/.gitconfig b/.config/git/config
similarity index 60%
rename from .gitconfig
rename to .config/git/config
index c142db6c619027b898f51d7b0d9f0c149ab2ef44..5724ab702a338281dbb075ca7b5f51bdd00adca5 100644
--- a/.gitconfig
+++ b/.config/git/config
@@ -1,39 +1,48 @@
+[apply]
+    whitespace = fix
 [alias]
     amend = commit --amend
-    autosquash = !GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
+    autorebase = -c 'core.editor=true' rebase -i --autosquash --autostash
     bull = submodule update --remote --init
-    clear = clean -fdx
+    cleaan = clean -fdX
+    cleaaan = clean -fdx
     dif = diff --color-words
     empty-commit = commit --allow-empty
-	exec = "!exec "
+	exec = "!${SHELL:-/bin/sh} -ic "
     ff = merge --no-edit --ff-only master
-    fixup = commit --fixup
+    fixup = !cd "${GIT_PREFIX:-$PWD}" && git commit --fixup $(git last-commit)
     forget = reset HEAD^
     merg = merge --no-edit
+    pop = stash pop
     posh = push --set-upstream origin HEAD
-    pul = pull --progress
+    Pull = pull --progress --ff --tags
     pull-force = !git fetch && git reset --hard "$(git tracking)"
-    push-force = push --force-with-lease
+    pushes = !git remote | xargs -n1 git push
     root = rev-parse --show-toplevel
     serve-git = daemon --reuseaddr --verbose --base-path=. --export-all ./.git
-    serve-http = !git update-server-info && cd .git && python -m SimpleHTTPServer
+    serve-http = !git update-server-info && cd .git && python -m http.server 8080
+    shove = push --force-with-lease
+    squash = !cd "${GIT_PREFIX:-$PWD}" && git commit --squash $(git last-commit)
     staash = stash --all
     stat = status --short --branch
-    tag-version = !git tag -af "v$(cat VERSION)"
+    tag-version = !git tag --annotate --force --message "v$(cat VERSION)" "v$(cat VERSION)"
     tracking = rev-parse --abbrev-ref --symbolic-full-name @{upstream}
-    trigger = !git commit --allow-empty --no-edit --amend && git push --force-with-lease
-    update-requirements = !git stash save -a -u -q && ( git ls-files '*requirements*.txt' | xargs -n1 pur -r ) && ( git commit -a -m '- Updated requirements.' || echo 'No requirements updated.' ) && git stash pop
+    trigger = !git commit --allow-empty --no-edit --amend && git pushes --force-with-lease
 [color]
     grep = true
+    ui = auto
 [core]
-    excludesfile = ~/.gitignore_global
+    whitespace = space-before-tab,-indent-with-non-tab,trailing-space
 [diff]
+    renames = copies
 	tool = meld
 [difftool]
 	prompt = false
 [fetch]
     fsckobjects = true
     prune = true
+[grep]
+    linenumber = true
 [merge]
     tool = meld
     ff = false
diff --git a/.gitignore_global b/.config/git/ignore
similarity index 67%
rename from .gitignore_global
rename to .config/git/ignore
index 7523db9a5a3b4bc26202e34bc488726e040d5359..3e66e1d5821e755498f864e372ae1dbe23c29414 100644
--- a/.gitignore_global
+++ b/.config/git/ignore
@@ -11,8 +11,10 @@ Thumbs.db
 .svn/
 .sass-cache/
 *.log
-a.out
-node-modules/
+*.out
+*.so
+node_modules/
+.npm/
 nbproject/
 *.ipynb
 .idea/
@@ -22,7 +24,7 @@ nbproject/
 .cache/
 bower_components/
 *.class
-*.jar
+*.[ewj]ar
 secring.*
 .*.kate-swp
 .swp.*
@@ -32,3 +34,16 @@ build/
 _build/
 dist/
 .tox/
+*.pdf
+*.exe
+*.dll
+*.gz
+*.tgz
+*.tar
+*.rar
+*.zip
+*.pid
+*.lock
+*.env
+.bundle/
+!Pipfile.lock
diff --git a/.config/pythonrc b/.config/pythonrc
new file mode 160000
index 0000000000000000000000000000000000000000..d9f2c7a9caf0076c011bbe0aa42fca641432ea57
--- /dev/null
+++ b/.config/pythonrc
@@ -0,0 +1 @@
+Subproject commit d9f2c7a9caf0076c011bbe0aa42fca641432ea57
diff --git a/.digrc b/.digrc
new file mode 100644
index 0000000000000000000000000000000000000000..a073a9f6fc81f914efad43fbf347781c0e4d122d
--- /dev/null
+++ b/.digrc
@@ -0,0 +1 @@
++short
diff --git a/.githooks/post-merge b/.githooks/post-merge
index 97b5562382713a368cb4d489372d97401abaa82c..3b0fd3c72aa5755c7c87d09f4a7180fd283d2d3c 100755
--- a/.githooks/post-merge
+++ b/.githooks/post-merge
@@ -1,9 +1,15 @@
 #!/bin/sh
 set -eu
 cd "$(git rev-parse --show-toplevel)"
-echo Installing Git hooks
+echo Installing Git hooks >> /dev/stderr
 Documents/bin/install-git-hooks
-echo Generating SSH config
+echo Generating SSH config >> /dev/stderr
 Documents/bin/gen-ssh-config
-echo Loading dconf config
+echo Loading dconf config >> /dev/stderr
 Documents/bin/dconf-load
+echo Configuring Git repo >> /dev/stderr
+git config --local status.showUntrackedFiles no
+echo Creating Bash completion scripts >> /dev/stderr
+Documents/bin/gen-bash-completion
+echo Adding Cron job >> /dev/stderr
+Documents/bin/cron-jobs
diff --git a/.gitignore b/.gitignore
index 72e8ffc0db8aad71a934dd11e5968bd5109e54b4..ee0d7edd0530a3b100f45803b999a92bcffbb8d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
 *
+.bash_completion.d/.pipenv
+.pre-commit/
+.ssh/config
diff --git a/.gitmodules b/.gitmodules
index 8479cf99a040d5c69dce5c0c06400fbca90b09a7..2f43042a0e50abb675312a69b942b44217a887f0 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -21,3 +21,6 @@
 [submodule "Documents/Shore/poquita"]
     path = Documents/Shore/poquita
     url = https://www.shore.co.il/git/poquita
+[submodule ".config/pythonrc"]
+	path = .config/pythonrc
+	url = https://github.com/lonetwin/pythonrc.git
diff --git a/.inputrc b/.inputrc
new file mode 100644
index 0000000000000000000000000000000000000000..f080aa5886fea40ce28f8bbf5271ef9ce774220e
--- /dev/null
+++ b/.inputrc
@@ -0,0 +1,13 @@
+$include  /etc/inputrc
+set completion-ignore-case on
+set show-all-if-ambiguous on
+set visible-stats on
+set skip-completed-text on
+set colored-stats on
+set colored-completion-prefix on
+set blink-matching-paren on
+set expand-tilde on
+set history-preserve-point on
+set mark-directories on
+"\e[A": history-search-backward
+"\e[B": history-search-forward
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d9d5d59091c2bfc672365d5d6ed32125053ec950..ed4a5c287d32572006c2f6613a1dc0d721687151 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,14 +1,20 @@
--   repo: git://github.com/pre-commit/pre-commit-hooks
-    sha: v0.8.0
+---
+repos:
+-   repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v1.4.0-1
     hooks:
     -   id: check-added-large-files
+    -   id: check-executables-have-shebangs
     -   id: check-merge-conflict
+    -   id: check-symlinks
+    -   id: detect-private-key
     -   id: flake8
-        files: \.pythonstartup|Documents/Shore/cleanup/vagrant-.*
+        exclude: pythonrc.py
 -   repo: https://www.shore.co.il/git/shell-pre-commit/
-    sha: v0.5.4
+    rev: v0.6.0
     hooks:
     -   id: shell-lint
-        files: &shellscripts 'bashrc|post-merge|profile|docker-|wifi-login|renew-certs|dma-clean|gen-ssh-config|dconf-load|install-git-hooks|pocketchip-battery|update-voltage'
+        exclude: &excluded_shellscripts \.bash_completion\.d/(docker-machine\.bash|fabric-completion.bash|docker-compose)|\.travis/travis\.sh
     -   id: shellcheck
-        files: *shellscripts
+        exclude: *excluded_shellscripts
+        include: .bashrc
diff --git a/.pythonstartup b/.pythonstartup
deleted file mode 100644
index 70e0b6fdecb18f9df79ecb3c49d038707d079e70..0000000000000000000000000000000000000000
--- a/.pythonstartup
+++ /dev/null
@@ -1,2 +0,0 @@
-from pprint import PrettyPrinter
-pprint = PrettyPrinter().pprint
diff --git a/.ssh/config.d/10_global b/.ssh/config.d/10_global
index 4f5cda4805ce568b7a53f32df9c97c808932c376..7dd008db4394d4749a2628ea717c85325d8880fe 100644
--- a/.ssh/config.d/10_global
+++ b/.ssh/config.d/10_global
@@ -1,6 +1,6 @@
 Compression yes
 ControlMaster auto
-ControlPath ~/.ssh/%r@%h:%p.sock
+ControlPath ~/.ssh/%C.sock
 ControlPersist 3m
 ServerAliveInterval 30
 IdentitiesOnly yes
diff --git a/.ssh/config.d/20_bullguard b/.ssh/config.d/20_bullguard
deleted file mode 100644
index 726128401beb5e59dbaa91e92d2a384741f0e1fb..0000000000000000000000000000000000000000
--- a/.ssh/config.d/20_bullguard
+++ /dev/null
@@ -1,20 +0,0 @@
-# Bullguard
-
-Host gitlab.dc.dojo-labs.com
-HostName gitlab.dc.dojo-labs.com
-User git
-IdentityFile ~/.ssh/bullguard_ecdsa
-
-Host 172.50.1.11
-User ec2-user
-
-Host 172.50.1.111
-User ec2-user
-
-Host 172.50.*.*
-IdentityFile ~/.ssh/bullguard-prod_rsa
-User ubuntu
-
-Host 172.70.*.*
-IdentityFile ~/.ssh/bullguard-dev_rsa
-User ubuntu
diff --git a/.ssh/config.d/30_localhost b/.ssh/config.d/30_localhost
new file mode 100644
index 0000000000000000000000000000000000000000..0c3422672eb2e14a9c58eaf77bb2bc162236411b
--- /dev/null
+++ b/.ssh/config.d/30_localhost
@@ -0,0 +1,7 @@
+# localhost
+
+Host localhost
+HostName 127.0.0.1
+IdentityFile ~/.ssh/localhost
+UserKnownHostsFile /dev/null
+StrictHostKeyChecking no
diff --git a/.tmux.conf b/.tmux.conf
new file mode 100644
index 0000000000000000000000000000000000000000..e39850c7d2624e52a7540d299dc6fcb27ddadfac
--- /dev/null
+++ b/.tmux.conf
@@ -0,0 +1,37 @@
+bind-key b send-prefix
+set -g set-titles on
+set -g set-titles-string '#T'
+#### COLOUR (Solarized dark)
+
+# default statusbar colors
+set-option -g status-bg black #base02
+set-option -g status-fg yellow #yellow
+set-option -g status-attr default
+
+# default window title colors
+set-window-option -g window-status-fg brightblue #base0
+set-window-option -g window-status-bg default
+#set-window-option -g window-status-attr dim
+
+# active window title colors
+set-window-option -g window-status-current-fg brightred #orange
+set-window-option -g window-status-current-bg default
+#set-window-option -g window-status-current-attr bright
+
+# pane border
+set-option -g pane-border-fg black #base02
+set-option -g pane-active-border-fg brightgreen #base01
+
+# message text
+set-option -g message-bg black #base02
+set-option -g message-fg brightred #orange
+
+# pane number display
+set-option -g display-panes-active-colour blue #blue
+set-option -g display-panes-colour brightred #orange
+
+# clock
+set-window-option -g clock-mode-colour green #green
+
+# bell
+set-window-option -g window-status-bell-style fg=black,bg=red #base02, red
diff --git a/.tox.ini.httpbin b/.tox.ini.httpbin
deleted file mode 100644
index f983e74c824a9f6d1ce21f8c712e4571c8f3804b..0000000000000000000000000000000000000000
--- a/.tox.ini.httpbin
+++ /dev/null
@@ -1,9 +0,0 @@
-[tox]
-skipsdist = True
-
-[testenv]
-basepython = python3
-deps =
-    httpbin
-    gunicorn
-commands = gunicorn httpbin:app {posargs}
diff --git a/.travis.yml b/.travis.yml
index 57cd15295a55eaee34e258fffdf5a2ad43a119c2..16af61eb1f2d09ff9b48a659da8d641e2f3214cb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,21 +7,9 @@ group: beta
 cache:
   - pip
   - directories:
-      - $HOME/.pre-commit
-      - $HOME/.cabal
-      - $HOME/.ghc
-
-addons:
-  apt:
-    packages:
-      - cabal-install
-      - ghc
-
-env:
-    PATH: $PATH:$HOME/.cabal/bin
+      - $HOME/.cache/
 
 install:
-  - cabal update && cabal install shellcheck
   - pip install pre_commit | cat
 
 script:
diff --git a/.vimrc b/.vimrc
index c147704b28f9a6f4bff1997cc07254cc2325b307..bba334e93fc607773be9e62e09fb33057bc9c8cc 100644
--- a/.vimrc
+++ b/.vimrc
@@ -8,4 +8,6 @@ setlocal shiftwidth=4
 setlocal textwidth=80
 setlocal smarttab
 setlocal expandtab
+setlocal incsearch
 syntax on
+setlocal modeline
diff --git a/Documents/Shore/Ansible/ansible-desktop-playbooks b/Documents/Shore/Ansible/ansible-desktop-playbooks
index d243c2e7ca803ec5aea0077e4271508caa4716a7..f2e18e5b4d35a951e5490d5929df769c516e93ce 160000
--- a/Documents/Shore/Ansible/ansible-desktop-playbooks
+++ b/Documents/Shore/Ansible/ansible-desktop-playbooks
@@ -1 +1 @@
-Subproject commit d243c2e7ca803ec5aea0077e4271508caa4716a7
+Subproject commit f2e18e5b4d35a951e5490d5929df769c516e93ce
diff --git a/Documents/Shore/bundle_certs b/Documents/Shore/bundle_certs
index c4daf6cdd3d60bc1774ff0b36b34cce17cc023b5..98c05383cf12598c3ae0025a98eb2ccdf3e58cf8 160000
--- a/Documents/Shore/bundle_certs
+++ b/Documents/Shore/bundle_certs
@@ -1 +1 @@
-Subproject commit c4daf6cdd3d60bc1774ff0b36b34cce17cc023b5
+Subproject commit 98c05383cf12598c3ae0025a98eb2ccdf3e58cf8
diff --git a/Documents/Shore/ssl-ca b/Documents/Shore/ssl-ca
index c5d71104a016870a7192d85fecfa3e67cb9913f0..d78bcbb85171f27d69ae26c385cb1152ea8aee27 160000
--- a/Documents/Shore/ssl-ca
+++ b/Documents/Shore/ssl-ca
@@ -1 +1 @@
-Subproject commit c5d71104a016870a7192d85fecfa3e67cb9913f0
+Subproject commit d78bcbb85171f27d69ae26c385cb1152ea8aee27
diff --git a/Documents/bin/bfg b/Documents/bin/bfg
new file mode 100755
index 0000000000000000000000000000000000000000..d5b692fbd59d3a0ecf092e2e57370aa29b114fd3
--- /dev/null
+++ b/Documents/bin/bfg
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -eu
+
+__BFG_JAR="$HOME/Documents/bin/bfg.jar"
+[ -f "$__BFG_JAR" ] || curl 'https://search.maven.org/remote_content?g=com.madgag&a=bfg&v=LATEST' -sLO "$__BFG_JAR"
+exec java -jar "$__BFG_JAR" "$@"
diff --git a/Documents/bin/cron-jobs b/Documents/bin/cron-jobs
new file mode 100755
index 0000000000000000000000000000000000000000..3c081b88359fb4b46c028e0a8a53907d82d9de1e
--- /dev/null
+++ b/Documents/bin/cron-jobs
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -eu
+
+#  TODO: Verify internet connectivity
+cronjob="0 11 * * 6 $HOME/.git-hooks/post-merge 2>&1 | logger -t rcfiles-post-merge"
+( (crontab -l 2>/dev/null || true) | sed '/post-merge/d'; echo "$cronjob" ) | crontab -
diff --git a/Documents/bin/dconf-load b/Documents/bin/dconf-load
index 07070bfea096ec17e318832f3b22edd3708ddd25..eafc88dd6d07322570b1a0f0f9c511e5a378aad2 100755
--- a/Documents/bin/dconf-load
+++ b/Documents/bin/dconf-load
@@ -1,7 +1,7 @@
 #!/bin/sh
 set -eu
 
-if ! which dconf > /dev/null
+if ! command -v dconf > /dev/null
 then
     echo "Can't find dconf, exiting."
     exit 0
diff --git a/Documents/bin/docker b/Documents/bin/docker
new file mode 120000
index 0000000000000000000000000000000000000000..22cb46f8d7894a2aaf35ad42108135984c1f5cd8
--- /dev/null
+++ b/Documents/bin/docker
@@ -0,0 +1 @@
+wrapper
\ No newline at end of file
diff --git a/Documents/bin/docker-Build b/Documents/bin/docker-Build
new file mode 100755
index 0000000000000000000000000000000000000000..c97dd5f9b9d09d7af4344e478ac330cdb0945626
--- /dev/null
+++ b/Documents/bin/docker-Build
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -eu
+docker build -t "$(basename "$PWD" | awk "{print tolower(\$0)}" )" ./
diff --git a/Documents/bin/docker-clean b/Documents/bin/docker-clean
index fbbb855ee0741fbe81175c2ddce40eca2f741841..648d12480625ee3ca81a5243479e07ef7a04157b 100755
--- a/Documents/bin/docker-clean
+++ b/Documents/bin/docker-clean
@@ -1,8 +1,11 @@
 #!/bin/sh
 # Deliberately don't set -e, allow failures to continue silently.
-set -u
+set -eu
 
+docker version --format '{{ .Server.Version }}' > /dev/null
+docker version --format '{{ .Client.Version }}' > /dev/null
 docker ps --quiet --filter=status=exited | xargs -r docker rm --volumes 2>/dev/null
 docker ps --quiet --filter=status=created | xargs -r docker rm --volumes 2>/dev/null
 docker images --quiet --filter=dangling=true | xargs -r docker rmi 2>/dev/null
 docker volume ls --quiet --filter=dangling=true | xargs -r docker volume rm 2>/dev/null
+docker system prune --force || true
diff --git a/Documents/bin/docker-dev b/Documents/bin/docker-dev
new file mode 100755
index 0000000000000000000000000000000000000000..94157953304eeb64cb3d03223eefce82482646ae
--- /dev/null
+++ b/Documents/bin/docker-dev
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -eu
+docker run --rm -Pitv "$PWD:/volume" "$@"
diff --git a/Documents/bin/docker-runit b/Documents/bin/docker-runit
new file mode 100755
index 0000000000000000000000000000000000000000..27aa212890f436881e17669072aba80a31130034
--- /dev/null
+++ b/Documents/bin/docker-runit
@@ -0,0 +1,3 @@
+#!/bin/sh
+set -eu
+docker run --rm -it "$@"
diff --git a/Documents/bin/gen-bash-completion b/Documents/bin/gen-bash-completion
new file mode 100755
index 0000000000000000000000000000000000000000..83b18521eae51f5502e2709683fe4daa43132aa6
--- /dev/null
+++ b/Documents/bin/gen-bash-completion
@@ -0,0 +1,13 @@
+#!/bin/sh
+set -eu
+
+gen_completion () {
+    executable="$1"
+    ! command -v "$executable" > /dev/null || "$@" > "$HOME/.bash_completion.d/$executable"
+}
+
+gen_completion pandoc --bash-completion
+gen_completion pipenv --completion
+gen_completion kops completion bash
+gen_completion kubectl completion bash
+gen_completion minikube completion bash
diff --git a/Documents/bin/git-Init b/Documents/bin/git-Init
new file mode 100755
index 0000000000000000000000000000000000000000..00c3fea8df369ba2d8a1cce45cc919547bb67ac6
--- /dev/null
+++ b/Documents/bin/git-Init
@@ -0,0 +1,22 @@
+#!/bin/sh
+set -eu
+
+die () {
+    echo "$@"
+    exit 1
+}
+
+usage () {
+    die "Usage: $0 repo_name"
+}
+
+[ "$#" = "1" ] || usage
+reponame="$1"
+# shellcheck disable=SC2029
+ssh cgit.shore.co.il "git init --bare /srv/git/$reponame"
+git clone "cgit.shore.co.il:/srv/git/$reponame"
+(
+cd "$reponame"
+git commit --allow-empty --message "Initial empty commit."
+git push
+)
diff --git a/Documents/bin/git-bump b/Documents/bin/git-bump
new file mode 100755
index 0000000000000000000000000000000000000000..9d56c935c211f239250c0a16a161128348bebad4
--- /dev/null
+++ b/Documents/bin/git-bump
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -eu
+
+semver-bump "$1-release"
+git commit VERSION -m "Bumped $1 version."
+git tag-version
+git pushes --tags
diff --git a/Documents/bin/git-initial b/Documents/bin/git-initial
new file mode 100755
index 0000000000000000000000000000000000000000..edb76956f49601e2639b03e9f69771c6c8dfd9c1
--- /dev/null
+++ b/Documents/bin/git-initial
@@ -0,0 +1,20 @@
+#!/bin/sh
+set -eu
+
+die () {
+    echo "$@"
+    exit 1
+}
+
+usage () {
+    die "Usage: $0 repo_name"
+}
+
+[ "$#" = "1" ] || usage
+reponame="$1"
+# shellcheck disable=SC2029
+git init "$reponame"
+(
+cd "$reponame"
+git commit --allow-empty --message "Initial empty commit."
+)
diff --git a/Documents/bin/git-last-commit b/Documents/bin/git-last-commit
new file mode 100755
index 0000000000000000000000000000000000000000..8611b27ccb5948631effb263f5b3edaaa2a00b1f
--- /dev/null
+++ b/Documents/bin/git-last-commit
@@ -0,0 +1,4 @@
+#!/bin/sh
+set -eu
+
+git log --no-merges --abbrev-commit --format="%h %s" | awk '{if ($2 != "fixup!" && $2 != "squash!") {print $1; exit}}'
diff --git a/Documents/bin/git-update-requirements b/Documents/bin/git-update-requirements
new file mode 100755
index 0000000000000000000000000000000000000000..03375c4fa606d5d76f09ca4862b8c465a6b2601f
--- /dev/null
+++ b/Documents/bin/git-update-requirements
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -eu
+command -v pur > /dev/null || { echo "Can't find pur."; exit 1; }
+
+git stash save --all --include-untracked --quiet
+git ls-files '*requirements*.txt' | xargs -n1 pur -r
+git commit -a -m '- Updated requirements.' || echo 'No requirements updated.'
+git stash pop
diff --git a/Documents/bin/urldecode b/Documents/bin/urldecode
new file mode 100755
index 0000000000000000000000000000000000000000..87954fe6f3592a37136320b1b48d0b0a7e2bdb38
--- /dev/null
+++ b/Documents/bin/urldecode
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+from fileinput import input
+from urllib.parse import unquote_plus as unquote
+
+
+if __name__ == '__main__':
+    for line in input():
+        print(unquote(line.strip()))
diff --git a/Documents/bin/urlencode b/Documents/bin/urlencode
new file mode 100755
index 0000000000000000000000000000000000000000..3f93145c3b495a339ac534aa32b27b66e54c7e1a
--- /dev/null
+++ b/Documents/bin/urlencode
@@ -0,0 +1,8 @@
+#!/usr/bin/env python3
+from fileinput import input
+from urllib.parse import quote_plus as quote
+
+
+if __name__ == '__main__':
+    for line in input():
+        print(quote(line.strip()))
diff --git a/Documents/bin/wifi-login b/Documents/bin/wifi-login
index 765339463a87c05087eceb47b940222e382a37b6..76328a57be0f92dfd351490f7b5a06b05f40e2f5 100755
--- a/Documents/bin/wifi-login
+++ b/Documents/bin/wifi-login
@@ -60,10 +60,10 @@ else
     action="$2"
 fi
 
-which curl > /dev/null || die "Can't login to the WiFi network, cURL is not installed."
-which awk > /dev/null || die "Can't login to the WiFi network, awk is not installed."
-which logger > /dev/null || die "Can't login to the WiFi network, logger is not installed."
-which nmcli > /dev/null || die "Can't login to the WiFi network, nmcli is not installed."
+command -v curl > /dev/null || die "Can't login to the WiFi network, cURL is not installed."
+command -v awk > /dev/null || die "Can't login to the WiFi network, awk is not installed."
+command -v logger > /dev/null || die "Can't login to the WiFi network, logger is not installed."
+command -v nmcli > /dev/null || die "Can't login to the WiFi network, nmcli is not installed."
 
 echo "$action" | grep -xq 'up\|dhcp4-change\|dhcp6-change\|connectivity-change' || \
     die "Can't login to the WiFi network, action $action isn't up nor changed."
diff --git a/Documents/bin/wrapper b/Documents/bin/wrapper
new file mode 100755
index 0000000000000000000000000000000000000000..a54f983cbedd30da1a48c202a90e285a490b3767
--- /dev/null
+++ b/Documents/bin/wrapper
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -eu
+
+basename="$(basename "$0")"
+command="$(command -pv "$basename")" || { echo "$basename: not found"; exit 127; }
+if alias="$(command -v "$basename-${1:-}")"
+then
+    shift
+    "$alias" "$@"
+else
+    "$command" "$@"
+fi
diff --git a/README.rst b/README.rst
index 8c25f7abe05b6c3ac86a327d5f3f036a0f266ef4..08cf7745bc50d04170642217f02406f5bbfc89e4 100644
--- a/README.rst
+++ b/README.rst
@@ -13,7 +13,7 @@ home directory and is not meant for mass consumption as it is.
 Installation
 ------------
 
-WARNING: This will overwrite your existing files.
+*WARNING: This will overwrite your existing files.*
 
 .. code:: shell